:root {
  --bg-page: #080808;
  --bg-hover: #111111;

  --text-strong: #FFFFFF;
  --text-primary: #8C8C8C;
  --text-secondary: #2B2B2B;

  --line-dotted: #3A3A3A;

  --hue-1: #FF0000; /* R */
  --hue-2: #00FF00; /* G */
  --hue-3: #0000FF; /* B */

  --dur-hover: 200ms;
  --ease-in: cubic-bezier(.55, 0, 1, .45);
  --ease-out: cubic-bezier(.215, .61, .355, 1);
  --ease-expo: cubic-bezier(.16, 1, .3, 1);
  --ease-amo: cubic-bezier(.175, .885, .32, 1.1);

  --font-mono: 'IBM Plex Mono';
  --font-ss: 'Inter';

  /* Layout knobs — tuned per breakpoint in the Responsive block at the foot
     of this file. Rules reference these instead of hardcoding, so a screen
     size is adjusted in one place. Desktop values live here; mobile overrides
     them. */
  --pad-page-x: 1.5rem;   /* body left/right */
  --pad-page-top: 5rem;   /* body top */
  --pad-page-bottom: 5.5rem;
  --pad-footer-x: 1.25rem;
  --pad-footer-y: 1rem;
  --gap-section: 4rem;    /* space between the main sections */
}

:root[data-theme="light"] {
  --bg-page: #F7F7F7;
  --bg-hover: #E9E9E5;

  --text-strong: #000000;
  --text-primary: #737373;
  --text-secondary: #D4D4D4;

  --line-dotted: #B8B8B8;

  --hue-1: #00FFFF; /* C */
  --hue-2: #FF00FF; /* M */
  --hue-3: #FFFF00; /* Y */
}

*, *::before, *::after { box-sizing: border-box; }

/* Suppress the mobile tap-highlight: on touch (and desktop mobile-emulation),
   WebKit/Blink paints a translucent rgba(51,181,229,.4) box over tap targets.
   Our hover/active states already signal the interaction; this leaves the
   keyboard :focus-visible ring untouched. */
a, button { -webkit-tap-highlight-color: transparent; }

body {
  overflow-y: scroll;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0;
  padding: var(--pad-page-top) var(--pad-page-x) var(--pad-page-bottom);
  background: var(--bg-page);
  color: var(--text-primary);
  text-rendering: optimizeLegibility;
  font: 460 .875rem/1.25rem var(--font-mono), monospace;
  letter-spacing: -.00563rem;
  /* text-transform: uppercase; */
  -webkit-font-smoothing: antialiased;
  transition: background-color var(--dur-hover), color var(--dur-hover);
}

h1, h2, p { margin: 0; }
h1, h2 { line-height: 1; font: inherit; color: var(--text-strong); }
s { color: var(--text-secondary); }

/* Header / footer ---------------------------------------------------- */

header {
  display: flex;
  flex-direction: column; 
  width: 100%;
}

/* The toggle is the only thing that fills on hover; links use their underline. */
button {
  display: flex;
  margin: -12px;
  padding: 12px;
  border: none;
  background: none;
  color: var(--text-primary);
  cursor: pointer;
  transition: color var(--dur-hover) var(--ease-out),
              background-color var(--dur-hover) var(--ease-out),
              transform var(--dur-hover) var(--ease-amo);
}
/* Hover effects are gated behind `hover: hover` so they only fire on devices
   with a real pointer. On touch screens a tap counts as a hover that has
   nowhere to move away to, so an unguarded :hover would stick to the tapped
   element until the next tap — the lingering state we're avoiding here. */
@media (hover: hover) {
  button:hover {
    color: var(--text-strong);
    transform: scale(1.12);
  }
}
/* :active mirrors the hover effect so touch devices — which never hover —
   still get feedback, but only for the duration of the press, so nothing
   lingers after the finger lifts. */
