/* Sizemac's site. One stylesheet, every page.
 *
 * THESIS. The page is a drafting board. Sizemac's one idea is that a window goes
 * exactly where you told it, so the site is drawn the way a placement is
 * specified: a ruled ground with a real grid on it, line work, sheets laid on
 * the board, dimension callouts carrying the actual fraction, a schedule of every
 * placement, and a title block at the foot.
 *
 * TWO APPEARANCES, IN THE SAN FRANCISCO GIANTS' COLORS (Derick, 2026-10-07, the
 * palette sheet's 1A and 1B). Cream paper by day, Giants black at night,
 * following the Mac. Every color below is a token defined once per appearance;
 * nothing further down this file names a color of its own, so a value that
 * reads in one appearance cannot be forgotten in the other. The site's earlier
 * dark mode shipped a headline at 1.09:1, which is why `contrastcheck` reads
 * every page in both appearances before a deploy. Full brief: docs/DESIGN.md.
 */
:root{
  color-scheme:light dark;

  /* 1A, by day. The board and the sheets laid on it. */
  --ground:#F4EBD7; --sheet:#FBF7EE; --raised:#EBDFC6; --screen:#E6D8BC;
  /* The line work. Ratios on the ground: 13.8, 6.6, 4.8. */
  --ink:#27251F; --ink-2:#57524A; --ink-3:#6E675B; --ink-rgb:39 37 31; --line:.85;
  /* Giants orange. A fill under black type (4.9:1); as type it is the deeper
     --accent-text (4.7:1 on the ground). */
  --accent:#FD5A1E; --accent-hi:#FF7140; --accent-dim:#F9B898; --accent-text:#B93F0F;
  --accent-rgb:253 90 30; --accent-wash:rgb(253 90 30 / .13); --on-accent:#27251F;
  /* A panel laid over the screen, the screen's glow, and shadows. */
  --overlay-rgb:251 247 238; --glow-rgb:174 143 111; --shadow:.3; --blend:multiply;
  /* The windows drawn on the board. */
  --win:#FFFDF8; --win-bar:#EDE3D0; --win-ink:#27251F; --win-ink-rgb:39 37 31; --url:#F1E8D6;
  --err:#B3261E;
  /* The orange as type on the drawn screen (--screen), where --accent-text is 3.9:1. */
  --accent-on-screen:#A3370C;
  /* The demo's menu bar dims File, Edit, View and the clock; cream needs less dimming.
     Both stay at 4.5:1 or better (contrastcheck, 2026-10-14). */
  --soft:1; --soft-2:1;

  /* Hairlines are the ink at low alpha, never a grey. */
  --hair:rgb(var(--ink-rgb) / calc(.13 * var(--line)));
  --hair-2:rgb(var(--ink-rgb) / calc(.26 * var(--line)));
  --hair-3:rgb(var(--ink-rgb) / calc(.42 * var(--line)));

  --display:Archivo,"Helvetica Neue",sans-serif;
  --body:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  --wrap:76rem; --measure:60ch; --gutter:clamp(1.15rem,3vw,2.2rem);
  --cta-w:11.75rem;

  /* Two eases. The snap belongs to one gesture: a window arriving. */
  --ease-settle:cubic-bezier(.22,1,.36,1);
  --ease-snap:cubic-bezier(.62,0,.15,1);
}
/* 1B, at night. Giants black. Ratios on the ground: ink 13.2, 9.4, 6.1; the
   orange itself reads as type at 5.7:1. */
@media (prefers-color-scheme:dark){
  :root{
    --ground:#221F1B; --sheet:#2B2823; --raised:#36322B; --screen:#181613;
    --ink:#F4ECDD; --ink-2:#CFC3AC; --ink-3:#A99C84; --ink-rgb:244 236 221; --line:1;
    --accent:#FD5A1E; --accent-hi:#FF7A45; --accent-dim:#A63C14; --accent-text:#FD6A33;
    --accent-rgb:253 90 30; --accent-wash:rgb(253 90 30 / .14); --on-accent:#1B1915;
    --overlay-rgb:24 22 19; --glow-rgb:174 143 111; --shadow:1; --blend:screen;
    --win:#F1E8D8; --win-bar:#DCCFB7; --win-ink:#27251F; --win-ink-rgb:39 37 31; --url:#E5D9C3;
    --err:#FFB3A6; --soft:.76; --soft-2:.8; --accent-on-screen:#FD6A33;
  }
}

*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0;background:var(--ground);color:var(--ink);
  font:400 clamp(16px,.28vw + 15px,17.5px)/1.6 var(--body);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  /* The board's own grid: a fine 28px rule with a heavier one every fifth line. */
  background-image:
    linear-gradient(rgb(var(--ink-rgb) / calc(.11 * var(--line))) 1px,transparent 1px),
    linear-gradient(90deg,rgb(var(--ink-rgb) / calc(.11 * var(--line))) 1px,transparent 1px),
    linear-gradient(rgb(var(--ink-rgb) / calc(.045 * var(--line))) 1px,transparent 1px),
    linear-gradient(90deg,rgb(var(--ink-rgb) / calc(.045 * var(--line))) 1px,transparent 1px);
  background-size:140px 140px,140px 140px,28px 28px,28px 28px;
}
/* Paper tooth. Fixed, decorative, never in the way. */
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.5;mix-blend-mode:var(--blend);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.06'/%3E%3C/svg%3E");
}
body{min-height:100vh;display:flex;flex-direction:column}
.mast,.titleblock{width:100%}
body>*{position:relative;z-index:1}
main{flex:1 0 auto;width:100%}
.titleblock{flex:none}

img,svg{max-width:100%}
a{color:inherit}
p{margin:0 0 1rem;text-wrap:pretty}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}
::selection{background:var(--accent);color:var(--on-accent)}
::-webkit-scrollbar{width:12px;height:12px}
::-webkit-scrollbar-track{background:var(--screen)}
::-webkit-scrollbar-thumb{background:var(--raised);border:3px solid var(--screen);border-radius:8px}
::-webkit-scrollbar-thumb:hover{background:var(--ink-3)}

h1,h2,h3{margin:0;font-family:var(--display);text-wrap:balance}
h1{font-variation-settings:"wdth" 80,"wght" 760;font-weight:760;
  font-size:clamp(2.9rem,7.4vw,5.1rem);line-height:.93;letter-spacing:-.018em}
h2{font-variation-settings:"wdth" 82,"wght" 730;font-weight:730;
  font-size:clamp(1.85rem,3.6vw,2.9rem);line-height:1;letter-spacing:-.014em}
h3{font-variation-settings:"wdth" 88,"wght" 680;font-weight:680;
  font-size:clamp(1.02rem,.3vw + .95rem,1.14rem);line-height:1.2;letter-spacing:-.004em}
h1 em{font-style:normal;color:var(--accent-text)}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--gutter)}
.muted{color:var(--ink-2)}
/* Six tab stops sit between the top of the page and the first action: the
   wordmark and the masthead nav. This gets past all of them in one press. */
.skip{position:absolute;left:0;top:-4rem;z-index:60;
  background:var(--accent);color:var(--on-accent);font:600 14px/1 var(--body);
  padding:.7rem 1rem;border-radius:0 0 7px 0;text-decoration:none;
  transition:top .2s var(--ease-settle)}
.skip:focus{top:0}
main:focus{outline:0}
@media (prefers-reduced-motion:reduce){.skip{transition:none}}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.tel{white-space:nowrap}
/* A phrase that breaks only at its edges: the wrap rule (bin/wrapcheck) wants every line to end
   where somebody chose, a sentence or a clause, never mid-phrase. */
.nw{white-space:nowrap}

/* A label in the mono, with a rule before it. The rule is an inline-block
   pseudo, never a flex child, or the label wraps into ragged columns on a
   phone. */
.kick{font:600 clamp(10.5px,.24vw + 9.8px,12px)/1.5 var(--mono);
  letter-spacing:.24em;text-transform:uppercase;color:var(--accent-text);margin:0 0 1.15rem}
