/* ==========================================================================================
   Proseward public site, v2 — "The Desk".

   Warm linen ground, manuscript paper, brand teal. Serif for display, sans for interface.
   No web fonts: the site is served under `font-src 'self'` and there is nothing to serve, so
   the stacks below are system faces chosen to sit near Newsreader and Archivo.

   Restraint is a requirement, not a preference. The v1 site's landing type was too large and
   the hierarchy read as noise; here the display sizes are capped and the weight of a section
   is carried by space and rule, not by point size.

   THIS FILE IS THE ORIGINAL. `app/styles/desk.css` is a byte-for-byte COPY of it, and the copy
   exists because the account page (spec #96) is served by the APP host, which cannot see
   `site-v2/` at all — the public site is answered on the www hostname and nowhere else. Edit
   this file, then re-copy; `app/test/account-page.test.js` fails the moment the two diverge.
   ========================================================================================== */

:root {
  color-scheme: light dark;

  /* ground and paper — the website palette out of the brand document, taken exactly
     (marketing/logo/Final/Proseward_Brand_Identity.html, "A website palette that belongs to the
     logo"). Canvas, Surface, Manuscript, Text, Muted text, Rule, Action and Accent wash are its
     eight names; the -2 and --faint shades between them are mixed from those and are ours. The
     ground moved from warm brown to the near-black green the logo is drawn in, which is why the
     shadows below are cast in that colour rather than in brown. */
  --linen:#f3f1eb; --linen-2:#e7e4db; --paper:#fbf9f5; --card:#ffffff;
  --ink:#011c1f; --ink-2:#33403f; --muted:#52615f; --faint:#7d8a88;
  --rule:#d6ddd7; --rule-2:#bcc7c1;

  /* brand.
     --teal is ACTION teal, not logo teal. The logo is drawn in #1E8C82, which reaches only 4.09:1
     against white and so cannot carry white button text; the brand document names #0B746E for that
     job (5.62:1) and #49C4BA for the same job in the dark theme. Neither is ever painted onto the
     artwork: the logo files carry their own colour and are never recoloured to match the interface. */
  --teal:#0b746e; --teal-ink:#095e59; --teal-wash:#dfeeea; --on-teal:#fff;
  --ochre:#9a6b16; --ochre-wash:#f6ecd8;
  --lilac:#66519c; --lilac-wash:#efeafa;
  --good:#2b6b45; --warn:#8b5a12; --bad:#a63f2e;

  --display:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,serif;
  --ui:"Avenir Next",Avenir,"Segoe UI",Inter,system-ui,-apple-system,sans-serif;
  --read:Charter,"Iowan Old Style",Georgia,serif;
  --mono:"SFMono-Regular",Consolas,"Liberation Mono",monospace;

  --shadow:0 20px 46px rgba(1,28,31,.13), 0 2px 6px rgba(1,28,31,.06);
  --shadow-soft:0 8px 22px rgba(1,28,31,.09);
  /* Cards. Small enough to lift a panel off the ground without turning the page into a stack of
     floating tiles — one soft drop and a hairline, not a halo. */
  --shadow-card:0 1px 2px rgba(1,28,31,.05), 0 6px 16px rgba(1,28,31,.07);
  --shadow-card-hover:0 2px 4px rgba(1,28,31,.07), 0 12px 26px rgba(1,28,31,.10);
  --r:14px; --r-sm:9px; --max:1240px;
}

:root[data-theme="dark"] {
  /* The brand document's after-hours desk: Canvas, Surface, Manuscript, Text, Muted, Rule, Action,
     Accent wash — again taken exactly, with the shades between them mixed from those. */
  --linen:#101718; --linen-2:#141b1c; --paper:#201e1a; --card:#172021;
  --ink:#e8efec; --ink-2:#c8d3d0; --muted:#aab8b4; --faint:#8a9895;
  --rule:#34413f; --rule-2:#485754;
  --teal:#49c4ba; --teal-ink:#6fd6ce; --teal-wash:#173330; --on-teal:#06221f;
  --ochre:#d3a44e; --ochre-wash:#332a17;
  --lilac:#b2a1ec; --lilac-wash:#282243;
  --good:#65c58d; --warn:#dfa54a; --bad:#e0705d;
  --shadow:0 22px 55px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.36);
  --shadow-soft:0 8px 24px rgba(0,0,0,.34);
  --shadow-card:0 1px 2px rgba(0,0,0,.3), 0 6px 16px rgba(0,0,0,.34);
  --shadow-card-hover:0 2px 4px rgba(0,0,0,.36), 0 12px 26px rgba(0,0,0,.44);
}

*,*::before,*::after { box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; }
body {
  margin:0; background:var(--linen); color:var(--ink);
  font:400 16px/1.62 var(--ui); text-rendering:optimizeLegibility;
  -webkit-font-smoothing:antialiased;
}
img,svg { max-width:100%; }
a { color:var(--teal-ink); text-underline-offset:3px; }
a:hover { color:var(--ink); }
h1,h2,h3 { margin:0; font-family:var(--display); font-weight:600; letter-spacing:-.02em; line-height:1.12; }
h1 { font-size:clamp(30px,4.2vw,46px); }
h2 { font-size:clamp(23px,2.6vw,30px); }
h3 { font-size:19px; }
p { margin:0 0 1em; }
ul { margin:0; padding:0; list-style:none; }
:focus-visible { outline:2px solid var(--teal); outline-offset:2px; border-radius:4px; }

