Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/windows-98/llms.txt

Use this file to discover all available pages before exploring further.

The Windows 98 Portfolio has a tightly scoped design system built on nine Tailwind color tokens, three Google Fonts, a handful of Win98 border utility classes, and two CRT-effect layers. Every visual decision — from the navy title bar to the scanline shimmer — traces back to one of these primitives, which means a single hex change can ripple consistently across the entire UI.

Color tokens

All retro colors are registered in tailwind.config.js under the theme.extend.colors.retro namespace in the source project. They become Tailwind utility classes (bg-retro-navy, text-retro-magenta, border-retro-darkgray, etc.) and are used throughout every component and page.
TokenClassHexPrimary usage
retro-navy*-retro-navy#000080Title bars, Start menu sidebar, hover states
retro-magenta*-retro-magenta#ec4899About icon, mail icon, selection highlight, guestbook accents
retro-turquoise*-retro-turquoise#00cfd1Projects icon, testimonials icon, sparkle animations, shadows
retro-teal*-retro-teal#0d9488Desktop background, blog icon
retro-gray*-retro-gray#c0c0c0Win98 chrome background (standard Windows silver)
retro-darkgray*-retro-darkgray#808080Border accents, sunken border top/left edges
retro-white*-retro-white#ffffffWindow body backgrounds
retro-black*-retro-black#0a0a0aBody text, Work icon, cursor fill
retro-cyan*-retro-cyan#5eead4LED counter display color

How to change a color token

In the source project, tailwind.config.js defines these tokens under theme.extend.colors.retro. To change a color, update the corresponding entry in tailwind.config.js in your local source, then rebuild with npm run build — every Tailwind class that references that token will pick up the change automatically.
tailwind.config.js
// Before
theme: {
  extend: {
    colors: {
      retro: {
        navy:      "#000080",
        magenta:   "#ec4899",
        turquoise: "#00cfd1",
        teal:      "#0d9488",
        gray:      "#c0c0c0",
        darkgray:  "#808080",
        white:     "#ffffff",
        black:     "#0a0a0a",
        cyan:      "#5eead4",
      },
    },
  },
},

// After — swap navy to a deep purple
theme: {
  extend: {
    colors: {
      retro: {
        navy:      "#4b0082", // ← changed
        // ... rest unchanged
      },
    },
  },
},
Changing retro-gray, retro-darkgray, or retro-white will affect the Win98 border utility classes (.win98-out, .win98-in, .win98-btn), which rely on those exact silver/white/gray values to reproduce the authentic beveled chrome look. See Win98 border classes below before modifying those three tokens.

Fonts

Three typefaces are loaded from Google Fonts via a single @import at the top of assets/main.css. Each is mapped to a Tailwind font-* utility class in tailwind.config.js in the source project.
FontTailwind classUsed for
IBM Plex Monofont-monoWindow body content, code snippets, prose
Pixelify Sansfont-pixelHeadings, UI labels, window title bars
VT323font-vt323Terminal displays, visitor counter readout
assets/main.css
@import "https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,700;1,400&family=Pixelify+Sans:wght@400;700&family=VT323&display=swap";
The Tailwind font family declarations look like this in tailwind.config.js in the source project:
tailwind.config.js
theme: {
  extend: {
    fontFamily: {
      mono:  ["IBM Plex Mono", "monospace"],
      pixel: ["Pixelify Sans", "sans-serif"],
      vt323: ["VT323", "monospace"],
    },
  },
},

Swapping a font

To replace a font (for example, swapping VT323 for Press Start 2P), you need the original source project:
  1. Update the Google Fonts @import URL in the source assets/main.css to include the new font family name.
  2. Update the matching fontFamily entry in tailwind.config.js with the new font name.
  3. Run npm run build — every component using that Tailwind class will switch automatically.
assets/main.css
/* Before */
@import "https://fonts.googleapis.com/css2?...&family=VT323&...";

/* After — swap VT323 for Press Start 2P */
@import "https://fonts.googleapis.com/css2?...&family=Press+Start+2P&...";
tailwind.config.js
// Before
fontFamily: {
  vt323: ["VT323", "monospace"],
},

// After
fontFamily: {
  vt323: ["\"Press Start 2P\"", "monospace"],
},

Desktop background