.kick::before{content:"";display:inline-block;width:2.2rem;height:1px;background:var(--accent);
  vertical-align:.28em;margin-right:.7rem}

/* A deliberate break between two sentences, so a line never ends mid-thought
   while a sentence boundary was sitting a few words away. It is a block down
   to phone width and inline below it, where the measure is short enough that
   forcing the break would strand a two-word line. The leading space inside the
   span is what the inline form needs and what the block form collapses. */
.brk{display:block}
@media (max-width:560px){.brk{display:inline}}
/* The inverse, for a line that fits at 1440 and cannot at 390: inline while
   there is room, a block once there is not, so the break lands on the
   sentence rather than wherever the width ran out. */
.brk-sm{display:inline}
@media (max-width:560px){.brk-sm{display:block}}

/* Lists get the same last-line care paragraphs already have, so no bullet
   ends on one orphaned word. */
li{text-wrap:pretty}

/* Key caps. Every shortcut on this site is drawn as the keys you press. */
/* The text face, not the mono: a mono face draws ⌘ ⌥ ⌃ ⇧ at two thirds of a letter
   (utility checklist C42). */
kbd{display:inline-block;font:500 .86em/1 var(--body);color:var(--ink);
  background:linear-gradient(var(--raised),var(--sheet));
  border:1px solid var(--hair-2);border-bottom:2px solid var(--hair-3);
  border-radius:5px;padding:.3em .42em .24em;min-width:1.95em;text-align:center;vertical-align:middle}
kbd+kbd{margin-left:.2em}
.keys{white-space:nowrap}

/* ── Masthead ─────────────────────────────────────────────────────────── */
.mast{position:sticky;top:0;z-index:40;
  background:color-mix(in srgb,var(--ground) 88%,transparent);
  backdrop-filter:saturate(1.3) blur(12px);-webkit-backdrop-filter:saturate(1.3) blur(12px);
  border-bottom:1px solid var(--hair)}
.mast .wrap{display:flex;align-items:center;gap:1rem;height:66px}
/* The Apple trademark rule: the two halves of "Sizemac" are never styled
   differently. One color, one weight, one face. */
.brand{display:flex;align-items:center;gap:.58rem;text-decoration:none;
  font-family:var(--display);font-variation-settings:"wdth" 88,"wght" 720;font-weight:720;
  font-size:1.13rem;letter-spacing:-.008em;color:var(--ink)}
.brand svg{width:27px;height:27px;display:block;flex:none}
/* The mark's black field all but vanishes on the night board (1.07:1), so it gets a
   quiet chalk edge there. */
@media (prefers-color-scheme:dark){.brand svg{border-radius:22%;box-shadow:0 0 0 1px rgb(var(--ink-rgb) / .3)}}
.mast nav{margin-left:auto;display:flex;align-items:center;gap:clamp(.9rem,1.6vw,1.6rem);
  font-size:14.5px}
.mast nav a{color:var(--ink-2);text-decoration:none;font-weight:500;position:relative;padding:.2rem 0}
.mast nav a:not(.btn)::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:var(--accent);transform:scaleX(0);transform-origin:right;transition:transform .35s var(--ease-settle)}
.mast nav a:not(.btn):hover{color:var(--ink)}
.mast nav a.btn{color:var(--on-accent);font-weight:600;padding:.55rem .95rem}
/* The section you are reading, held lit in the nav: the underline stays
   drawn and the label goes to full ink. site.js sets aria-current. */
.mast nav a[aria-current]:not(.btn){color:var(--ink)}
.mast nav a[aria-current]:not(.btn)::after{transform:scaleX(1)}
.mast nav a:not(.btn):hover::after{transform:scaleX(1);transform-origin:left}
@media (prefers-reduced-motion:reduce){.mast nav a::after{transition:none}}
@media (max-width:720px){.mast nav a:not(.btn){display:none}.mast .wrap{height:58px}}
/* Reading progress, drawn on the masthead's own bottom edge. */
.progress{position:absolute;left:0;bottom:-1px;height:2px;width:0;background:var(--accent);
  box-shadow:0 0 8px rgb(var(--accent-rgb) / .45)}

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  font:600 15px/1 var(--body);padding:.78rem 1.2rem;border-radius:7px;text-decoration:none;
  border:1px solid transparent;white-space:nowrap;background:var(--accent);color:var(--on-accent);
  cursor:pointer;transition:background .18s var(--ease-settle),transform .16s var(--ease-settle)}
.btn:hover{background:var(--accent-hi);transform:translateY(-1px)}
.btn.ghost{background:transparent;color:var(--ink);border-color:var(--hair-2)}
.btn.ghost:hover{background:var(--sheet);border-color:var(--ink-3);transform:translateY(-1px)}
@media (prefers-reduced-motion:reduce){.btn,.btn:hover{transition:none;transform:none}}

/* ── Sheets and section grammar ───────────────────────────────────────── */
section{padding:clamp(2.6rem,4.8vw,4.3rem) 0;position:relative}
#placements,#details{padding-top:clamp(3rem,5.6vw,5rem)}
#layouts,#snapback{padding:clamp(2.2rem,3.6vw,3.2rem) 0}
#early{padding-top:clamp(2.2rem,3.6vw,3.2rem)}
section+section{border-top:1px solid var(--hair)}
.hero{padding-top:clamp(2.4rem,4.4vw,4rem);border-top:0}

.sec-head{display:grid;gap:.75rem;max-width:var(--measure);margin-bottom:clamp(1.8rem,3vw,2.8rem)}
.sec-head p:not(.kick){color:var(--ink-2);font-size:clamp(1rem,.3vw + .95rem,1.12rem);margin:0}
/* ⚠ Every paragraph rule inside a section head excludes .kick. Without it, a
   descendant `p` rule outranks `.kick` and the label takes the body's size
   and grey: it shipped that way, three kickers at 18px and all six grey.
   Here the grid gap carries most of the space, so the two add to 1.15rem. */
.sec-head .kick{margin-bottom:.4rem}
/* ⚠ No section numbers: none on a kicker, no numbered rail in the gutter. A heading carries its section by itself. Derick, 2026-10-01: "They
   don't buy us anything." sitecheck FAILs one. */

/* Corner registration ticks, one pseudo-element, four corners. Used on the
   two blocks that are literally drawings: the board and the price. */
.corners{position:relative}
.corners::after{content:"";position:absolute;inset:-1px;pointer-events:none;
  background:
    linear-gradient(var(--accent),var(--accent)) 0 0/15px 1px no-repeat,
    linear-gradient(var(--accent),var(--accent)) 0 0/1px 15px no-repeat,
    linear-gradient(var(--accent),var(--accent)) 100% 0/15px 1px no-repeat,
    linear-gradient(var(--accent),var(--accent)) 100% 0/1px 15px no-repeat,
    linear-gradient(var(--accent),var(--accent)) 0 100%/15px 1px no-repeat,
    linear-gradient(var(--accent),var(--accent)) 0 100%/1px 15px no-repeat,
    linear-gradient(var(--accent),var(--accent)) 100% 100%/15px 1px no-repeat,
    linear-gradient(var(--accent),var(--accent)) 100% 100%/1px 15px no-repeat}

/* ── Hero ─────────────────────────────────────────────────────────────── */
.hero-grid{display:grid;gap:clamp(1.8rem,3.4vw,3rem);
  grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);align-items:center}
@media (max-width:1040px){.hero-grid{grid-template-columns:1fr;gap:2rem}}
.hero h1 .l2{display:block;padding-left:clamp(0px,2.6vw,2.4rem)}
.hero .lede{font-size:clamp(1.06rem,.5vw + .95rem,1.22rem);color:var(--ink-2);
  max-width:34rem;margin:1.3rem 0 0}