button:active {
  color: var(--text-strong);
  transform: scale(1.12);
}
@media (hover: hover) and (prefers-reduced-motion: reduce) {
  button:hover { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  button:active { transform: none; }
}

/* The toggle fades in with the entrance. A CSS animation fires once when the
   element first renders (page load); it is NOT replayed on theme switch, so the
   icon keeps its own swing there. The delay holds the toggle hidden until the
   scramble is about halfway through, so it materialises mid-scramble rather than
   leading it. */
@keyframes toggle-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
[data-theme-toggle] {
  animation: toggle-in 700ms var(--ease-out) 800ms both;
}
@media (prefers-reduced-motion: reduce) {
  [data-theme-toggle] { animation: none; }
}

/* Every link wears a dotted underline that goes solid on hover. The worklist
   name rides along: its own <a> can't carry the underline (see below). Keep
   that half scoped to .work — the scramble wraps loose prose in spans, so a
   broader `section span` would dress the intro paragraphs as links.
   Only the colour eases — text-decoration-style is not animatable, so the
   dots knit into a line in a single frame. */
a, .list span:first-child {
  color: var(--text-primary);
  text-decoration: underline dotted var(--line-dotted) 1px;
  text-underline-offset: 4px;
  transition: color var(--dur-hover) var(--ease-out),
              text-decoration-color var(--dur-hover) var(--ease-out);
}
@media (hover: hover) {
  a:hover, .list a:hover span:first-child {
    color: var(--text-strong);
    text-decoration-style: solid;
    text-decoration-color: var(--text-strong);
  }
}
a:active, .list a:active span:first-child {
  color: var(--text-strong);
  text-decoration-style: solid;
  text-decoration-color: var(--text-strong);
}

/* Content ------------------------------------------------------------ */

main {
  display: flex;
  flex-direction: column;
  gap: var(--gap-section);
  width: 100%;
  max-width: 70ch;
}

section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.intro {
  gap: 1.25rem;
}

.list {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 24px;
  row-gap: 0px;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Both the <li> and its <a> re-declare the parent's three columns via subgrid
   and span all of them, so the grid track passes straight through the list
   item down to the spans — name / blurb / years stay aligned across rows. */
.list li,
.list a {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: span 2;
  margin-block: 0; /* a grid row can't pull vertically without collapsing */
  text-decoration: none;
  /* transform is re-listed here on purpose: this rule (.list a, 0,1,1) outranks
     the generic `a` transition (0,0,1), so without it the scale on hover has no
     transition and snaps instead of easing. Keep opacity for the dim effect. */
  transition: opacity var(--dur-hover),
              transform var(--dur-hover) var(--ease-amo);
}

/* Height lives on the <a>, not the <li>: the <a> is the hover target, so
   padding it (rather than its wrapper) makes the whole taller box hoverable.
   Only the block axis — inline padding would offset the subgrid from the
   parent's column lines and break name/year alignment. With row-gap: 0 the
   anchors tile edge-to-edge, so the hover zone is continuous down the list. */
.list a {
  align-items: center;
  padding-block: 4px;
}

.list span:last-child {
  color: var(--text-secondary);
  text-align: right;
}

/* While an item is hovered, dim every *other* item. Scoping the trigger to
   :has(a:hover) — rather than .work:hover — exempts the <h2> heading, which
   otherwise counts as hovering the section. The :not(:hover) spares the
   hovered row itself, so we don't need a higher-specificity rule to undo it. */
@media (hover: hover) {
  .list:has(a:hover) a:not(:hover) { opacity: .35; }
}
.list:has(a:active) a:not(:active) { opacity: .35; }

footer {
  position: fixed;
  bottom: 0;
  display: flex;
  justify-content: space-between;
  padding: var(--pad-footer-y) var(--pad-footer-x);
  width: 100%;
  color: var(--text-primary);
  font: 400 12px var(--font-mono);
  font-size: 12px;
}

footer a { white-space: nowrap; }

/* Responsive --------------------------------------------------------- */

/* Desktop-first: the rules above hold the base (larger) values; each query
   below only re-tunes the layout knobs for narrower screens. Add a new token
   to :root, reference it in a rule, then override it here — one place per
   breakpoint. 640px is roughly where the 70ch column stops fitting with room
   to breathe. */
@media (max-width: 640px) {
  :root {
    --pad-page-x: 1.5rem;
    --pad-page-top: 2rem;
    --pad-page-bottom: 5.5rem;
    --gap-section: 3rem;
    --pad-footer-y: 1.25rem;
  }
}