.wrap { width:100%; max-width:var(--max); margin:0 auto; padding:0 24px; }
.skip { position:absolute; left:-9999px; }
.skip:focus { left:12px; top:12px; z-index:99; padding:10px 14px; background:var(--card); border-radius:8px; }
.vh { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
.fine { color:var(--muted); font-size:13.5px; }

/* ---------- buttons ---------- */
.btn {
  display:inline-flex; align-items:center; gap:8px; padding:9px 16px;
  border:1px solid var(--rule-2); border-radius:999px; background:var(--card); color:var(--ink);
  font:600 14.5px/1 var(--ui); text-decoration:none; cursor:pointer; white-space:nowrap;
  transition:background .15s, border-color .15s, color .15s;
}
.btn:hover { border-color:var(--ink-2); color:var(--ink); }
.btn-primary { background:var(--teal); border-color:var(--teal); color:var(--on-teal); }
.btn-primary:hover { background:var(--teal-ink); border-color:var(--teal-ink); color:var(--on-teal); }
.btn-quiet { background:transparent; border-color:transparent; color:var(--muted); }
.btn-quiet:hover { background:var(--linen-2); color:var(--ink); }
.btn-lg { padding:12px 22px; font-size:15.5px; }
.btn[disabled] { opacity:.45; cursor:default; }
.text-button { padding:0; border:0; background:none; color:var(--teal-ink); font:inherit; text-decoration:underline; text-underline-offset:3px; cursor:pointer; }

/* ---------- header ---------- */
.head { position:sticky; top:0; z-index:40; background:color-mix(in srgb, var(--linen) 88%, transparent); backdrop-filter:saturate(1.4) blur(9px); border-bottom:1px solid var(--rule); }
/* 68px rather than 60: the signature below needs the height, and the brand document is explicit that
   a placement which cannot hold the artwork should change rather than the artwork be squeezed. */
.head-inner { display:flex; align-items:center; gap:18px; height:68px; }

/* THE LOGO IS ARTWORK, NOT A TINTED SHAPE.

   The previous version drew the wordmark as a CSS mask and painted it with a brand variable, so one
   file could serve both themes. That is exactly what the brand document forbids — "never recolour the
   logo to match a button or theme accent", "use the official colour, black, or white files" — and it
   also threw away the two-colour mark, since a mask has only one colour to give. So each signature is
   now the supplied file, and the dark theme swaps in the supplied white-text file instead of retinting
   anything.

   The artwork carries its own clear space: the content sits inside a 1764.55 x 530.79 canvas with the
   quarter-of-mark-height exclusion zone already drawn around it. Sizing by that outer ratio therefore
   keeps the exclusion zone automatically, and it is why the boxes below look larger than the ink.

   Header: the horizontal signature without the tagline — the document's "everyday website and product
   signature" — at 65px of box, which puts the ink at 180px wide, its stated digital minimum. */
.brand { display:flex; align-items:center; font-size:0; text-decoration:none; }
.brand::before {
  content:""; display:block; height:65px; width:calc(65px * 1764.55 / 530.79);
  background:url(/assets/logo-horizontal.svg) center/contain no-repeat;
}
:root[data-theme="dark"] .brand::before { background-image:url(/assets/logo-horizontal-dark.svg); }
/* No hover recolour, for the same reason: there is no such thing as a hover-coloured Proseward logo. */
.brand:hover { opacity:.82; }

/* Footer: the complete signature, tagline included — the document's "preferred first introduction" —
   at 100px of box, which puts the ink at 280px wide, its stated minimum with the tagline. */
.foot-mark {
  display:block; height:100px; width:calc(100px * 1764.55 / 530.79); margin:-14px 0 0 -14px;
  background:url(/assets/logo-full.svg) left center/contain no-repeat;
}
:root[data-theme="dark"] .foot-mark { background-image:url(/assets/logo-full-dark.svg); }
.nav { margin-left:auto; }
.nav ul { display:flex; gap:4px; }
.nav a { display:block; padding:7px 11px; border-radius:8px; color:var(--muted); font-size:14.5px; font-weight:550; text-decoration:none; }
.nav a:hover,.nav a[aria-current="page"] { background:var(--linen-2); color:var(--ink); }
.head-actions { display:flex; align-items:center; gap:8px; }
.menu-toggle { display:none; }

/* A menu row that exists only on narrow screens: it stands in for a header action the width rule
   below drops. Hidden on a wide screen, where the header still has room for the real one. */
.nav-narrow { display:none; }

/* ---------- the account control (#96 D-96-60) ----------

   One control, two names. The app writes an authority-free `pw_signedin` hint on the shared parent
   domain and `assets/account-boot.js` stamps `data-signedin` on <html> before first paint; everything
   below is that one attribute deciding which of the two names is in the document.

   THE SIGNED-OUT NAME IS THE ONE IN THE HTML. No JavaScript, no cookie, a private window, a hint that
   has gone stale the wrong way — all of them land on "Sign in", and no stranger ever sees "Your
   account" flicker past. The other name is `display:none`, not visually hidden, so the control's
   accessible name is whichever word is showing rather than both run together.

   The icon is the same mark the app uses beside its own account menu, painted through a mask so it
   takes `currentColor` and needs no second file for the dark theme. It is on the header pill only: the
   narrow-screen copy in the menu is a text link among text links, and a lone icon in that list would
   be the odd one out. */
.head-actions .acct { padding-left:13px; }
.head-actions .acct::before {
  content:""; width:18px; height:18px; flex:none; background:currentColor;
  -webkit-mask:url(/assets/icon-user.svg) center/contain no-repeat;
          mask:url(/assets/icon-user.svg) center/contain no-repeat;
}
.acct .in { display:none; }
:root[data-signedin] .acct .out { display:none; }
:root[data-signedin] .acct .in { display:inline; }

/* ---------- what the header shows to whom (#96 D-96-63) ----------

   MEASURED, because the first version of this shipped a clipped control. On `pricing.html` at the
   site's widest layout the box is 1192px and the header wanted 1241px: brand 216 + nav 502 + six
   actions 487 + gaps 36. The account pill was the thing hanging off the right edge, and no amount of
   spacing arithmetic recovers 49px. (The pristine header needed 1091px of window, so it already ran
   out of room below that — see §"header, narrow" for what this package did and did not fix.)

   So the header holds four things at a time, not six, and which four depends on the one bit the hint
   carries:

     · SIGNED OUT, the forum action is hidden. It would take the reader to a sign-in page — which the
       control immediately beside it offers more honestly — and the nav's plain `Community` link is
       already the front door meant for somebody who has never heard of us.
     · SIGNED IN, the acquisition calls are hidden. "Start free", "Beta signup" and "Put your hand up"
       are addressed to a stranger; showing them to a subscriber is noise at best.

   Both states degrade to something sensible if the hint is wrong, which it is allowed to be: a stale
   hint costs a signed-out reader the two calls to action, and a missing one costs a subscriber the
   one-click forum route. Neither loses anybody a way in. */
:root:not([data-signedin]) .head-actions .head-forum { display:none; }
:root[data-signedin] .head-actions .head-join { display:none; }

/* ---------- footer ---------- */
.foot { margin-top:64px; padding:26px 0 44px; border-top:1px solid var(--rule); color:var(--muted); font-size:13.5px; }
.foot-inner { display:flex; flex-wrap:wrap; align-items:center; gap:10px; }
.foot a { color:var(--muted); }
.foot .sep { color:var(--faint); }
.foot .right { margin-left:auto; }

/* ==========================================================================================
   The splash (ungated front door)
   ========================================================================================== */
.splash-main { padding:52px 0 0; }
.splash-grid { display:grid; grid-template-columns:minmax(320px,1fr) minmax(420px,1.1fr); gap:52px; align-items:center; }
.splash-eyebrow { margin:0 0 14px; color:var(--teal-ink); font-size:12.5px; font-weight:700; letter-spacing:.11em; text-transform:uppercase; }
.splash-copy h1 { margin-bottom:16px; }
.splash-lede { max-width:46ch; color:var(--ink-2); font-family:var(--read); font-size:19px; line-height:1.56; }
.splash-cta { display:flex; flex-wrap:wrap; gap:10px; margin:26px 0 14px; }
.splash-note { margin:14px 0 0; padding:11px 14px; border-left:3px solid var(--ochre); background:var(--ochre-wash); border-radius:0 8px 8px 0; color:var(--ink-2); font-size:14px; }

/* the paper card: a manuscript page with four marks on it */
.paper {
  position:relative; padding:30px 34px 26px; border:1px solid var(--rule);
  border-radius:var(--r); background:var(--paper); box-shadow:var(--shadow);
}
.paper::after { content:""; position:absolute; inset:auto 16px -7px 16px; height:7px; border-radius:0 0 10px 10px; background:var(--linen-2); }
.paper-head { display:flex; justify-content:space-between; margin-bottom:16px; color:var(--faint); font-size:12px; letter-spacing:.04em; text-transform:uppercase; }
.paper-copy { font-family:var(--read); font-size:17px; line-height:1.72; color:var(--ink); }
.paper-copy h2 { margin:2px 0 14px; font-size:25px; }
.paper-copy mark { padding:1px 2px; background:var(--ochre-wash); border-bottom:2px solid var(--ochre); color:inherit; }
.marks { display:grid; gap:8px; margin-top:20px; padding-top:18px; border-top:1px dashed var(--rule); }
.mark { display:grid; grid-template-columns:auto 1fr; gap:11px; align-items:start; padding:9px 11px; border:1px solid var(--rule); border-radius:var(--r-sm); background:var(--card); box-shadow:var(--shadow-card); text-align:left; font:inherit; cursor:pointer; }
.mark:hover { border-color:var(--rule-2); }
.mark[aria-pressed="true"] { border-color:var(--teal); background:var(--teal-wash); }
.mark-kind { padding:2px 8px; border-radius:999px; background:var(--linen-2); color:var(--muted); font-size:11px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; }
.mark[aria-pressed="true"] .mark-kind { background:var(--teal); color:var(--on-teal); }
.mark b { display:block; font-family:var(--read); font-size:15px; font-weight:500; }
.mark i { display:block; margin-top:3px; color:var(--muted); font-size:12.5px; font-style:normal; }

.workmap { display:grid; grid-template-columns:repeat(auto-fit,minmax(168px,1fr)); gap:1px; margin:56px 0 0; border:1px solid var(--rule); border-radius:var(--r); background:var(--rule); overflow:hidden; }
.workmap a { display:block; padding:17px 18px; background:var(--linen-2); color:var(--ink); text-decoration:none; }
.workmap a:hover { background:var(--card); }
.workmap strong { display:block; margin-bottom:4px; font-family:var(--display); font-size:19px; font-weight:600; }
.workmap span { color:var(--muted); font-size:13.5px; line-height:1.45; }

/* the invite dialog */
dialog.gate { width:min(440px,calc(100vw - 32px)); padding:0; border:1px solid var(--rule-2); border-radius:var(--r); background:var(--card); color:var(--ink); box-shadow:var(--shadow); }
dialog.gate::backdrop { background:rgba(30,25,18,.5); }
dialog.gate form { padding:26px 26px 22px; }
dialog.gate h2 { margin-bottom:8px; font-size:22px; }
.gate-blurb { color:var(--muted); font-size:14.5px; }
.gate-label { display:block; margin:16px 0 6px; font-size:13px; font-weight:650; letter-spacing:.03em; text-transform:uppercase; color:var(--muted); }
.gate-code { width:100%; padding:12px 14px; border:1px solid var(--rule-2); border-radius:var(--r-sm); background:var(--paper); color:var(--ink); font:600 26px/1.2 var(--mono); letter-spacing:.28em; text-align:center; }
.gate-error { margin:11px 0 0; color:var(--bad); font-size:14px; }
.gate-progress { margin:11px 0 0; color:var(--muted); font-size:14px; }
.gate-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:20px; }