.hero .cta{display:flex;gap:.65rem;flex-wrap:wrap;align-items:center;margin:1.8rem 0 1rem}
/* A pair of calls to action side by side is one width, the longer label's. */
@media (min-width:541px){.hero .cta .btn,.price .price-cta .btn{min-width:var(--cta-w)}}
.hero .fine{font:400 13.5px/1.55 var(--mono);color:var(--ink-3);margin:0;max-width:30rem}
@media (max-width:540px){.hero .cta{display:grid;grid-template-columns:1fr;gap:.55rem}
  .hero .cta .btn{width:100%}}

/* The drawing board: the hero demo. */
.board{background:var(--sheet);border:1px solid var(--hair-2);padding:clamp(.75rem,1.2vw,1.05rem);
  outline:0}
.board .plate{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;
  font:500 10.5px/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;color:var(--ink-3);
  padding:0 .15rem .65rem;border-bottom:1px solid var(--hair);margin-bottom:.75rem}
.board .plate .live{display:inline-flex;align-items:center;gap:.4rem;color:var(--accent-text)}
.tremor{flex:1 1 60px;min-width:60px;max-width:190px;height:14px;margin-left:auto;color:var(--accent-text);
  display:block;opacity:.85}
.tremor polyline{fill:none;stroke:currentColor;stroke-width:1.25;stroke-linejoin:round;
  stroke-linecap:round;vector-effect:non-scaling-stroke}
@media (max-width:560px){.tremor{display:none}}
.board .plate .live::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 0 rgb(var(--accent-rgb) / .6);animation:pulse 2.4s infinite}
@keyframes pulse{70%{box-shadow:0 0 0 7px rgb(var(--accent-rgb) / 0)}100%{box-shadow:0 0 0 0 rgb(var(--accent-rgb) / 0)}}
@media (prefers-reduced-motion:reduce){.board .plate .live::before{animation:none}}

.screen{position:relative;aspect-ratio:16/10;background:var(--screen);overflow:hidden;
  border:1px solid rgb(var(--ink-rgb) / calc(.14 * var(--line)));border-radius:4px}
.screen .menubar{position:absolute;top:0;left:0;right:0;height:7.4%;display:flex;align-items:center;
  gap:3.4%;padding:0 2.6%;background:rgb(var(--ink-rgb) / calc(.07 * var(--line)));border-bottom:1px solid rgb(var(--ink-rgb) / calc(.09 * var(--line)));
  font:500 clamp(7.5px,1.15vw,11px)/1 var(--body);color:rgb(var(--ink-rgb) / .97)}
.screen .menubar svg{height:62%;width:auto;flex:none}
.screen .menubar>*{flex:none}
.screen .menubar .soft{opacity:var(--soft)}
.screen .menubar svg{aspect-ratio:1}
.screen .menubar .clock{margin-left:auto;font-family:var(--mono);opacity:var(--soft-2)}
/* The desk sits inside the display with a drawing's margins, so the dimension
   callouts have a gutter to live in instead of lying across the window. */
.desk{position:absolute;inset:12% 6.5% 12.5% 7.5%;
  outline:1px solid rgb(var(--ink-rgb) / calc(.1 * var(--line)));
  background-image:
    linear-gradient(rgb(var(--ink-rgb) / calc(.07 * var(--line))) 1px,transparent 1px),
    linear-gradient(90deg,rgb(var(--ink-rgb) / calc(.07 * var(--line))) 1px,transparent 1px);
  background-size:calc(100%/6) calc(100%/6)}

.win{position:absolute;background:var(--win);border-radius:5px;overflow:hidden;
  box-shadow:0 14px 34px rgb(0 0 0 / calc(.5 * var(--shadow))),0 0 0 1px rgb(var(--overlay-rgb) / .5);
  transition:left .44s var(--ease-snap),top .44s var(--ease-snap),
             width .44s var(--ease-snap),height .44s var(--ease-snap),opacity .3s var(--ease-settle)}
.win .bar{height:15%;min-height:11px;max-height:20px;display:flex;align-items:center;gap:4px;
  padding:0 7px;background:var(--win-bar)}
