/* ================================================================
   WinExpat — winexpat.com

   Bilingual signage. Two languages, one sign: square caps are what
   your hands do, rounded caps are what the Mac wanted all along.
   Precision is the register; the jokes live in the words.
   ================================================================ */

@font-face {
  font-family: "Archivo";
  src: url("/fonts/Archivo.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}
/* SF stand-in for machines without SF: Apple hardware never reaches this
   (the -apple-system entries win), Windows gets Inter instead of Segoe so
   the Mac dialect still looks Apple there. Self-hosted like the others. */
@font-face {
  font-family: "Inter";
  src: local("Inter"), url("/fonts/Inter-Medium.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}

:root {
  /* --- ink & paper ------------------------------------------- */
  --paper:       oklch(1 0 0);
  --surface:     oklch(0.968 0.006 258);
  --ink:         oklch(0.17 0.02 258);
  --ink-2:       oklch(0.40 0.022 258);
  --rule:        oklch(0.87 0.012 258);
  --rule-strong: oklch(0.74 0.018 258);

  /* --- blue: identity, then authority ------------------------ */
  --blue:        oklch(0.51 0.14 252);   /* the app icon. links, marks. */
  --blue-deep:   oklch(0.355 0.115 258); /* the drenched band */
  --blue-dark:   oklch(0.225 0.07 258);  /* declaration board, footer */
  --blue-pale:   oklch(0.86 0.045 252);  /* type on deep blue */
  --blue-rule:   oklch(0.50 0.075 258);  /* rules on deep blue */
  --blue-rule-2: oklch(0.36 0.05 258);   /* rules on the dark board */

  /* --- amber: demoted to a stamp ----------------------------- */
  --stamp:       oklch(0.72 0.155 68);
  --stamp-soft:  oklch(0.955 0.035 80);
  --stamp-rule:  oklch(0.80 0.09 75);
  --stamp-ink:   oklch(0.42 0.105 62);

  /* --- redmond: the Windows dialect, in the Windows 11 logo blue -----
         Deliberately NOT a solid fill. #0078d4 and Cupertino's #0071e3
         are ~7° apart in hue; two solid caps side by side would read as
         one dialect in two shades. So Redmond gets the tinted/ruled
         weight and Cupertino keeps the solid fill — the caps stay
         instantly tellable apart on fill and radius, and each finally
         wears its own brand blue instead of Windows wearing grey. */
  --win-blue: #0078d4;
  --win-soft: color-mix(in oklab, #0078d4 7%, #ffffff);
  --win-soft-2: color-mix(in oklab, #0078d4 14%, #ffffff);
  /* 60% lands the rule at 2.30:1 on paper — the grey it replaced was 2.31:1,
     so the cap edge stays exactly as crisp, just in the other dialect. */
  --win-rule: color-mix(in oklab, #0078d4 60%, #ffffff);
  --win-shade: color-mix(in oklab, #0078d4 30%, #ffffff);
  --win-ink:  #00538f;

  /* --- cupertino: the Mac dialect, matched to Smitee's Cupertino
         theme — action blue, deep link blue for ink ---------------- */
  --mac-blue: #0071e3;
  --mac-blue-deep: #0058b0;
  --mac-soft: color-mix(in oklab, #0071e3 9%, #ffffff);
  --mac-rule: color-mix(in oklab, #0071e3 35%, #ffffff);
  --mac-ink:  #0058b0;

  /* ONE prose family. Archivo sets every word on this site. --win-key and
     --mac-key are keycap-only: the dialect motif lives on the caps, never in
     running text, or the page reads as four fonts fighting. */
  --sans: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --win-key: "Segoe UI", Tahoma, Arial, sans-serif;
  --mac-key: -apple-system, "system-ui", "SF Pro Text", "Helvetica Neue", "Inter", "Segoe UI", system-ui, sans-serif;
  /* the modifier glyphs ⌘ ⇧ ⌥ ⌃ ⇥ ← → ⊞ only exist in the system mono; see .sym */
  --glyph: "Cascadia Code", ui-monospace, Menlo, monospace;

  --r-win: 2px;   /* the Windows dialect: square */
  --r-mac: 8px;   /* the Mac dialect: rounded, but measured */

  /* --- type scale -------------------------------------------------
     ONE ladder, anchored on 17px body. Every size on the site is one of
     these seven; no raw rem values anywhere else.

     The ratio is 1.25 ABOVE body and ~1.13 BELOW it, on purpose. 1.25 is
     what display hierarchy wants; applied downward from a 17px body it
     lands secondary prose at 13.6px, which turns every caption, hint and
     note into fine print. Captions and hints are prose people actually
     read, so they sit one gentle step under body and take their
     subordination from colour (--ink-2), not from being small.
     --text-label is 12px because it is only ever ALL-CAPS, which reads
     optically larger — a different class, not a second helping of small. */
  --text-label: 0.75rem;                                  /* 12px  caps labels */
  --text-small: 0.9375rem;                                /* 15px  captions, notes, nav */
  --text-body:  1.0625rem;                                /* 17px  body */
  --text-lead:  1.328rem;                                 /* 21px  ledes, sub-heads */
  --text-h3:    1.66rem;                                  /* 27px */
  --text-h2:    clamp(2.075rem, 2.6vw + 1.1rem, 3.24rem);
  --text-h1:    clamp(2.594rem, 3.6vw + 0.9rem, 4.05rem);

  /* --- and the rest of the type system, in full ---------------------
     weights:  400 body · 500 labels and keycaps · 600 sub-heads and
               buttons · 700 display.           Nothing between them.
     widths:   112% display (h1/h2/brand) · 108% sub-head · 100% body.
     tracking: -0.025em h1 · -0.02em h2 · -0.012em h3 · 0.06em caps.
     leading:  1.08 display · 1.5 lede · 1.6 body · 1.7 small-on-dark
               (light type on a dark ground reads lighter and needs it). */

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --z-sticky: 10;

  --measure: 70rem;
  --pad-x: clamp(1.25rem, 4vw, 3.5rem);
  --space-section: clamp(4rem, 8vw, 7rem);
}

* { box-sizing: border-box; margin: 0; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--sans);
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; display: block; }
a { color: oklch(0.44 0.13 255); }

h1, h2, h3 { line-height: 1.08; text-wrap: balance; }
h1, h2 {
  font-stretch: 112%;          /* signage width */
  font-weight: 700;
  letter-spacing: -0.02em;
}
h3 { font-stretch: 108%; font-weight: 600; letter-spacing: -0.012em; }
p { text-wrap: pretty; }

.wrap { max-width: var(--measure); margin-inline: auto; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 2px; }
.hero :focus-visible, .board :focus-visible, .site-foot :focus-visible { outline-color: var(--mac-blue); }

::selection { background: var(--mac-soft); color: var(--ink); }

/* ================================================================
   Keycaps — engineered, not gummy. Two dialects.
   ================================================================ */

.k {
  display: inline-block;
  font-family: var(--win-key);
  font-size: 0.82em;
  font-weight: 500;
  line-height: 1;
  padding: 0.36em 0.5em 0.4em;
  margin: 0 0.08em;
  color: var(--win-ink);
  background: linear-gradient(var(--win-soft), var(--win-soft-2));
  border: 1px solid var(--win-rule);
  border-radius: var(--r-win);
  box-shadow: inset 0 -1px 0 var(--win-shade);
  white-space: nowrap;
}
/* Optical size correction for the modifier glyphs.
   The system mono draws ⌘ ⇧ ⌥ ⌃ ⇥ ← → ⊞ at four different sizes — against a
   0.80em reference cap height: ⇧ 0.56, ⌘ 0.53, ⊞ 0.53, ⌥ 0.48, ⌃ 0.34,
   ⇥ ← → 0.32. Each therefore needs its own multiplier; one shared font-size
   cannot fix them.
   (size-adjust on a local() @font-face is the tidier mechanism and is silently
   ignored by Chromium — verified at 400%, zero visual change. Plain font-size
   works everywhere.)
   line-height: 0 keeps the enlarged glyph from growing the keycap; even at 2×
   these stay under cap height, so nothing overflows. ↑ ↓ are left alone.

   vertical-align then re-centres each glyph, because they are not
   baseline-aligned the way letters are — they hang off the maths axis, so
   scaling them up pushed the ink upward. Letters occupy baseline→0.80em,
   centre 0.40em; measured ink centres before correction were ⌃ 1.03 (its ink
   bottom sits 0.72em *above* the baseline), ← → 0.56, ⌥ 0.55, ⌘ 0.55,
   ⇥ 0.53, ⊞ 0.46. vertical-align is in em of the span, so these values are
   already scaled by the font-size above them. */
.sym {
  line-height: 0;
  font-size: calc(1em * var(--sym-s));
  vertical-align: calc(-1em * var(--sym-v));
}
.sym-cmd   { --sym-s: 1.44; --sym-v: 0.102; }   /* ⌘ */
.sym-shift { --sym-s: 1.46; --sym-v: 0.005; }   /* ⇧ — near enough already */
.sym-opt   { --sym-s: 1.55; --sym-v: 0.098; }   /* ⌥ */
.sym-ctl   { --sym-s: 1.78; --sym-v: 0.351; }   /* ⌃ — the big offender */
.sym-tab   { --sym-s: 1.92; --sym-v: 0.066; }   /* ⇥ */
.sym-arw   { --sym-s: 2.05; --sym-v: 0.079; }   /* ← → — matches the mono's own ↑ ↓ */

/* The Windows mark is drawn (see the "winmark" template), not typeset, so it
   needs no optical multiplier and no per-context override — one size works in
   a keycap and in running text alike. Being a replaced element, its bottom
   edge IS its baseline, so it lands on the cap-height band for free.
   currentColor means it picks up Windows-blue ink on paper caps and white on
   the inverted ones without a second rule. */
.winmark {
  width: 0.74em; height: 0.74em;
  fill: currentColor;
  display: inline-block;
  vertical-align: -0.012em;   /* optical: square mass sits a touch heavy */
}

/* The values above are measured against Martian Mono inside a keycap. In
   running text the reference is Archivo's cap height (0.686, vs the mono's
   0.80) AND the sans fallback draws these glyphs larger than the mono one
   does — so the keycap multipliers overshoot badly there, ⌘ by about 60%.
   Only ⌘ currently appears outside a keycap. */
:not(.k) > .sym-cmd { --sym-s: 0.90; --sym-v: -0.018; }

/* Windows caps set letters in Segoe/Tahoma, but the symbol glyphs must keep
   the mono chain the .sym multipliers were measured against. (That chain used
   to start with a self-hosted Martian Mono, which was preloaded, downloaded,
   and drew exactly zero glyphs — it has none of the eight symbols above. The
   mono that actually draws them has always been the system one.) */
.k .sym { font-family: var(--glyph); }

.k.mac {
  font-family: var(--mac-key);
  font-weight: 500;
  border-radius: var(--r-mac);
  background: var(--mac-blue);
  border-color: var(--mac-blue);
  box-shadow: none;
  color: #fff;
}
/* SF Pro draws ⌘ ⇧ ⌥ ⌃ ⇥ natively at text size — no optical correction needed */
.k.mac .sym { font-family: inherit; --sym-s: 1; --sym-v: 0; }
/* on the deep-blue band the caps invert */
.hero .k, .board .k {
  color: var(--paper);
  background: oklch(1 0 0 / 0.10);
  border-color: oklch(1 0 0 / 0.42);
  box-shadow: inset 0 -1px 0 oklch(0 0 0 / 0.14);
}
/* the generic on-blue .k override above must not wash out the solid blue */
.hero .k.mac, .board .k.mac {
  background: var(--mac-blue);
  border-color: var(--mac-blue);
  box-shadow: none;
  color: #fff;
}

/* ================================================================
   The sign — the site's structural spine.
   An airport sign: primary language on top, local language below,
   a rule between them. Used in the hero, the features, the table.
   ================================================================ */

.sign { border-top: 1px solid var(--rule); }
.sign-row {
  display: grid;
  grid-template-columns: 11.5rem 1fr;
  gap: 0 1.5rem;
  align-items: baseline;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule);
}
.sign-lang {
  font-family: var(--sans);
  font-size: var(--text-label);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding-top: 0.15em;
}
.sign-row.is-mac .sign-lang { color: var(--mac-ink); }
/* on light sections the whole Mac row speaks in the dialect ink;
   the hero keeps its pale-on-navy palette */
.feat .sign-row.is-mac :is(.sign-gloss, .chord-lit, .chord-plus) { color: var(--mac-ink); }
/* The dialect is carried by the KEYCAPS — square/pale vs rounded/blue — and by
   ink colour on the Mac rows. It used to be carried by the prose font as well:
   glosses and connective words were set in SF or Segoe, so a sentence next to a
   Mac key rendered in a different typeface from the identical sentence one row
   up. Four families in running text bought a distinction the caps already make. */
.sign-keys { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.9rem; }
.sign-gloss { color: var(--ink-2); }

/* the hero's sign inverts onto the blue */
.hero .sign { border-top-color: var(--blue-rule); }
.hero .sign-row { border-bottom-color: var(--blue-rule); }
.hero .sign-lang { color: var(--blue-pale); }
.hero .sign-row.is-mac .sign-lang { color: oklch(0.82 0.08 252); }
.hero .sign-gloss { color: var(--blue-pale); }
.hero .no-equiv { color: oklch(0.82 0.09 252); }

/* ================================================================
   Header
   ================================================================ */

.site-head {
  position: sticky; top: 0; z-index: var(--z-sticky);
  border-bottom: 1px solid var(--rule);
  background: oklch(1 0 0 / 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
/* This is the site's own signage bar, and a sign is never apologetic. It used
   to run 62px tall with a 17px wordmark and 13.6px links floating in it, which
   read as reluctance to occupy the top of the page at all. */
.site-head .wrap {
  display: flex; align-items: center; gap: 2rem;
  padding: 0.85rem var(--pad-x);
}
.brand {
  display: flex; align-items: center; gap: 0.7rem;
  font-stretch: 112%; font-weight: 700; font-size: var(--text-lead);
  color: var(--ink); text-decoration: none;
}
.site-head nav { display: flex; gap: 1.9rem; margin-left: auto; }
/* Body size, not --text-small. The nav is the site's primary wayfinding, and
   --text-small is the caption tier — putting navigation there set it SMALLER
   than the paragraphs it navigates to (0.88× body), which is what made the bar
   read as an afterthought even after it grew taller. Nothing in this bar goes
   below --text-body; the wordmark takes one step up from it. */
.site-head nav a {
  color: var(--ink-2); text-decoration: none;
  font-size: var(--text-body); font-weight: 500;
  padding: 0.4rem 0;
  border-bottom: 1px solid transparent;
}
.site-head nav a:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* ================================================================
   Buttons — authority, not candy
   ================================================================ */

.btn {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  font-family: var(--sans); font-weight: 600;
  text-decoration: none;
  border-radius: var(--r-win);
  transition: background 0.18s var(--ease-out), border-color 0.18s var(--ease-out),
              color 0.18s var(--ease-out);
}
.btn small {
  font-family: var(--sans); font-weight: 400;
  font-size: var(--text-small);
  margin-top: 0.25rem;
}

.btn-head {
  margin-left: auto;
  background: var(--ink); color: var(--paper);
  padding: 0.5rem 1.2rem; font-size: var(--text-body);
  border: 1px solid var(--ink);
}
.btn-head:hover { background: var(--blue-deep); border-color: var(--blue-deep); }

.btn-lg {
  padding: 0.85rem 1.6rem 0.95rem;
  font-size: var(--text-lead);
  line-height: 1.15;
  border: 1px solid;
}
/* on blue: white block, blue type */
.btn-invert { background: var(--paper); color: var(--blue-deep); border-color: var(--paper); }
.btn-invert small { color: oklch(0.42 0.09 258); }
.btn-invert:hover { background: oklch(0.94 0.02 252); border-color: oklch(0.94 0.02 252); }
/* on paper: ink block */
.btn-solid { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn-solid small { color: oklch(0.80 0.02 258); }
.btn-solid:hover { background: var(--blue-deep); border-color: var(--blue-deep); }

/* ================================================================
   Hero
   ================================================================ */

.hero { background: var(--blue-deep); color: var(--paper); }
.hero .wrap { padding: clamp(3rem, 6vw, 5.5rem) var(--pad-x) 0; }

.hero-top {
  display: grid;
  grid-template-columns: minmax(0, 30rem) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.hero h1 {
  font-size: var(--text-h1);
  font-stretch: 112%;
  font-weight: 700;
  letter-spacing: -0.025em;
  margin-bottom: 1.4rem;
}
.hero .lede {
  font-size: var(--text-lead);
  line-height: 1.5;
  color: var(--blue-pale);
  margin-bottom: 2rem;
  max-width: 30rem;
}
.hero .lede strong { color: var(--paper); font-weight: 600; }
.cta-row { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }
.cta-note {
  font-family: var(--sans);
  font-size: var(--text-small); line-height: 1.7;
  color: var(--blue-pale);
}

.hero-sign { padding-bottom: clamp(2rem, 4vw, 3rem); }
.hero-sign .sign-row { grid-template-columns: 13rem 1fr; }
/* the two language rows share one grid, so each phrase sits above its
   translation — the whole point of a bilingual sign */
.hero-sign .sign-keys {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.4rem 1.5rem;
  align-items: center;
}
.hero-sign .pair { display: flex; align-items: center; gap: 0.1rem; min-width: 0; }
.hero-sign .pair.sign-gloss { display: block; }

/* ================================================================
   Screenshot frames — the proof
   ================================================================ */

.shot-fig { min-width: 0; }
.shot {
  position: relative;
  border-radius: var(--r-mac);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--rule);
  box-shadow: 0 1px 2px oklch(0.2 0.04 258 / 0.08), 0 18px 40px oklch(0.2 0.04 258 / 0.14);
}
.hero .shot {
  border-color: oklch(1 0 0 / 0.22);
  box-shadow: 0 2px 4px oklch(0.12 0.05 258 / 0.3), 0 30px 60px oklch(0.1 0.05 258 / 0.45);
}
.shot img { width: 100%; height: auto; }
.shot-cap {
  font-family: var(--sans);
  font-size: var(--text-small);
  color: var(--ink-2);
  margin-top: 0.7rem;
}
.hero .shot-cap { color: var(--blue-pale); }

/* An SVG stand-in, not a capture. The badge is deliberately loud: it has to be
   impossible to ship one of these by accident. It disappears on its own the
   moment the matching .png lands in static/shots/. */
.shot.is-mock::after {
  content: "Mock-up — not a real screenshot";
  position: absolute; top: 0; left: 0;
  font-family: var(--sans);
  font-size: var(--text-small);   /* sentence case, so --text-small not --text-label */
  color: var(--ink);
  background: var(--stamp);
  padding: 0.4rem 0.7rem;
  border-bottom-right-radius: var(--r-win);
  box-shadow: 0 1px 6px oklch(0.2 0.04 258 / 0.25);
}

/* placeholder while a shot is missing — visible, never a broken image */
.shot-pending {
  aspect-ratio: 16 / 10;
  display: grid; place-items: center;
  font-family: var(--sans); font-size: var(--text-small);
  color: var(--ink-2);
  background:
    repeating-linear-gradient(135deg,
      oklch(0.94 0.008 258) 0 8px, oklch(0.965 0.006 258) 8px 16px);
}

/* ================================================================
   The declaration board — shortcuts with nothing to declare
   ================================================================ */

.board {
  background: var(--blue-dark);
  color: var(--blue-pale);
  padding: clamp(3rem, 5vw, 4.5rem) 0;
}
.board .wrap { padding-inline: var(--pad-x); }
.board h2 {
  font-size: var(--text-h3);
  color: var(--paper);
  margin-bottom: 0.4rem;
}
.board-lede { color: var(--blue-pale); font-size: var(--text-small); margin-bottom: 2rem; max-width: 44rem; }
.board-list {
  list-style: none; padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 0 clamp(1.5rem, 4vw, 3.5rem);
  border-top: 1px solid var(--blue-rule-2);
}
.board-list li {
  display: flex; align-items: baseline; gap: 0.75rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--blue-rule-2);
  font-size: var(--text-small);
}
.board-list .board-keys { white-space: nowrap; }
.board-list .leader {
  flex: 1;
  border-bottom: 1px dotted var(--blue-rule-2);
  transform: translateY(-0.25em);
  min-width: 1.5rem;
}
.board-list .nil { font-family: var(--sans); font-size: var(--text-small); color: oklch(0.68 0.03 258); }
.board-tag {
  margin-top: 2rem;
  font-size: var(--text-lead);
  font-stretch: 108%; font-weight: 600;
  color: var(--paper);
  max-width: 40rem;
}
.board-tag em { font-style: normal; color: oklch(0.72 0.14 252); }

/* ================================================================
   Reflexes — the feature sections
   ================================================================ */

.reflexes { padding: var(--space-section) 0; }
.reflexes .wrap { padding-inline: var(--pad-x); }
.reflexes h2, .phrasebook h2, .install h2 { font-size: var(--text-h2); }
.section-lede {
  font-size: var(--text-lead);
  color: var(--ink-2);
  max-width: 44rem;
  margin-top: 1rem;
  line-height: 1.5;
}
.section-lede strong { color: var(--ink); font-weight: 600; }

.feat {
  display: grid;
  grid-template-columns: minmax(0, 25rem) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
  margin-top: clamp(3rem, 6vw, 5rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--rule);
}
/* mirrored row: swap the tracks too, so the screenshot keeps the wide
   column instead of inheriting the copy's narrow one */
.feat-flip { grid-template-columns: minmax(0, 1fr) minmax(0, 25rem); }
.feat-flip .feat-copy { order: 2; }
.feat h3 { font-size: var(--text-h3); margin-bottom: 0.75rem; }
.feat p { color: var(--ink-2); }
.feat p + p { margin-top: 0.8rem; }
.feat .sign { margin-top: 1.5rem; }

/* ================================================================
   Phrasebook — the full bilingual reference
   ================================================================ */

.phrasebook { background: var(--surface); padding: var(--space-section) 0; }
.phrasebook .wrap { padding-inline: var(--pad-x); }
.phrasebook .section-lede { margin-bottom: 2.5rem; }

.group-name {
  font-size: var(--text-small);
  font-family: var(--sans);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-top: 3rem;
  padding-bottom: 0.6rem;
  border-bottom: 2px solid var(--ink);
}
.group-name:first-of-type { margin-top: 0; }

.phrase-table { width: 100%; border-collapse: collapse; }
.phrase-table th {
  font-family: var(--sans);
  font-size: var(--text-label);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: left;
  color: var(--ink-2);
  padding: 0.85rem 1rem 0.85rem 0;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.phrase-table th.col-mac { color: var(--mac-ink); }
.phrase-table td {
  padding: 0.65rem 1rem 0.65rem 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: baseline;
}
/* Live keyboard highlight. The old wash was #ebf3fe on a #f2f5f9 surface —
   an RGB distance of 9, which is not "subtle", it is invisible. This tint is
   24% Windows blue: distance 46, and every ink on it still clears 4.5:1 (ink
   14.0, --ink-2 6.8, --mac-ink 5.1). Past 28% the Mac column starts failing.
   Windows blue rather than Mac blue on purpose: every key that can trigger
   this is a Windows-side key, so the rows light in that dialect's colour.
   Fast in, slow out — the strike lands, then decays. */
.phrase-table tr { transition: background 0.55s var(--ease-out); }
.phrase-table tbody tr.hl {
  background: color-mix(in oklab, #0078d4 24%, #ffffff);
  transition-duration: 0.07s;
}
.phrase-table tbody tr.hl td { border-bottom-color: var(--win-rule); }
.phrase-table tbody tr.hl .col-does { color: var(--ink); }

/* The key you are physically holding is drawn right there on the page, so it
   goes down with your finger: the raised inset highlight along the bottom edge
   becomes a shadow along the top, which is what a depressed key actually looks
   like. Caps track the real key state (down on keydown, up on keyup) while the
   rows dwell, so your hands drive the caps and the rows stay put to be read. */
.k { transition: transform 0.45s var(--ease-out), background 0.45s var(--ease-out),
                 box-shadow 0.45s var(--ease-out), border-color 0.45s var(--ease-out); }
/* :not(.mac) is insurance — a Mac cap keeps `color: #fff`, so this tinted fill
   under it would be white-on-pale, ~1.6:1 and unreadable */
.k.k-down:not(.mac) {
  transform: translateY(1px);
  background: color-mix(in oklab, #0078d4 30%, #ffffff);
  border-color: var(--win-blue);
  box-shadow: inset 0 2px 3px oklch(0.45 0.12 250 / 0.30);
  transition-duration: 0.05s;
}
/* Fixed widths, identical in all four group tables, sized to the widest
   content across all of them — nothing wraps, everything lines up. */
.col-win { width: 13.5rem; white-space: nowrap; }
.col-does { color: var(--ink); }
.col-mac { width: 25rem; white-space: nowrap; color: var(--mac-ink); }
/* connective words in the Mac column pick up the dialect ink, not gray */
.col-mac .chord-lit, .col-mac .chord-plus { color: inherit; }
.mac-word { margin: 0 0.15em; }
/* connective words are prose, so they set in the prose face like everything
   else; only their colour says which dialect they belong to */
.chord-plus { color: var(--ink-2); margin: 0 0.15em; }
.chord-lit { color: var(--ink-2); margin: 0 0.15em; }
.no-equiv { color: var(--mac-ink); }

.kb-hint {
  display: none;
  font-family: var(--sans);
  font-size: var(--text-small);
  color: var(--ink-2);
  margin: 0 0 2.25rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--rule);
  background: var(--paper);
}
@media (hover: hover) and (pointer: fine) { .kb-hint { display: block; } }

/* ================================================================
   Install — the form
   ================================================================ */

.install { padding: var(--space-section) 0; }
.install .wrap { padding-inline: var(--pad-x); max-width: 52rem; }
.install .section-lede { margin-bottom: 2.5rem; }

.steps {
  list-style: none; padding: 0; margin: 0 0 2.5rem;
  counter-reset: step;
  border-top: 1px solid var(--ink);
}
.steps li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  gap: 0.3rem 1.25rem;
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--rule);
}
.steps li::before {
  content: counter(step);
  grid-row: 1 / 3;
  font-family: var(--sans); font-weight: 600; font-size: var(--text-small);
  width: 2.1rem; height: 2.1rem;
  display: grid; place-items: center;
  color: var(--ink);
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-win);
  margin-top: 0.1rem;
}
.steps li:last-child::before {
  /* the last step goes native */
  border-radius: var(--r-mac);
  border-color: var(--mac-rule);
  background: var(--mac-soft);
  color: var(--mac-ink);
}
.steps h3 { font-size: var(--text-lead); }
.steps p { color: var(--ink-2); grid-column: 2; max-width: 44rem; }
.install-note {
  margin-top: 1.25rem;
  font-size: var(--text-small); color: var(--ink-2); max-width: 38rem;
}

/* ================================================================
   Footer
   ================================================================ */

.site-foot {
  background: var(--blue-dark);
  color: var(--blue-pale);
  padding: clamp(3rem, 5vw, 4rem) 0;
}
.site-foot .wrap {
  padding-inline: var(--pad-x);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 2rem clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.foot-brand { display: flex; gap: 0.85rem; align-items: flex-start; }
.foot-brand p, .foot-kin { font-size: var(--text-small); line-height: 1.7; }
.site-foot a { color: oklch(0.78 0.11 252); }
.foot-legal {
  grid-column: 1 / -1;
  font-size: var(--text-small); color: oklch(0.66 0.03 258);
  padding-top: 1.5rem;
  border-top: 1px solid var(--blue-rule-2);
}

/* ================================================================
   Motion — measured. Content is visible by default; JS only ever
   adds the rise, so no-JS and hidden tabs still render complete.
   ================================================================ */

.rise.armed { opacity: 0; transform: translateY(14px); }
.rise.armed.in {
  opacity: 1; transform: none;
  transition: opacity 0.6s var(--ease-out), transform 0.7s var(--ease-out);
}

/* the hero chord presses itself — the one demonstrative animation */
.hero-sign .k-demo { animation: press 5s infinite; }
.hero-sign .k-demo.d2 { animation-delay: 0.45s; }
@keyframes press {
  0%, 14%   { transform: none; }
  17%, 26%  { transform: translateY(1.5px); background: oklch(1 0 0 / 0.26); }
  30%, 100% { transform: none; }
}

/* ================================================================
   Responsive
   ================================================================ */

@media (max-width: 980px) {
  .hero-top { grid-template-columns: 1fr; }
  .hero .lede { max-width: 46rem; }
  .feat, .feat-flip { grid-template-columns: 1fr; gap: 1.75rem; }
  .feat-flip .feat-copy { order: 0; }
}

@media (max-width: 720px) {
  .site-head nav { display: none; }
  .sign-row, .hero-sign .sign-row { grid-template-columns: 1fr; gap: 0.4rem; }
  .sign-lang { padding-top: 0; }
  /* four phrases per row is a desktop sign; halve it so the pairs still
     line up above their translations instead of shredding into columns */
  .hero-sign .sign-keys { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.7rem 1rem; }
  .hero .lede { font-size: var(--text-body); }

  /* the phrasebook becomes the sign: Mac equivalent stacks under the
     Windows chord instead of vanishing off the edge. */
  .phrase-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .phrase-table tr { display: block; padding: 0.9rem 0; border-bottom: 1px solid var(--rule); }
  .phrase-table td { display: block; border: 0; padding: 0; }
  .col-win, .col-mac { width: auto; white-space: normal; }
  .col-does { font-size: var(--text-small); color: var(--ink-2); margin-top: 0.35rem; }
  .col-mac {
    margin-top: 0.5rem; padding-top: 0.5rem;
    border-top: 1px solid var(--rule);
  }
  .col-mac::before {
    content: "The Mac way";
    display: block;
    font-family: var(--sans); font-size: var(--text-label);
    letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--mac-ink);
    margin-bottom: 0.35rem;
  }
}

/* ================================================================
   Reduced motion
   ================================================================ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
  /* .armed is set by JS at load; if reduce is switched on afterwards it would
     otherwise strand these figures at opacity 0 */
  .rise, .rise.armed { opacity: 1 !important; transform: none !important; }
}