/* ==========================================================================================
   The journey — the whole product in one screen
   ========================================================================================== */
.hero { padding:56px 0 34px; border-bottom:1px solid var(--rule); }
/* Both columns start at the top. They used to be bottom-aligned, which was fine when the right-hand
   box was four lines and wrong the moment it became ten: the heading slid down the page to meet the
   bottom of a list it has nothing to do with. */
.hero-grid { display:grid; grid-template-columns:1.15fr .85fr; gap:48px; align-items:start; }
.hero-grid h1 { max-width:16ch; }
.hero-lede { max-width:52ch; margin:16px 0 0; color:var(--ink-2); font-family:var(--read); font-size:18.5px; line-height:1.58; }
.hero-side { padding-bottom:6px; color:var(--muted); font-size:14.5px; }
.hero-side p { margin:0 0 10px; }
.hero-cta { display:flex; flex-wrap:wrap; gap:10px; margin-top:22px; }

.journey { padding-top:34px; }
.journey-head { display:flex; flex-wrap:wrap; align-items:baseline; gap:10px 14px; margin-bottom:14px; }
.journey-head h2 { font-size:24px; }
.journey-head p { margin:0; color:var(--muted); font-size:14.5px; }

/* The journey lives in the SAME margins as the rest of the site — a section that breaks the page's
   own grid reads as a different website bolted on, which is what it looked like.

   That makes the two left columns load-bearing. The arithmetic, at the 1240px maximum: 1192 of
   content, less 185 of rail, less 245 of list, less 24 of gaps, leaves 738 for the pane and 716
   inside its padding. A capture is 1180 wide natively and 60% of that is 708. It fits, with eight
   pixels to spare — which is why these numbers are what they are, and why changing one means
   redoing the sum. */