.win .bar i{width:7px;height:7px;border-radius:50%;background:#df5f52;flex:none}
.win .bar i:nth-child(2){background:#dfa94e}
.win .bar i:nth-child(3){background:#54ab5c}
.win .bar b{font:500 clamp(7px,.95vw,10px)/1 var(--body);color:var(--win-ink);opacity:.8;
  margin-left:auto;margin-right:auto;padding-right:1.1rem;white-space:nowrap;overflow:hidden}
.win .body{padding:7% 6%;display:grid;gap:5.5%;align-content:start}
.win .body i{display:block;height:5px;border-radius:3px;background:rgb(var(--win-ink-rgb) / .14)}
.win .body i:nth-child(1){width:56%}.win .body i:nth-child(2){width:82%}
.win .body i:nth-child(3){width:39%}.win .body i:nth-child(4){width:71%}
.win[hidden]{display:none}
.win.extra{opacity:0}
.win.extra.on{opacity:1}
@media (prefers-reduced-motion:reduce){.win{transition:none}}

/* Dimension callouts. The orange line work that proves the fraction. */
.dim-x,.dim-y{position:absolute;pointer-events:none;color:var(--accent-on-screen);
  transition:left .44s var(--ease-snap),top .44s var(--ease-snap),
             width .44s var(--ease-snap),height .44s var(--ease-snap),opacity .25s var(--ease-settle)}
@media (prefers-reduced-motion:reduce){.dim-x,.dim-y{transition:none}}
.dim-x{bottom:-14px;height:1px;background:currentColor}
.dim-x::before,.dim-x::after{content:"";position:absolute;top:-3.5px;width:1px;height:8px;background:currentColor}
.dim-x::before{left:0}.dim-x::after{right:0}
.dim-y{left:-16px;width:1px;background:currentColor}
.dim-y::before,.dim-y::after{content:"";position:absolute;left:-3.5px;height:1px;width:8px;background:currentColor}
.dim-y::before{top:0}.dim-y::after{bottom:0}
.dim-x>span,.dim-y>span{position:absolute;font:600 clamp(12px,1.35vw,15px)/1 var(--mono);letter-spacing:0;
  font-variant-numeric:tabular-nums;font-feature-settings:"frac" 0;
  background:var(--screen);padding:3px 7px;white-space:nowrap}
.dim-x>span{left:50%;transform:translate(-50%,-50%);top:0}
.dim-y>span{top:50%;transform:translate(-100%,-50%);left:-5px}
@media (max-width:620px){.dim-y{display:none}.dim-x{bottom:-11px}}

.origin{position:absolute;pointer-events:none;color:var(--accent-on-screen);
  font:600 clamp(11px,1.15vw,13px)/1 var(--mono);letter-spacing:0;
  font-variant-numeric:tabular-nums;
  background:var(--screen);padding:2px 4px;transform:translateY(-124%);white-space:nowrap;
  transition:left .44s var(--ease-snap),top .44s var(--ease-snap),opacity .25s var(--ease-settle)}
@media (prefers-reduced-motion:reduce){.origin{transition:none}}
@media (max-width:620px){.origin{display:none}}
.prompt{position:absolute;left:50%;bottom:8%;transform:translateX(-50%);display:flex;align-items:center;
  gap:.35rem;white-space:nowrap;background:rgb(var(--overlay-rgb) / .94);color:var(--ink);
  border:1px solid var(--hair-2);border-radius:999px;padding:.45rem .55rem .45rem .85rem;
  font:500 clamp(10px,1.2vw,12.5px)/1 var(--body);box-shadow:0 8px 26px rgb(0 0 0 / calc(.5 * var(--shadow)));
  pointer-events:none;transition:opacity .3s var(--ease-settle),transform .3s var(--ease-settle)}
.prompt kbd{font-size:1em;min-width:1.7em}
.board.is-live .prompt{opacity:0;transform:translate(-50%,8px)}
.board:focus-visible .screen{outline:2px solid var(--accent);outline-offset:3px}

/* The instrument: two fixed rows, so nothing shifts while keys are being
   pressed. Row one is the placement, its size and its keys. Row two is the note. */
.instr{display:grid;grid-template-rows:1.55rem 1.15rem;align-content:center;
  margin:.85rem 0 0;padding:0 .15rem}
.instr .r1{display:flex;align-items:center;gap:.6rem;min-width:0;white-space:nowrap;overflow:hidden}
.instr .name{font:600 15px/1 var(--body);color:var(--ink);overflow:hidden;text-overflow:ellipsis}
.instr .size{font:600 clamp(13px,.4vw + 11.5px,15px)/1 var(--mono);color:var(--on-accent);
  background:var(--accent);font-variant-numeric:tabular-nums;font-feature-settings:"frac" 0;
  padding:.32em .55em .26em;border-radius:4px;flex:none;letter-spacing:0}
.instr .keys{flex:none}
/* The built fraction is wider than the glyph it replaced, and on a phone it
   was pushing the placement's name into an ellipsis. The name is the token
   that matters, so the chip and the caps give the width back. */
@media (max-width:520px){
  .instr .name{font-size:13.5px}
  .instr .size{font-size:12.5px;padding:.3em .42em .24em}
  .instr .keys kbd{font-size:11px;min-width:1.5em;padding:.26em .28em .2em}
}
.instr .note{font:400 12.5px/1.15 var(--mono);color:var(--ink-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.02em}

.chips{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.4rem;margin-top:.7rem}
@media (max-width:520px){.chips{grid-template-columns:repeat(3,minmax(0,1fr))}}
.chips button{display:flex;flex-direction:column;align-items:center;gap:.4rem;min-width:0;
  font:500 12.5px/1.15 var(--body);color:var(--ink-2);text-align:center;
  padding:.55rem .3rem .5rem;min-height:58px;cursor:pointer;
  background:transparent;border:1px solid var(--hair);border-radius:6px;
  transition:border-color .16s var(--ease-settle),background .16s var(--ease-settle),color .16s var(--ease-settle)}
.chips button:hover{border-color:var(--ink-3);color:var(--ink);background:var(--raised)}
.chips button[aria-pressed=true]{border-color:var(--accent);background:var(--accent-wash);color:var(--ink)}
.chips svg{width:34px;height:21px;display:block;flex:none}
.chips svg .frame{fill:none;stroke:currentColor;stroke-width:1;opacity:.55;vector-effect:non-scaling-stroke}
.chips svg .fill{fill:currentColor;opacity:.95}
.chips svg .dim{fill:currentColor;opacity:.32}
.chips svg .arrow{stroke:currentColor}
.chips svg .arrow-in{stroke:var(--sheet)}
.chips button[aria-pressed=true] svg{color:var(--accent-text)}
.chips button[aria-pressed=true] svg .arrow-in{stroke:var(--on-accent)}
@media (prefers-reduced-motion:reduce){.chips button{transition:none}}

.howto{font:400 13px/1.5 var(--mono);color:var(--ink-3);margin:.75rem .15rem 0;letter-spacing:.01em}
.howto kbd{font-size:.95em}

/* The fraction, drawn. Real digits in the mono, never the Unicode vulgar
   fraction glyph, which compresses the numerator to nothing at these sizes.
   The solidus steps back so "1/2" reads as one number. */
/* ⚠ Always declared, never merely defaulted: `.dim-x span` once matched this
   and absolutely positioned the solidus over the numerator. Same family of
   name collision as the `.dim` one recorded in DESIGN.md. */
.sl,.by{display:inline;position:static;opacity:.55}
.sl{padding:0 .01em}
.by{opacity:.6;letter-spacing:.02em}
.frac{font-variant-numeric:tabular-nums;font-feature-settings:"frac" 0;white-space:nowrap}

/* ── The schedule of placements ───────────────────────────────────────── */
/* Two columns of whole groups, so no group is ever split and no row is ever
   orphaned. Each group's own count decides nothing: the rows are rows. */
.schedule{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(1.4rem,3vw,3rem)}
@media (max-width:860px){.schedule{grid-template-columns:1fr;gap:1.4rem}}
.grp{min-width:0}
.grp+.grp{margin-top:1.9rem}
.grp-h{display:flex;align-items:baseline;gap:.7rem;font:600 11.5px/1 var(--mono);
  letter-spacing:.22em;text-transform:uppercase;color:var(--ink);
  padding-bottom:.55rem;border-bottom:1px solid var(--hair-2);margin:0 0 .2rem}
.grp-h b{font-weight:400;color:var(--ink-3);margin-left:auto;letter-spacing:.1em}
.rows{list-style:none;margin:0;padding:0}
.rows li{display:grid;grid-template-columns:46px minmax(0,1fr) auto;gap:.85rem;align-items:center;
  padding:.5rem .3rem;border-bottom:1px solid var(--hair);min-width:0}
.rows li:hover{background:var(--sheet)}
.rows svg{width:46px;height:29px;display:block}
.rows svg .frame{fill:rgb(var(--overlay-rgb) / .75);stroke:var(--hair-3);stroke-width:1;vector-effect:non-scaling-stroke}
.rows svg .fill{fill:var(--accent)}
.rows svg .dim{fill:var(--accent);opacity:.34}
.rows svg .arrow{stroke:var(--accent)}
.rows svg .arrow-in{stroke:var(--screen)}
.rows .name{font-size:14.5px;color:var(--ink);min-width:0;overflow-wrap:break-word}
.rows .keys{flex:none;text-align:right}
.rows .keys:empty::before{content:"not set";font:400 12px/1 var(--mono);color:var(--ink-3);
  letter-spacing:.08em;text-transform:uppercase}
.rows kbd{font-size:11.5px;min-width:1.75em;padding:.28em .34em .22em}
/* No measure: both sentences fit the page width at 1440, and the reading
   measure was forcing the first one to break after "no shortcut". */
.sched-note{font:400 13.5px/1.6 var(--mono);color:var(--ink-3);margin:1.5rem 0 0}

/* ── Two-column feature rows, alternating weight ──────────────────────── */
.row{display:grid;gap:clamp(1.6rem,3.2vw,3rem);
  grid-template-columns:minmax(0,1.04fr) minmax(0,.96fr);align-items:stretch}
.row>*{display:grid;align-content:center;min-width:0}
.row.flip{grid-template-columns:minmax(0,.96fr) minmax(0,1.04fr)}
.row.flip>.art{order:-1}
@media (max-width:860px){.row,.row.flip{grid-template-columns:1fr;gap:1.5rem}.row.flip>.art{order:0}
  /* One column means the full page width, which is far past a reading measure. */
  .row>div>p:not(.kick),.row ul{max-width:var(--measure)}}
.row h2{margin-bottom:.85rem}
.row>div>p:not(.kick){color:var(--ink-2)}
.row ul,.lhead ul{margin:0;padding:0;list-style:none;display:grid;gap:.6rem;color:var(--ink-2);font-size:15.5px}
.row li,.lhead li{padding-left:1.55rem;position:relative}
.row li::before,.lhead li::before{content:"";position:absolute;left:0;top:.58em;width:.62rem;height:.32rem;
  border-left:1.5px solid var(--accent);border-bottom:1.5px solid var(--accent);transform:rotate(-45deg)}
.art{background:var(--sheet);border:1px solid var(--hair);padding:clamp(.9rem,1.6vw,1.3rem);min-width:0}

/* ── Layouts: the claim, then the same layout on two different desks ─── */
/* The head is the claim and the four things a layout does, side by side, so
   the two boards below start at the same y and can be read against each
   other. Both boards are the same drawing with the same panes and the same
   picker: the variable being swept is what was on the desk beforehand. */
.lhead{display:grid;gap:clamp(1.3rem,3vw,3rem);
  grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr);align-items:start;
  margin-bottom:clamp(1.5rem,2.6vw,2.3rem)}
@media (max-width:860px){.lhead{grid-template-columns:1fr;gap:1.25rem}}
.lhead h2{margin-bottom:.85rem}
.lhead>div>p:not(.kick){color:var(--ink-2);max-width:var(--measure);margin:0}
.boards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(1rem,2.2vw,1.9rem);align-items:stretch}
@media (max-width:860px){.boards{grid-template-columns:1fr}}
.boards>.art{display:grid;align-content:start;min-width:0}

/* ── The layout board ────────────────────────────────────────────────── */
/* This section sells layouts, so the panel is a working one: three real windows
   with the same traffic lights, title bars and snap ease the hero draws, that
   start scattered and tile to 40 / 30 / 30 on the app's own shortcut. Content
   scales off the stage, not the viewport, because the stage is a column at
   1440 and the full width at 390. */
/* A container, so the picker answers the BOARD's width and not the window's.
   The two boards are a pair and they have to wrap at the same moment: at 1080
   the warm picker fit one row and the cold one needed two, purely because
   "Clear the Desk" is wider than "Snap Back", and the pair fell 41px out of
   step. */
.lboard{display:grid;gap:0;container-type:inline-size}
.lboard .plate{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;
  font:500 10.5px/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;color:var(--ink-3);
  padding:0 .1rem .6rem;border-bottom:1px solid var(--hair);margin:0 0 .7rem}
.lstage{container-type:inline-size;position:relative;aspect-ratio:16/10;background:var(--screen);
  border-radius:4px;border:1px solid rgb(var(--ink-rgb) / calc(.12 * var(--line)));overflow:hidden}
.lmenubar{position:absolute;top:0;left:0;right:0;height:7.4%;display:flex;align-items:center;
  gap:3.4%;padding:0 2.6%;background:rgb(var(--ink-rgb) / calc(.07 * var(--line)));
  border-bottom:1px solid rgb(var(--ink-rgb) / calc(.09 * var(--line)));
  font:500 clamp(7px,2cqi,11px)/1 var(--body);color:rgb(var(--ink-rgb) / calc(.82 * var(--line)))}
.lmenubar>*{flex:none}
.lmenubar svg{height:62%;width:auto;aspect-ratio:1}
.lmenubar .soft{opacity:var(--soft)}
.lmenubar .clock{margin-left:auto;font-family:var(--mono);opacity:var(--soft-2)}
/* The desk, with a drawing's margins so the dimension strip has a gutter, and
   the Dock's strip left out at the foot the way the visible frame leaves it
   out on a real Mac. Both boards use the same inset, so the panes drawn from
   the same fractions come out the same size on both. */
.ldesk{position:absolute;inset:12% 4.5% 19.5% 4.5%;
  background-image:
    radial-gradient(125% 95% at 50% -14%,rgb(var(--glow-rgb) / .17),rgb(var(--glow-rgb) / 0) 64%),
    linear-gradient(rgb(var(--ink-rgb) / calc(.07 * var(--line))) 1px,transparent 1px),
    linear-gradient(90deg,rgb(var(--ink-rgb) / calc(.07 * var(--line))) 1px,transparent 1px);
  background-size:100% 100%,calc(100%/6) calc(100%/6),calc(100%/6) calc(100%/6);
  outline:1px solid rgb(var(--ink-rgb) / calc(.1 * var(--line)))}

/* The edges of the applied layout, drawn on the desk. These are the shared
   edges the second bullet says you can drag, and there are as many of them as
   the layout has gutters: two for Dev Desk, one for Laptop. */
.ledges{position:absolute;inset:0;pointer-events:none}
.ledges i{position:absolute;top:0;bottom:0;left:var(--at);width:1px;background:var(--accent);
  color:var(--accent-text);opacity:0;transform:scaleY(.2);transform-origin:top;
  transition:opacity .35s var(--ease-settle) .34s,transform .45s var(--ease-settle) .34s}
.ledges i::before,.ledges i::after{content:"";position:absolute;left:-3.5px;width:8px;height:1px;
  background:currentColor}
.ledges i::before{top:0}.ledges i::after{bottom:0}
.lboard.is-tiled .ledges i{opacity:.75;transform:none}
@media (prefers-reduced-motion:reduce){.ledges i{transition:none}}
/* The plan, drawn before it is applied. Point at a saved layout and its panes
   are chalked onto the desk with the app each one is bound to, which is the
   thing a layout actually stores and the thing a picture of three rectangles
   could never say. It is drawn only for a layout that is NOT the applied one,
   so it is always a proposal rather than a label. */
.lplan{position:absolute;inset:0;pointer-events:none;z-index:6;opacity:0;
  transition:opacity .22s var(--ease-settle)}
.lplan.on{opacity:1}
/* A scrim, so the plan reads over a desk that is already full of white
   windows and not only over an empty one. */
.lplan::before{content:"";position:absolute;inset:0;background:rgb(var(--overlay-rgb) / .58)}
@media (prefers-reduced-motion:reduce){.lplan{transition:none}}
.lplan i{position:absolute;z-index:1;left:var(--x);top:var(--y);width:var(--w);height:var(--h);
  border:1px dashed var(--accent);border-radius:4px;background:rgb(var(--accent-rgb) / .07);
  display:grid;place-items:center}
.lplan b{font:600 clamp(6.5px,2.1cqi,11px)/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent-text);background:rgb(var(--overlay-rgb) / .86);
  padding:.35em .5em .3em;border-radius:3px;max-width:92%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

.lwin{position:absolute;background:var(--win);border-radius:4px;overflow:hidden;display:flex;
  flex-direction:column;
  box-shadow:0 12px 30px rgb(0 0 0 / calc(.5 * var(--shadow))),0 0 0 1px rgb(var(--overlay-rgb) / .5);
  left:var(--x);top:var(--y);width:var(--w);height:var(--h);z-index:var(--z,1)}
/* Closed: not on the desk at all. A window coming back from this state opens
   INTO its pane rather than travelling to it, which is what launching looks
   like, and the same rule tucks a window away when a layout has no pane for
   it. */
.lwin.gone{opacity:0;transform:scale(.92)}
/* ⚠ One transition declaration, delay last. A second `transition` shorthand
   anywhere below this resets transition-delay to zero, which is how the
   staggered launch came out as three windows appearing at once. */
.lwin{transform-origin:50% 62%;
  transition:left .52s var(--ease-snap),top .52s var(--ease-snap),
             width .52s var(--ease-snap),height .52s var(--ease-snap),
             transform .42s var(--ease-snap),opacity .34s var(--ease-settle);
  transition-delay:var(--lag,0ms)}
/* The content arrives just behind the window, so a window that opens reads as
   an app drawing itself rather than as a rectangle that was always there. */
.lwin>:not(.bar){transition:opacity .3s var(--ease-settle);
  transition-delay:calc(var(--lag,0ms) + 210ms)}
.lwin.gone>:not(.bar){opacity:0;transition-delay:0ms}
/* Transitions off for one frame, so a window that is opening lands in its
   pane rather than sliding there from the last layout's geometry. */
.lwin.nomove,.lwin.nomove>*{transition:none}
@media (prefers-reduced-motion:reduce){.lwin,.lwin>:not(.bar){transition:none}}
/* The traffic lights, drawn the way the hero's window draws them. */
.lwin .bar{flex:none;height:clamp(11px,4.4cqi,22px);display:flex;align-items:center;
  gap:clamp(2px,.9cqi,4px);padding:0 clamp(3px,1.5cqi,8px);background:var(--win-bar)}
.lwin .bar i{width:clamp(4px,1.6cqi,7px);aspect-ratio:1;border-radius:50%;background:#df5f52;flex:none}
.lwin .bar i:nth-child(2){background:#dfa94e}
.lwin .bar i:nth-child(3){background:#54ab5c}
.lwin .bar b{font:500 clamp(6.5px,1.9cqi,10px)/1 var(--body);color:var(--win-ink);opacity:.8;
  margin:0 auto;padding-right:clamp(10px,4cqi,20px);white-space:nowrap;overflow:hidden}

/* Safari: an address bar and a page under it. */
.lurl{flex:none;padding:clamp(2px,1cqi,5px) clamp(3px,1.6cqi,8px);background:var(--url)}
.lurl span{display:block;background:var(--win);border-radius:99px;color:rgb(var(--win-ink-rgb) / .78);
  font:500 clamp(5.5px,1.7cqi,9.5px)/1.9 var(--mono);text-align:center;padding:0 .5em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lpage{flex:1 1 auto;padding:clamp(4px,2.4cqi,12px) clamp(4px,2.2cqi,11px);display:grid;
  gap:clamp(3px,1.6cqi,8px);align-content:start}
.lpage s{display:block;height:clamp(2.5px,.9cqi,5px);border-radius:3px;width:var(--w);
  background:rgb(var(--win-ink-rgb) / .15)}
.lpage s.hd{height:clamp(4px,1.5cqi,8px);background:rgb(var(--win-ink-rgb) / .28);margin-bottom:clamp(2px,.9cqi,5px)}

/* Xcode: a numbered gutter and code-shaped colour. */
.lcode{flex:1 1 auto;counter-reset:ln;padding:clamp(3px,1.6cqi,8px) 0 0;overflow:hidden;
  font:500 clamp(5px,1.5cqi,8.5px)/1 var(--mono)}
.lcode .cl{display:flex;align-items:center;gap:clamp(2px,.9cqi,5px);
  padding:clamp(1.6px,.75cqi,4px) clamp(3px,1.4cqi,7px) clamp(1.6px,.75cqi,4px) 0}
.lcode .cl::before{counter-increment:ln;content:counter(ln);flex:none;
  width:clamp(8px,3.4cqi,18px);text-align:right;color:rgb(var(--win-ink-rgb) / .32);
  margin-right:calc(var(--i,0) * clamp(4px,2cqi,11px))}
.lcode s{display:block;height:clamp(2.5px,.9cqi,5px);border-radius:3px;width:var(--w);
  background:rgb(var(--win-ink-rgb) / .34);flex:none}
.lcode s.k{background:#8E4C88}
.lcode s.q{background:#A8543F}
.lcode .cl:empty{height:clamp(6px,2.4cqi,13px)}

/* Terminal: a prompt and two commands, on the board's own screen colour. */
/* ⚠ Bottom anchored, the way a shell is: the prompt sits at the foot of the
   pane and older lines run off the top. A terminal whose content stopped
   two thirds of the way up read as a window nobody had finished drawing, and
   at 768 that is most of the pane. */
.lterm{flex:1 1 auto;background:var(--screen);padding:clamp(3px,1.8cqi,9px) clamp(4px,2cqi,10px);
  font:400 clamp(5.5px,1.75cqi,9.5px)/1.55 var(--mono);color:var(--ink-2);overflow:hidden;
  display:flex;flex-direction:column;justify-content:flex-end}
.lterm p{margin:0 0 .25em;overflow-wrap:break-word}
.lterm b{color:var(--accent-on-screen);font-weight:500}
.lterm .out{color:var(--ink-2)}
.lterm i{display:inline-block;width:.55em;height:1em;background:var(--ink-2);
  vertical-align:-.14em;opacity:.8}

/* The invitation, drawn the way the hero draws its own: an empty desk has the
   room for it, and a board nobody knows they can press is a picture. It goes
   the moment a layout lands, and stays gone once the reader has touched the
   board. */
.lprompt{position:absolute;left:50%;top:46%;transform:translate(-50%,-50%);
  display:flex;align-items:center;gap:.35rem;white-space:nowrap;margin:0;
  background:rgb(var(--overlay-rgb) / .94);color:var(--ink);border:1px solid var(--hair-2);
  border-radius:999px;padding:.45rem .55rem .45rem .85rem;
  font:500 clamp(9.5px,2.5cqi,12.5px)/1 var(--body);box-shadow:0 8px 26px rgb(0 0 0 / calc(.5 * var(--shadow)));
  pointer-events:none;opacity:0;z-index:7;
  transition:opacity .3s var(--ease-settle),transform .3s var(--ease-settle)}
.lprompt kbd{font-size:.92em;min-width:1.7em}
.lboard.cold:not(.is-tiled):not(.is-live):not(.is-planning) .lprompt{opacity:1}
@media (prefers-reduced-motion:reduce){.lprompt{transition:none}}

/* ── The Dock ──────────────────────────────────────────────────────────
   Both boards carry it, and that is what makes the pair legible at a glance:
   the same three apps, lit on the left desk and dark on the right one. A dot
   under a tile means the app is running, the way it does on a real Mac. The
   tiles are generic marks for a browser, an editor and a shell, never anybody
   else's icon artwork. */
.dock{position:absolute;left:50%;bottom:2.6%;transform:translateX(-50%);
  display:flex;align-items:flex-end;gap:clamp(4px,1.9cqi,11px);
  padding:clamp(3px,1.3cqi,7px) clamp(4px,1.7cqi,10px) clamp(5px,2cqi,11px);
  background:rgb(var(--ink-rgb) / calc(.09 * var(--line)));border:1px solid rgb(var(--ink-rgb) / calc(.13 * var(--line)));
  border-radius:clamp(6px,2.2cqi,12px);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
.dtile{position:relative;width:clamp(15px,6.2cqi,34px);aspect-ratio:1;flex:none;
  border-radius:23%;background:var(--tint);display:grid;place-items:center;
  box-shadow:0 2px 6px rgb(0 0 0 / calc(.4 * var(--shadow)));
  transition:filter .35s var(--ease-settle) var(--dot-lag,0ms)}
.dtile svg{width:66%;height:66%;display:block}
/* Not running: the tile is asleep. A 3px dot alone is not readable at 390. */
.dtile[data-on=false]{filter:grayscale(.68) brightness(.62)}
.dtile::after{content:"";position:absolute;left:50%;bottom:clamp(-7px,-2.4cqi,-4px);
  transform:translateX(-50%);width:clamp(2.5px,1cqi,4.5px);aspect-ratio:1;border-radius:50%;
  background:var(--ink);opacity:0;
  transition:opacity .3s var(--ease-settle) var(--dot-lag,0ms)}
.dtile[data-on=true]::after{opacity:.82}
/* Point at a layout and the Dock answers with the apps that layout binds, so
   the plan on the desk and the apps it will open are one statement. */
.dtile[data-plan=in]{filter:none;box-shadow:0 0 0 1.5px var(--accent),0 2px 6px rgb(0 0 0 / calc(.4 * var(--shadow)))}
.dtile[data-plan=out]{filter:grayscale(.85) brightness(.5)}
/* One bounce, the moment the layout opens that app. Only a tile going from
   closed to running ever gets it. */
@keyframes dockbounce{
  0%{transform:translateY(0)} 28%{transform:translateY(-42%)}
  52%{transform:translateY(0)} 70%{transform:translateY(-15%)}
  100%{transform:translateY(0)}}
.dtile.pop{animation:dockbounce .62s var(--ease-settle) var(--pop-lag,0ms) 1}
@media (prefers-reduced-motion:reduce){
  .dtile.pop{animation:none}
  .dtile,.dtile::after{transition:none}}

/* The dimension strip. It reads 40 / 30 / 30, so it is dim until that is true. */
.layout-dims{display:grid;grid-template-columns:40fr 30fr 30fr;gap:3%;margin:.7rem 4.5% 0;
  color:var(--accent-text);opacity:.26;transition:opacity .4s var(--ease-settle) .22s}
.layout-dims.on{opacity:1}
@media (prefers-reduced-motion:reduce){.layout-dims{transition:none}}
.layout-dims>span{position:relative;display:block;height:1px;background:currentColor;
  font:600 11.5px/1 var(--mono);letter-spacing:.06em;text-align:center}
.layout-dims>span::before,.layout-dims>span::after{content:"";position:absolute;top:-3.5px;
  width:1px;height:8px;background:currentColor}
.layout-dims>span::before{left:0}.layout-dims>span::after{right:0}
.layout-dims b{position:relative;top:-.55em;display:inline-block;background:var(--sheet);
  padding:0 5px;font-weight:600}

/* The saved layouts, as a picker. Two of them, because one layout does not
   teach what a layout is, and Snap Back set apart because it applies none. */
.lpicker{display:flex;gap:.45rem;flex-wrap:wrap;margin:1rem 0 0}
.lbtn{display:inline-flex;align-items:center;gap:.55rem;cursor:pointer;
  font:600 13.5px/1 var(--body);color:var(--ink);background:var(--raised);
  border:1px solid var(--hair-2);border-radius:7px;padding:.58rem .75rem;white-space:nowrap;
  transition:border-color .18s var(--ease-settle),background .18s var(--ease-settle)}
.lbtn:hover{border-color:var(--accent);background:var(--sheet)}
.lbtn[data-on=true]{border-color:var(--accent);background:var(--accent-wash)}
/* Snap Back carries no keycaps here: all three shortcuts share the same ⌃⌥⌘
   prefix, three sets of four caps will not fit the column at 1440, and the
   Snap Back section below draws this one in full. The two layouts keep theirs, because "a
   whole desk in one key" is the claim being made. */
/* Both boards' third button reserves the same width, so the two pickers are
   the same shape whatever they are called. */
.lbtn.ghosty{background:transparent;color:var(--ink-2);margin-left:auto;
  min-width:8.4rem;justify-content:center}
.lbtn.ghosty:hover{color:var(--ink);background:var(--sheet)}
.lbtn kbd{font-size:11.5px;min-width:1.75em;padding:.28em .34em .22em}
@container (max-width:500px){.lbtn .keys{display:none}}
@container (max-width:310px){.lbtn.ghosty{margin-left:0;min-width:0}}
@media (prefers-reduced-motion:reduce){.lbtn{transition:none}}
/* Which of the two cases this board is. It reads under the drawing, the way a
   caption does, and it is the one line on the board that never changes. */
/* ⚠ It names the STARTING POINT, not what is on the desk this second. Without
   that word the right-hand board reads "Nothing open at all" over three open
   windows the moment anybody presses a button. */
.lcap{display:flex;align-items:baseline;gap:.6rem;margin:.95rem 0 0;
  font:600 13.5px/1.4 var(--body);color:var(--ink);flex-wrap:wrap}
.lcap span{font:500 10.5px/1.5 var(--mono);letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-3)}
.lcap span::before{content:"";display:inline-block;width:1.4rem;height:1px;
  background:var(--accent);vertical-align:.25em;margin-right:.6rem}
/* Two lines of room whatever it says, so applying a layout on one board never
   changes its height and the pair never falls out of step. */
.lnote{display:block;font:400 13px/1.45 var(--mono);color:var(--ink-3);letter-spacing:.01em;
  margin:.85rem 0 0;text-wrap:pretty;min-height:2.9em}
.lnote .brk-sm{display:block}

/* The pair, measured. A dimension line under both boards, drawn the way every
   other span on this page is drawn, because the claim the section makes is
   that one key covers both desks. */
.pairnote{display:block;margin:clamp(1rem,1.8vw,1.5rem) 0 0;height:1px;
  background:var(--accent);color:var(--accent-text);position:relative;text-align:center}
.pairnote::before,.pairnote::after{content:"";position:absolute;top:-4px;
  width:1px;height:9px;background:currentColor}
.pairnote::before{left:0}.pairnote::after{right:0}
.pairnote span{position:relative;top:-.72em;display:inline-flex;align-items:center;gap:.55rem;
  background:var(--ground);padding:0 .8rem;
  font:600 11.5px/1 var(--mono);letter-spacing:.18em;text-transform:uppercase}
.pairnote kbd{font-size:10.5px;letter-spacing:0;min-width:1.7em;padding:.26em .3em .2em}
/* Stacked, the pair is not side by side and the caps wrapped one cap onto a
   second line with the rule running behind it. The label carries it alone;
   the keys are drawn on both pickers a few inches above. */
@media (max-width:860px){.pairnote kbd{display:none}.pairnote span{gap:0}}
@media (max-width:420px){.pairnote span{letter-spacing:.12em;padding:0 .55rem;font-size:11px}}

/* The Tremor Log, as it actually reads. */
.log{display:grid;gap:0}
.log .day{font:600 11px/1 var(--mono);letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-3);margin:.15rem 0 .6rem}
.log .line{display:grid;grid-template-columns:4.4rem minmax(0,1fr) auto;gap:.8rem;align-items:baseline;
  padding:.46rem 0;border-top:1px solid var(--hair);min-width:0}
.log .line:first-of-type{border-top:0}
/* A line the reader's own move just wrote. */
.log .line{transition:opacity .4s var(--ease-settle),transform .4s var(--ease-settle)}
.log .line.is-new{opacity:0;transform:translateY(-6px)}
@media (prefers-reduced-motion:reduce){.log .line{transition:none}.log .line.is-new{opacity:1;transform:none}}
.log time{font:400 12.5px/1.3 var(--mono);color:var(--ink-3);white-space:nowrap}
.log .what{font-size:14.5px;color:var(--ink-2);min-width:0}
.log .what b{color:var(--ink);font-weight:600}
.log .where{font:400 12px/1.3 var(--mono);color:var(--ink-3);white-space:nowrap}
@media (max-width:420px){.log .where{display:none}}
.log-note{font:400 12.5px/1.55 var(--mono);color:var(--ink-3);margin:.9rem 0 0}

/* ── Six details: 3+3, then 2+2+2, then one per row. Never 4+2. ───────── */
.details{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;list-style:none;
  margin:0;padding:0;background:var(--hair);border:1px solid var(--hair)}
@media (max-width:900px){.details{grid-template-columns:1fr}}
@media (max-width:560px){.details{grid-template-columns:1fr}}
.details li{padding:1.25rem 1.3rem;background:var(--ground);min-width:0}
.details h3{margin-bottom:.45rem}
.details p{margin:0;color:var(--ink-2);font-size:15px}
.details .n{display:block;font:500 11px/1 var(--mono);letter-spacing:.2em;color:var(--accent-text);margin-bottom:.7rem}

/* ── Pricing: one price, said once ────────────────────────────────────── */
.price{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);align-items:stretch;
  background:var(--sheet);border:1px solid var(--hair-2)}
@media (max-width:760px){.price{grid-template-columns:1fr}}
.price>div{padding:clamp(1.5rem,2.6vw,2.2rem);min-width:0;display:grid;align-content:center;gap:1rem}
.price .amount-cell{border-right:1px solid var(--hair-2);align-content:center}
@media (max-width:760px){.price .amount-cell{border-right:0;border-bottom:1px solid var(--hair-2)}}
.amount{font-family:var(--display);font-variation-settings:"wdth" 78,"wght" 800;font-weight:800;
  font-size:clamp(4.4rem,10vw,7rem);line-height:.85;letter-spacing:-.04em;
  font-variant-numeric:tabular-nums;color:var(--ink);margin:0}
.amount span{color:var(--accent-text)}
.amount-cell .once{font:500 12px/1 var(--mono);letter-spacing:.24em;text-transform:uppercase;
  color:var(--ink-3);margin:0}
.amount-cell .who{font:400 13.5px/1.6 var(--mono);color:var(--ink-3);margin:0}
.amount-cell .who a{color:var(--ink-2)}
.price ul{margin:0;padding:0;list-style:none;display:grid;gap:.6rem;font-size:15.5px;color:var(--ink-2)}
.price li{padding-left:1.6rem;position:relative}
.price li::before{content:"";position:absolute;left:0;top:.56em;width:.6rem;height:.3rem;
  border-left:1.5px solid var(--accent);border-bottom:1.5px solid var(--accent);transform:rotate(-45deg)}
.price .price-cta{display:flex;gap:.65rem;flex-wrap:wrap;align-items:center;margin-top:18px}
@media (max-width:540px){.price .price-cta{display:grid;grid-template-columns:1fr}.price .price-cta .btn{width:100%}}

/* ── Early access ─────────────────────────────────────────────────────── */
#early{scroll-margin-top:5rem}
.early{display:grid;grid-template-columns:minmax(0,1.22fr) minmax(0,.78fr);gap:clamp(1.4rem,3vw,2.6rem);
  align-items:center;background:var(--sheet);border:1px solid var(--hair-2);
  padding:clamp(1.5rem,3vw,2.4rem)}
@media (max-width:820px){.early{grid-template-columns:1fr}}
.early h2{color:var(--ink)}
.early p:not(.kick){color:var(--ink-2);margin:.8rem 0 0;max-width:46ch}
.early strong{color:var(--accent-text);font-weight:600}
.earlyform{display:grid;gap:.6rem}
.earlyform input[type=email]{width:100%;font:400 16px/1.2 var(--body);padding:.8rem .9rem;
  border:1px solid var(--hair-2);border-radius:6px;background:var(--screen);color:var(--ink);min-height:48px}
.earlyform input[type=email]::placeholder{color:var(--ink-3)}
.earlyform input[type=email]:focus{outline:2px solid var(--accent);outline-offset:1px}
.earlyform button{min-height:48px;width:100%}
.earlynote{margin:0;font:400 12.5px/1.6 var(--mono);color:var(--ink-3);overflow-wrap:anywhere;
  text-wrap:balance}
.earlymsg{margin:0;font:400 13.5px/1.5 var(--mono);color:var(--ink-3);overflow-wrap:anywhere}
.earlymsg.is-bad{color:var(--err)}
.earlydone{display:flex;gap:.7rem;align-items:flex-start;font-size:15.5px;line-height:1.5;
  color:var(--ink-2);outline:0;animation:earlyin .3s var(--ease-settle) both}
.earlydone strong{color:var(--accent-text);font-weight:600}
.earlytick{flex:0 0 auto;width:1.35em;height:1.35em;margin-top:.15em;color:var(--accent-text)}
@keyframes earlyin{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.earlydone{animation:none}}

/* ── Legal and plain pages ────────────────────────────────────────────── */
.page{padding:clamp(2.4rem,5vw,4rem) 0 2rem;display:grid;gap:clamp(1.2rem,3vw,3rem);
  grid-template-columns:minmax(0,15rem) minmax(0,66ch)}
@media (max-width:900px){.page{grid-template-columns:1fr}}
/* A one-paragraph page: the footer is pinned to the bottom, so without this
   the whole page sits in the top third with half a screen of board under it.
   Centred, the air reads as margin rather than as a page that ran out. */
main.short{display:flex;flex-direction:column;justify-content:center}
main.short .page{padding-bottom:clamp(2.4rem,5vw,4rem)}
.page-head{align-self:start}
@media (min-width:901px){.page-head{position:sticky;top:6.5rem}}
.page-body>:first-child{margin-top:0}
.page h1{font-size:clamp(2.2rem,4.2vw,3rem);margin-bottom:.6rem}
.page h2{font-size:clamp(1.15rem,1.6vw,1.4rem);margin:2.2rem 0 .6rem}
.page p,.page li{color:var(--ink-2)}
.page a{color:var(--accent-text)}
.page .small{font:400 12.5px/1.5 var(--mono);color:var(--ink-3);letter-spacing:.02em;
  margin-bottom:1.6rem}
.page code{font:.88em/1.4 var(--mono);background:var(--accent-wash);color:var(--ink);
  padding:1px 5px;border-radius:3px}
.page ol,.page ul{padding-left:1.2rem;display:grid;gap:.6rem;margin:0 0 1rem}
/* A button on a plain page keeps its own ink: `.page a` would paint an orange button's
   label orange, which made the activate page's button a blank slab. */
.page a.btn{color:var(--on-accent)}
.page a.btn.ghost{color:var(--ink)}
.page .earlyform{max-width:26rem;margin:1.2rem 0 1.4rem}
.page .earlyform + .small{margin-top:0}

/* ── Title block ──────────────────────────────────────────────────────── */
.titleblock{border-top:1px solid var(--hair-2);margin-top:0;background:var(--sheet)}
/* The last cell is Legal: three links with nothing to break between them, so its column takes
   their width and the other five share the rest. Six even columns overflowed it by 18px at 1024. */
.tb{display:grid;grid-template-columns:repeat(5,minmax(0,1fr)) minmax(max-content,1fr);gap:1px;
  background:var(--hair);padding:0;max-width:var(--wrap);margin:0 auto}
@media (max-width:1000px){.tb{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:620px){.tb{grid-template-columns:repeat(2,minmax(0,1fr))}}
.tb-cell{background:var(--sheet);padding:1.1rem var(--gutter) 1.4rem;display:grid;gap:.4rem;
  align-content:start;min-width:0}
.tb-k{font:500 10px/1 var(--mono);letter-spacing:.24em;text-transform:uppercase;color:var(--ink-3)}
.tb-v{font-size:14px;color:var(--ink-2);overflow-wrap:break-word}
.tb-v a{color:var(--ink-2);text-decoration:none;border-bottom:1px solid var(--hair-2)}
.tb-v a:hover{color:var(--accent-text);border-bottom-color:var(--accent)}
.tb-v a+a{margin-left:.7rem}
/* The bottom rule of the title block: the one line every drawing carries. */
.tb-foot{max-width:var(--wrap);margin:0 auto;padding:1.1rem var(--gutter) 1.3rem;
  display:flex;align-items:baseline;justify-content:space-between;gap:1rem 1.6rem;flex-wrap:wrap;
  font:400 12.5px/1.6 var(--mono);color:var(--ink-3);letter-spacing:.02em}
.tb-foot p{margin:0}
.tb-foot a{color:var(--ink-3);text-decoration:none;border-bottom:1px solid var(--hair-2)}
.tb-foot a:hover{color:var(--accent-text);border-bottom-color:var(--accent)}
.totop{letter-spacing:.14em;text-transform:uppercase;font-weight:500;white-space:nowrap}

/* ── Reveals. One shared observer, one calm ease, a stagger on siblings. ─ */
.js .rv{opacity:0;transform:translateY(22px);filter:blur(5px);
  transition:opacity .75s var(--ease-settle),transform .75s var(--ease-settle),filter .75s var(--ease-settle);
  transition-delay:var(--d,0ms)}
.js .rv.in{opacity:1;transform:none;filter:none}
@media (prefers-reduced-motion:reduce){
  .js .rv{opacity:1;transform:none;filter:none;transition:none}
}

/* ------------------------------------------------------------------- faq */
/* The questions under the price card. Rules, not cards: it is the list a
   drawing puts under its title block, and it keeps the price the one sheet. */
.faq{margin-top:clamp(2rem,4vw,3rem);max-width:52rem}
.faq-k{font:500 12px/1 var(--mono);letter-spacing:.24em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 .9rem}
.faq details{border-top:1px solid var(--hair-2)}
.faq details:last-child{border-bottom:1px solid var(--hair-2)}
.faq summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;
  align-items:baseline;gap:1rem;padding:1rem 0;font:600 17px/1.35 var(--body);color:var(--ink)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";flex:none;font:500 1em/1 var(--mono);color:var(--accent-text)}
.faq details[open] summary::after{content:"\2212"}
.faq summary:hover{color:var(--accent-text)}
.faq summary:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.faq .a{padding:0 0 1.15rem;max-width:var(--measure)}
.faq .a p{margin:0;font-size:15.5px;line-height:1.6;color:var(--ink-2)}

/* The condensed hero face needs a visible word boundary, even at its narrowest axis. */
.hero h1 .nw { word-spacing: .09em; }