The desktop’s teal background comes from a single rule in assets/main.css applied to the body element. This corresponds to retro-teal (#0d9488) but is set directly rather than via a Tailwind class so it renders before any JavaScript hydrates.
assets/main.css
body {
  margin: 0;
  overflow: hidden;
  background-color: #0d9488; /* retro-teal — the desktop color */
  color: #0a0a0a;
  cursor: none;
}
To change the desktop color, update the background-color hex value in the source and run npm run build. If you want to keep it in sync with a token, update both this rule and the retro-teal entry in tailwind.config.js to the same hex.

Win98 border classes

Three utility classes in assets/main.css reproduce the classic Windows 98 beveled border system. They are intentionally hard-coded to the authentic Win98 silver palette — deviating from these values breaks the raised/sunken illusion.

.win98-out — raised chrome

Used on window frames, Start menu containers, and any element that should appear to sit above the surface.
assets/main.css
.win98-out {
  border-top:    2px solid white;
  border-left:   2px solid white;
  border-bottom: 2px solid black;
  border-right:  2px solid black;
  box-shadow: inset 1px 1px #dfdfdf, inset -1px -1px gray;
  background: silver;
}

.win98-in — sunken / inset

Used for text inputs, scrollable list areas, and any element that should appear pressed into the surface.
assets/main.css
.win98-in {
  border-top:    2px solid #808080;
  border-left:   2px solid #808080;
  border-bottom: 2px solid white;
  border-right:  2px solid white;
  box-shadow: inset 1px 1px #000, inset -1px -1px #dfdfdf;
  background: #fff;
}

.win98-btn — button

Used on interactive buttons. The default cursor is none (overridden to auto on touch devices). The :active pseudo-class swaps the highlight/shadow edges to simulate a physical press.
assets/main.css
.win98-btn {
  cursor: none;
  border-top:    2px solid white;
  border-left:   2px solid white;
  border-bottom: 2px solid black;
  border-right:  2px solid black;
  box-shadow: inset 1px 1px #dfdfdf, inset -1px -1px gray;
  background: silver;
}

/* Touch devices: restore auto cursor */
@media (hover: none) and (pointer: coarse) {
  .win98-btn { cursor: auto; }
}

.win98-btn:active {
  padding-top:   1px;
  padding-left:  1px;
  border-top:    2px solid #808080;
  border-left:   2px solid #808080;
  border-bottom: 2px solid white;
  border-right:  2px solid white;
  box-shadow: inset 1px 1px #000, inset -1px -1px #dfdfdf;
  background: #fff;
}
These classes are calibrated to exact Win98 color keywords (silver, white, black, gray) and hex values (#808080, #dfdfdf, #000, #fff). Modifying any of these values changes the perceived depth of the beveled edges — the raised and sunken effects only work because the highlight and shadow colors are precisely offset from the base silver.

.text-shadow-retro

A simple one-pixel drop shadow applied to heading text to increase legibility against patterned or colorful backgrounds.
assets/main.css
.text-shadow-retro {
  text-shadow: 1px 1px 0px #0a0a0a;
}

CRT effects

Two overlay <div> elements are stacked above the entire app in the root App component to simulate a CRT monitor. They are purely visual and have pointer-events: none so they never intercept clicks.

.crt-overlay — scanlines

Produces horizontal dark lines across the screen by repeating a semi-transparent gradient at a fixed 4 px vertical pitch.
assets/main.css
.crt-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 9998;
  background: linear-gradient(#12101000 50%, #0000001a 50%);
  background-size: 100% 4px;
}
Adjusting scanline density: the 4px value in background-size: 100% 4px controls the pitch of each scanline cycle. Increase it (e.g. 6px, matching the gradient stop offsets) for wider, more visible scanlines; decrease it for a finer, subtler effect. Adjusting scanline intensity: the second color stop #0000001a is black at roughly 10% opacity. Replace the alpha channel — #0000002a is ~16%, #00000040 is 25% — for heavier, more prominent lines.

.crt-vignette — edge darkening

Darkens the corners and edges of the screen with a radial gradient, mimicking the light falloff on a physical CRT tube.
assets/main.css
.crt-vignette {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 9999;
  background: radial-gradient(circle at center, transparent 50%, rgba(0, 0, 0, 0.4) 100%);
}
Adjusting vignette strength: raise the rgba(0, 0, 0, 0.4) alpha value for darker edges (e.g. 0.65 for a very dramatic vignette) or lower it toward 0.10 for subtle shading. Adjusting the 50% stop expands or contracts how far toward the center the darkening reaches.

Disabling the CRT effects

To remove both effects, open the root App component in the source project and delete (or comment out) the two overlay <div> elements:
App component (before)
return (
  <div className="relative w-screen h-screen overflow-hidden">
    <div className="crt-overlay" />
    <div className="crt-vignette" />
    {/* ... rest of the app */}
  </div>
);
App component (after — CRT disabled)
return (
  <div className="relative w-screen h-screen overflow-hidden">
    {/* CRT overlays removed */}
    {/* ... rest of the app */}
  </div>
);
You can also disable them individually — remove only crt-overlay to keep the vignette, or remove only crt-vignette to keep the scanlines. After any change, run npm run build to regenerate the compiled bundle.

Architecture: Styling

Learn how Tailwind, retro tokens, and main.css work together across the full styling architecture.

Adding Pages

Add new portfolio sections — route, component, desktop icon, and static HTML shell.

Build docs developers (and LLMs) love