.journey-grid { display:grid; grid-template-columns:185px 245px minmax(0,1fr); gap:12px; align-items:start; }

/* — the rail — */
.rail { position:sticky; top:84px; border:1px solid var(--rule); border-radius:var(--r); background:var(--linen-2); overflow:hidden; }
.rail-item + .rail-item { border-top:1px solid var(--rule); }
.rail-btn { display:grid; grid-template-columns:21px 1fr auto; gap:9px; align-items:center; width:100%; padding:10px 11px; border:0; background:none; color:var(--ink); font:600 15px/1.3 var(--ui); text-align:left; cursor:pointer; }
.rail-btn:hover { background:var(--card); }
.rail-item.is-open .rail-btn { background:var(--card); }
.num { display:grid; place-items:center; width:21px; height:21px; border-radius:6px; background:var(--linen); color:var(--muted); font:700 11.5px/1 var(--mono); }
.rail-item.is-open .num { background:var(--teal); color:var(--on-teal); }

.rail-count { color:var(--faint); font:600 12px/1 var(--mono); }
.rail-line { display:none; padding:0 11px 12px 40px; margin:-2px 0 0; color:var(--muted); font-family:var(--read); font-size:14px; line-height:1.48; background:var(--card); }
.rail-item.is-open .rail-line { display:block; }

/* — the feature list — */
.featurelist { border:1px solid var(--rule); border-radius:var(--r); background:var(--card); overflow:hidden; }
.featurelist-head { display:flex; align-items:center; gap:9px; padding:10px 13px; background:var(--teal); color:var(--on-teal); }
.featurelist-head .num { background:rgba(255,255,255,.22); color:var(--on-teal); }
.featurelist-head b { font-family:var(--display); font-size:17px; font-weight:600; letter-spacing:-.01em; }
.feat + .feat { border-top:1px solid var(--rule); }
.feat-btn { display:block; width:100%; padding:10px 13px; border:0; border-left:3px solid transparent; background:none; color:var(--ink); font:inherit; text-align:left; cursor:pointer; }
.feat-btn:hover { background:var(--linen-2); }
.feat-btn[aria-current="true"] { border-left-color:var(--teal); background:var(--teal-wash); }

/* The demo's steps, under the feature they belong to. They used to sit below the demo in the pane,
   where they were under the fold and nobody found them. */
.steplist { display:grid; margin:0; padding:0; list-style:none; border-top:1px solid var(--rule); background:var(--paper); }
.step-btn { display:grid; grid-template-columns:18px 1fr; gap:8px; align-items:center; width:100%; padding:7px 13px 7px 16px; border:0; border-left:3px solid transparent; background:none; color:var(--muted); font:500 13px/1.35 var(--ui); text-align:left; cursor:pointer; }
.step-btn:hover { background:var(--linen-2); color:var(--ink); }
.step-btn.is-current { border-left-color:var(--teal); background:var(--teal-wash); color:var(--ink); font-weight:650; }
.step-n { display:grid; place-items:center; width:18px; height:18px; border-radius:5px; background:var(--linen-2); color:var(--faint); font:700 10.5px/1 var(--mono); }
.step-btn.is-current .step-n { background:var(--teal); color:var(--on-teal); }
.feat-btn b { display:block; font-size:14.5px; font-weight:650; }
.feat-btn i { display:block; margin-top:3px; color:var(--muted); font-size:13px; font-style:normal; line-height:1.45; }
.tag { display:inline-block; margin-left:7px; padding:1px 7px; border-radius:999px; font:700 10.5px/1.55 var(--ui); letter-spacing:.05em; text-transform:uppercase; vertical-align:1px; }
.tag-partial { background:var(--ochre-wash); color:var(--ochre); }
.tag-future { background:var(--lilac-wash); color:var(--lilac); }

/* — the pane — */
.pane { border:1px solid var(--rule); border-radius:var(--r); background:var(--card); overflow:hidden; }
/* Title and controls on ONE line. The heading had a line of its own and a benefit paragraph under it,
   and between them they pushed the demo far enough down that its callouts fell off the screen. */
.pane-head { display:flex; flex-wrap:wrap; align-items:center; gap:10px 14px; padding:10px 14px; border-bottom:1px solid var(--rule); background:var(--linen-2); }
.pane-head h3 { flex:1 1 auto; min-width:0; font-size:18px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* On a wide pane the controls sit beside the title; on a narrow one they take a line of their own
   and wrap inside it, rather than running off the right edge. */
.pane-head #pane-transport { flex:1 1 auto; min-width:0; display:flex; justify-content:flex-end; }
@media (max-width:700px) {
  .pane-head h3 { flex:1 1 100%; white-space:normal; }
  .pane-head #pane-transport { justify-content:flex-start; }
}
.pane-benefit { margin:0 0 10px; max-width:70ch; color:var(--ink-2); font-family:var(--read); font-size:16px; line-height:1.5; }
.pane-partial { margin:0 0 10px; padding:8px 12px; border-left:3px solid var(--ochre); background:var(--ochre-wash); border-radius:0 7px 7px 0; color:var(--ink-2); font-size:13.5px; }

/* The step's own clock, so a still screen says whether it is playing. */
.progress { height:3px; background:var(--linen-2); }
.progress-fill { width:0; height:100%; background:var(--teal); }

/* Above the smallest zoom the demo is wider than the pane on purpose, so this is the one place on
   the site allowed to scroll sideways. The page body never does. */
.stage-wrap { padding:10px; background:var(--linen-2); border-bottom:1px solid var(--rule); overflow-x:auto; }
.stage {
  position:relative; margin:0 auto; border:1px solid var(--rule-2); border-radius:10px;
  background:var(--paper); box-shadow:var(--shadow-soft); overflow:hidden;
}
.stage iframe { display:block; border:0; transform-origin:0 0; background:var(--paper); }
.stage-empty { display:grid; place-items:center; gap:8px; min-height:220px; padding:30px; text-align:center; color:var(--muted); }
.stage-empty b { font-family:var(--display); font-size:18px; color:var(--ink-2); }
.stage-empty span { font-size:13.5px; max-width:44ch; }

/* callout pins on the frame, cards in the gutter */
.pin { position:absolute; z-index:3; display:grid; place-items:center; width:21px; height:21px; border-radius:999px; background:var(--teal); color:var(--on-teal); font:700 11.5px/1 var(--mono); box-shadow:0 1px 4px rgba(0,0,0,.3); }
.ring { position:absolute; z-index:2; border:1.5px solid var(--teal); border-radius:5px; background:color-mix(in srgb, var(--teal) 8%, transparent); pointer-events:none; }
.callouts { display:grid; gap:7px; align-content:start; }
.callout { display:grid; grid-template-columns:21px 1fr; gap:10px; align-items:start; padding:10px 12px; border:1px solid var(--rule); border-radius:var(--r-sm); background:var(--paper); box-shadow:var(--shadow-card); opacity:.42; transition:opacity .2s, border-color .2s; }
.callout.is-live { opacity:1; border-color:var(--teal); }
.callout-n { display:grid; place-items:center; width:21px; height:21px; border-radius:999px; background:var(--linen-2); color:var(--muted); font:700 11.5px/1 var(--mono); }
.callout.is-live .callout-n { background:var(--teal); color:var(--on-teal); }
.callout b { display:block; font-size:14px; font-weight:650; }
.callout i { display:block; margin-top:2px; color:var(--muted); font-size:13px; font-style:normal; line-height:1.45; }

/* transport */
.transport { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.tgroup { display:inline-flex; }
.tgroup .tbtn { border-radius:0; margin-left:-1px; }
.tgroup .tbtn:first-child { border-radius:7px 0 0 7px; margin-left:0; }
.tgroup .tbtn:last-child { border-radius:0 7px 7px 0; }
.tbtn { display:grid; place-items:center; width:30px; height:29px; padding:0; border:1px solid var(--rule-2); border-radius:7px; background:var(--card); color:var(--ink); cursor:pointer; }
.tbtn:hover { border-color:var(--ink-2); z-index:1; }
.tbtn[disabled] { opacity:.35; cursor:default; }
/* `display:grid` above beats the browser's own `[hidden] { display:none }`, so a transport button
   that is hidden in script stays on screen unless this says otherwise. Found with the pop-out's own
   button, which sat in the dialog beside the Close it had just been replaced by. */
.tbtn[hidden] { display:none; }
.tbtn.is-on { background:var(--teal); border-color:var(--teal); color:var(--on-teal); }
.tbtn svg { width:14px; height:14px; fill:currentColor; }
/* A 15px turtle read as a smudge. The speed control is labelled and its drawing is half again bigger. */
.tbtn svg.ic-lg { width:19px; height:19px; }
.tbtn-wide { width:auto; gap:6px; grid-auto-flow:column; padding:0 10px; font:650 12.5px/1 var(--ui); }
.tstep { min-width:44px; color:var(--muted); font:600 12.5px/1 var(--mono); text-align:center; }
.pane-foot { padding:12px 14px 14px; }
.pane-lower { display:grid; grid-template-columns:1fr 1fr; gap:14px; align-items:start; }
.points { display:grid; gap:5px; align-content:start; }
@media (max-width:900px) { .pane-lower { grid-template-columns:1fr; } }
.points li { position:relative; padding-left:17px; color:var(--ink-2); font-size:14px; line-height:1.5; }
.points li::before { content:""; position:absolute; left:2px; top:8px; width:6px; height:6px; border-radius:2px; background:var(--teal); }
/* The step's own words, beside the step's own picture. Quiet on purpose: the callouts to its left
   are the argument, this is the caption. */
.note-card { padding:10px 12px; border:1px solid var(--rule); border-left:3px solid var(--teal); border-radius:0 var(--r-sm) var(--r-sm) 0; background:var(--linen-2); box-shadow:var(--shadow-card); }
.note-card b { display:block; font-size:14px; font-weight:650; }
.note-card p { margin:3px 0 0; color:var(--ink-2); font-size:13.5px; line-height:1.5; }

.pane-aside { flex:0 1 250px; padding:12px 14px; border:1px dashed var(--rule-2); border-radius:var(--r-sm); background:var(--linen-2); color:var(--muted); font-size:13px; }
.pane-aside b { display:block; margin-bottom:4px; color:var(--ink-2); font-size:13px; }

/* ==========================================================================================
   Long-form sections used by the depth pages
   ========================================================================================== */
.band { padding-top:52px; padding-bottom:52px; border-top:1px solid var(--rule); }
.band-lede { max-width:62ch; color:var(--ink-2); font-family:var(--read); font-size:17.5px; line-height:1.6; }
.cards { display:grid; grid-template-columns:repeat(auto-fit,minmax(255px,1fr)); gap:14px; margin-top:26px; }
/* Every card on the site lifts off the ground by the same amount. They were flat outlines before,
   which on the new lighter canvas made a grid of them read as a table rather than as things. */
.card { padding:18px 20px; border:1px solid var(--rule); border-radius:var(--r); background:var(--card); box-shadow:var(--shadow-card); }
.card h3 { margin-bottom:7px; }
.card p { margin:0; color:var(--muted); font-size:14.5px; line-height:1.55; }

/* The top ten opens the page. Its ten cards are the same cards as everywhere else — these are the
   same features, and dressing them differently would suggest otherwise — so the section is marked by
   its rule and its lede rather than by restyling the contents. */
.index-group { margin-top:34px; }
.index-group.is-shortcut > h2 { border-bottom-width:2px; border-bottom-color:var(--teal); }
.index-group.is-shortcut > p { color:var(--ink-2); }
.index-group.is-shortcut .index-item h3 { font-family:var(--display); font-size:17px; font-weight:600; letter-spacing:-.01em; }
.index-group > h2 { padding-bottom:8px; border-bottom:1px solid var(--rule); }
.index-group > p { margin:9px 0 16px; color:var(--muted); font-family:var(--read); font-size:16px; }
.index-list { display:grid; grid-template-columns:repeat(auto-fit,minmax(290px,1fr)); gap:12px; }
.index-item { padding:15px 17px; border:1px solid var(--rule); border-radius:var(--r); background:var(--card); box-shadow:var(--shadow-card); transition:box-shadow .15s, border-color .15s; }
.index-item:hover { border-color:var(--rule-2); box-shadow:var(--shadow-card-hover); }
.index-item h3 { font-family:var(--ui); font-size:15px; font-weight:700; letter-spacing:0; }
.index-item p { margin:6px 0 9px; color:var(--ink-2); font-size:14px; line-height:1.5; }
.index-item ul { display:grid; gap:4px; }
.index-item li { position:relative; padding-left:15px; color:var(--muted); font-size:13px; line-height:1.45; }
.index-item li::before { content:""; position:absolute; left:2px; top:7px; width:5px; height:5px; border-radius:2px; background:var(--rule-2); }
.index-item .demo-link { display:inline-block; margin-top:9px; font-size:13px; font-weight:650; }

/* comparison */
.compare-pills { display:flex; flex-wrap:wrap; gap:7px; margin:18px 0 8px; }
.pill { padding:7px 13px; border:1px solid var(--rule-2); border-radius:999px; background:var(--card); color:var(--ink); font:600 13.5px/1 var(--ui); cursor:pointer; }
.pill[aria-pressed="true"] { background:var(--teal); border-color:var(--teal); color:var(--on-teal); }
/* A pill can be selected AND disabled at once — the table needs at least two competitors, so the
   last two selected cannot be turned off. Fading those would say "not selected" about the two columns
   the reader is looking at. Only an unselected, unavailable pill fades. */
.pill[disabled] { cursor:default; }
.pill[disabled][aria-pressed="false"] { opacity:.4; }
.table-scroll { overflow-x:auto; margin-top:18px; border:1px solid var(--rule); border-radius:var(--r); background:var(--card); }
table.compare { width:100%; border-collapse:collapse; font-size:14px; }
table.compare th, table.compare td { padding:11px 14px; border-bottom:1px solid var(--rule); text-align:left; vertical-align:top; }
table.compare thead th { position:sticky; top:0; background:var(--linen-2); font-size:13px; letter-spacing:.02em; }
table.compare tbody th { font-weight:600; color:var(--ink); }
table.compare .pw-col { background:var(--teal-wash); }
.cap { display:inline-flex; align-items:center; gap:6px; font-weight:650; font-size:13px; }
.cap-full { color:var(--good); } .cap-part { color:var(--warn); } .cap-none { color:var(--faint); }
.compare-notes { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:12px; margin-top:18px; }
.compare-notes article { padding:15px 17px; border:1px solid var(--rule); border-radius:var(--r); background:var(--card); box-shadow:var(--shadow-card); }
.compare-notes h3 { font-family:var(--ui); font-size:15px; font-weight:700; }
.compare-notes p { margin:6px 0 0; color:var(--muted); font-size:14px; line-height:1.5; }

/* pricing */
.billing { display:inline-flex; gap:3px; padding:3px; border:1px solid var(--rule-2); border-radius:999px; background:var(--card); }
.billing button { padding:6px 15px; border:0; border-radius:999px; background:none; color:var(--muted); font:650 13.5px/1 var(--ui); cursor:pointer; }
.billing button[aria-pressed="true"] { background:var(--teal); color:var(--on-teal); }
.plans { display:grid; grid-template-columns:repeat(auto-fit,minmax(255px,1fr)); gap:14px; margin-top:22px; }
.plan { display:flex; flex-direction:column; padding:20px 22px; border:1px solid var(--rule); border-radius:var(--r); background:var(--card); box-shadow:var(--shadow-card); }
.plan.is-featured { border-color:var(--teal); box-shadow:var(--shadow-card-hover); }
.plan h3 { font-family:var(--ui); font-size:16px; font-weight:750; letter-spacing:0; }
.plan .price { margin:12px 0 2px; font-family:var(--display); font-size:38px; font-weight:600; letter-spacing:-.03em; }
.plan .per { color:var(--muted); font-size:13.5px; }
.plan .plan-job { min-height:2.8em; margin-top:4px; color:var(--muted); font-size:13.5px; line-height:1.4; }
.plan ul { display:grid; gap:6px; margin:16px 0 20px; }
.plan ul + .fine { margin:-10px 0 18px; line-height:1.45; }
.plan li { position:relative; padding-left:18px; color:var(--ink-2); font-size:14px; line-height:1.5; }
.plan li::before { content:"✓"; position:absolute; left:0; color:var(--teal); font-weight:700; }
.plan .btn { margin-top:auto; justify-content:center; }

/* ==========================================================================================
   Beta form
   ========================================================================================== */
.beta-wrap { max-width:800px; margin:0 auto; padding:0 24px; }
.pitch { padding:40px 0 8px; }
.pitch h1 { max-width:22ch; }
.pitch p { max-width:70ch; color:var(--ink-2); font-family:var(--read); font-size:17px; line-height:1.66; }
.pitch-tldr { padding:13px 16px; border-left:3px solid var(--teal); background:var(--teal-wash); border-radius:0 8px 8px 0; font-family:var(--ui) !important; font-size:15px !important; }
.pitch-list { display:grid; gap:9px; margin:14px 0 22px; }
.pitch-list li { position:relative; max-width:70ch; padding-left:19px; color:var(--ink-2); font-size:15px; line-height:1.58; }
.pitch-list li::before { content:""; position:absolute; left:2px; top:9px; width:6px; height:6px; border-radius:2px; background:var(--teal); }
.pitch-honest { padding:13px 16px; border-left:3px solid var(--ochre); background:var(--ochre-wash); border-radius:0 8px 8px 0; font-family:var(--ui) !important; font-size:14.5px !important; }
.beta-card { margin:26px 0 40px; padding:26px 28px; border:1px solid var(--rule); border-radius:var(--r); background:var(--card); box-shadow:var(--shadow-soft); }
.field { margin:0 0 20px; padding:0; border:0; }
.field > label, .field > legend { display:block; margin:0 0 6px; padding:0; font-size:14px; font-weight:700; }
.hint { margin:0 0 9px; color:var(--muted); font-size:13.5px; line-height:1.5; }
.field input[type=text],.field input[type=email],.field textarea {
  width:100%; padding:10px 12px; border:1px solid var(--rule-2); border-radius:var(--r-sm);
  background:var(--paper); color:var(--ink); font:15px/1.5 var(--ui);
}
.field textarea { resize:vertical; }
.checks { display:grid; grid-template-columns:repeat(auto-fit,minmax(165px,1fr)); gap:5px; margin-bottom:9px; }
.check { display:flex; align-items:center; gap:8px; padding:7px 10px; border:1px solid var(--rule); border-radius:var(--r-sm); background:var(--paper); font-size:14px; cursor:pointer; }
.check:hover { border-color:var(--rule-2); }
.radios { display:grid; gap:7px; }
.radio { display:grid; grid-template-columns:auto 1fr; gap:10px; align-items:start; padding:11px 13px; border:1px solid var(--rule); border-radius:var(--r-sm); background:var(--paper); cursor:pointer; }
.radio:hover { border-color:var(--rule-2); }
.radio b { display:block; font-size:14.5px; }
.radio i { display:block; margin-top:2px; color:var(--muted); font-size:13px; font-style:normal; line-height:1.45; }
input[type=checkbox],input[type=radio] { accent-color:var(--teal); width:16px; height:16px; margin:2px 0 0; }
.hp { position:absolute; left:-9999px; }
.form-error { margin:0 0 14px; padding:11px 14px; border-left:3px solid var(--bad); background:color-mix(in srgb, var(--bad) 9%, transparent); border-radius:0 8px 8px 0; color:var(--ink); font-size:14.5px; }
.form-actions { margin-top:22px; }
.thanks h2 { margin-bottom:10px; }
.thanks p { max-width:62ch; color:var(--ink-2); font-size:15.5px; }
.sr-only { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }

/* ==========================================================================================
   Narrow screens
   ========================================================================================== */
@media (max-width:1080px) {
  .journey-grid { grid-template-columns:190px minmax(0,1fr); }
  .pane { grid-column:1 / -1; }
  .rail { position:static; }
}
/* ---------- header, narrow (#96 D-96-63) ----------

   Below the site's widest layout the account control keeps its icon and loses its word. The name is
   still there — clipped, not removed — so the control is still "Sign in" or "Your account" to a screen
   reader and is a bare user icon to everybody else, which is the one glyph on the web that needs no
   caption. That buys back about 60px in the band where the header is tightest.

   WHAT THIS DOES NOT FIX, stated plainly because the next person will measure it and wonder. The
   header was ALREADY too wide for a window between 861px and about 1069px before this package existed
   — at a 1000px window, `pricing.html` laid out 1069px of header in a 985px box and nothing said so.
   The account control widens that band to about 1119px WHEN SIGNED OUT, and narrows it to nothing when
   signed in (the two acquisition calls that stand down are wider than the control that replaces them).
   Closing the signed-out band properly means deciding what a mid-width header drops, which is a
   redesign of the header rather than an addition to it. Measured and recorded, not fixed. */
@media (max-width:1220px) {
  .head-actions .acct { padding-left:11px; padding-right:11px; }
  .head-actions .acct span { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
}
@media (max-width:860px) {
  .splash-grid, .hero-grid { grid-template-columns:1fr; gap:32px; }
  .hero-grid { align-items:start; }
  .journey-grid { grid-template-columns:1fr; }
  .menu-toggle { display:inline-flex; margin-left:auto; }
  .nav { position:absolute; left:0; right:0; top:68px; margin:0; padding:8px 16px 14px; background:var(--linen); border-bottom:1px solid var(--rule); }
  .nav[data-open="false"] { display:none; }
  .nav ul { flex-direction:column; gap:2px; }
  /* The header cannot hold its actions at this width, so the quiet ones are dropped — but a link that
     is ONLY in the header is then unreachable on a phone, which is what happened to the front door's
     "Sign in". Each page that drops one carries a `nav-narrow` copy of it in the menu, and that copy
     appears exactly where the original disappears. */
  .head-actions .btn:not(.theme-toggle):not(.btn-primary) { display:none; }
  .nav-narrow { display:list-item; }
  .pane-foot { flex-direction:column; }
}
/* Below about 560px the header runs out of room: brand + Menu + appearance + Start free came to
   404px of content in a 327px box, and the CTA overflowed off the right edge. Measured, not guessed.
   The wordmark is what goes — the mark alone is still the home link, and it keeps its accessible
   name — because losing the CTA or the appearance switch costs the reader more than losing a word
   they can see in the page title. */
@media (max-width:560px) {
  .head-inner { gap:8px; }
  /* The signature becomes the logomark rather than a squashed signature — a different supplied file,
     not the same one shrunk. 50px of box puts the ink at 32px, the document's preferred logomark
     minimum (24px is its absolute floor). The colour logomark is passed for both themes: the document
     allows it on white and on a near-black solid field alike. */
  .brand::before {
    height:50px; width:calc(50px * 1085.71 / 973.86);
    background-image:url(/assets/logo-mark.svg);
  }
  :root[data-theme="dark"] .brand::before { background-image:url(/assets/logo-mark.svg); }
  .head-inner .btn { padding:8px 12px; font-size:14px; }
  .head-actions { gap:6px; }
}

@media (prefers-reduced-motion:reduce) {
  * { animation:none !important; transition:none !important; scroll-behavior:auto !important; }
}

/* ==========================================================================================
   Spacing utilities.

   These exist because the site is served under `style-src 'self'`, which blocks inline style
   attributes as firmly as it blocks inline <script>. A one-off nudge that would ordinarily be
   `style="margin-top:16px"` has to be a class, so here they are, named for what they do.
   ========================================================================================== */
.mt-s { margin-top:12px; }
.mt-m { margin-top:18px; }
.mt-l { margin-top:28px; }
.mb-0 { margin-bottom:0; }
.measure { max-width:70ch; }
.stack-1 { grid-template-columns:1fr; }
.form-inset { margin-top:24px; }

/* ---------- the hero's side column, and the About page ---------- */
.hero-side-h { margin:0 0 6px; color:var(--ink); font-size:14px; font-weight:700; }
.hero-side p + .hero-side-h, .hero-side ul + .hero-side-h { margin-top:18px; }
/* Ten hooks, one line each. A marker rather than a bullet: these are jumps, not prose. */
.wowlist { display:grid; gap:3px; margin:0 0 10px; }
.wowlist li { position:relative; padding-left:15px; line-height:1.45; }
.wowlist li::before { content:""; position:absolute; left:2px; top:8px; width:5px; height:5px; border-radius:2px; background:var(--teal); }
.wowlist a { color:var(--ink-2); text-decoration:none; border-bottom:1px solid var(--rule-2); }
.wowlist a:hover { color:var(--ink); border-bottom-color:var(--teal); }
.jumps { display:flex; flex-wrap:wrap; gap:8px; margin-top:20px; }
.jumps a { padding:6px 13px; border:1px solid var(--rule-2); border-radius:999px; background:var(--card); color:var(--ink); font:600 13.5px/1 var(--ui); text-decoration:none; }
.jumps a:hover { border-color:var(--ink-2); }
.prose { max-width:70ch; }
.prose p { color:var(--ink-2); font-family:var(--read); font-size:17px; line-height:1.66; }
.impressum { max-width:56ch; margin-top:22px; }
.impressum p { color:var(--ink-2); font-size:15px; line-height:1.55; }
.impressum b { color:var(--ink); }

/* A rendered chapter, in the pane and in the static index. The control is the browser's own — a
   hand-built transport would be one more thing to keep working in four browsers, and this one
   already has a keyboard and a screen reader. */
.pane-aud, .aud { margin:10px 0 0; }
.pane-aud audio, .aud audio { display:block; width:100%; max-width:460px; height:34px; }
.pane-aud figcaption, .aud figcaption { margin-top:5px; color:var(--ink-2); font-size:12.5px; line-height:1.45; }

/* ==========================================================================================
   The pop-out — the same demo, at its true size

   The pane fits a 1180px capture into about 700px, which is fine for following what is happening
   and no good at all for reading the app's own text. Rather than a zoom control that has to be
   nudged twice, one button opens the demo in a dialog at 100%: the title, the same transport, the
   same progress bar, the stage, and the callouts underneath where there is room for all of them at
   once. The nodes are MOVED here and moved back, so the frame does not reload and the step the
   reader was on is the step they still see.
   ========================================================================================== */
dialog.demo-pop {
  width:min(96vw, 1340px); max-width:none; max-height:92vh; padding:0; overflow:hidden;
  border:1px solid var(--rule-2); border-radius:var(--r);
  background:var(--card); color:var(--ink); box-shadow:var(--shadow);
}
/* Guarded on [open], because `display` on a bare `dialog` overrides the browser's own
   `dialog:not([open]) { display:none }` and the closed dialog would sit in the page. The column is
   what keeps the title and the controls still while only the picture scrolls. */
dialog.demo-pop[open] { display:flex; flex-direction:column; }
dialog.demo-pop::backdrop { background:rgba(1,28,31,.62); }
.pop-head { display:flex; align-items:center; gap:14px; padding:11px 14px; border-bottom:1px solid var(--rule); background:var(--linen-2); }
.pop-title { flex:0 1 auto; min-width:0; font-family:var(--display); font-size:18px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.pop-transport { flex:1 1 auto; display:flex; justify-content:flex-end; }
.pop-close { flex:0 0 auto; }
.pop-bar .progress { height:3px; }
/* The one place a capture is shown at 100%, so the one place it may be wider and taller than the
   window. It scrolls in both directions rather than being shrunk back down — being shrunk is what
   the reader just asked to escape. */
.pop-stage { flex:1 1 auto; min-height:0; overflow:auto; background:var(--linen-2); }
.pop-stage .stage-wrap { overflow:visible; border-bottom:0; }
.pop-calls { flex:0 0 auto; padding:12px 14px 14px; border-top:1px solid var(--rule); }
.pop-calls .callouts { grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:8px; }
/* A step with nothing to say gets no empty strip under it. */
.pop-calls:not(:has(.callout)) { padding:0; border-top:0; }
@media (max-width:700px) {
  .pop-head { flex-wrap:wrap; }
  .pop-title { flex:1 1 100%; }
  .pop-transport { justify-content:flex-start; }
}
