/* Butterpie public site — Lemon Berry.
   ================================================================================================
   ONE STYLESHEET, NO FRAMEWORK, NO WEBFONT, NO THIRD-PARTY REQUEST. The public page is what an
   unauthenticated stranger loads first, and every external reference is a request this estate cannot
   vouch for. The page's own CSP says so in machine terms — `default-src 'none'` with `style-src
   'self'`, which also means NO inline `style=` attribute anywhere in the generated HTML, and (since
   `font-src` falls through to `default-src`) no web font at all. The type stack is what the visitor
   already has; the character comes from scale, weight, spacing and colour rather than from a face
   nobody is guaranteed to receive.

   THE PAGE IS BUILT LIKE THE MARK. Butter on filling on crust: a plum crust at the top and the
   bottom, a berry filling that does the work, and lemon as the thin bright line between layers. That
   is not a metaphor stretched over a template — it is the composition the brand kit prescribes for
   the product itself (plum navigation shell, berry actions, lemon for small emphasis, ~85-90%
   neutral where the reading happens), applied to a page instead of an application.

   DEPTH IS GROUNDS AND ELEVATION, NOT DECORATION. Three grounds alternate down the page; three
   elevations lift objects off them; one object crosses a seam to prove the grounds are separate
   sheets rather than a background that changed colour. There is no gradient on this page.
   THE ONE DEPARTURE FROM BOTH SENTENCES (2026-09-28, pending the owner's word) is the eye candy the
   owner asked for: the hero's ASCII object, and the hover kit's lights, which are gradients only while
   something is lit — at rest the page is still the one described here. See those two sections.
   ================================================================================================ */

/* ---- Tokens -------------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  /* The three permanent colours of the approved mark. Never a UI surface; never recoloured. */
  --bp-lemon: #F4E68A;
  --bp-berry: #A32142;
  --bp-plum: #3E2838;

  --bp-canvas: #F8F7F8;
  --bp-surface: #FFFFFF;
  --bp-sunk: #F1EDF0;
  --bp-text: #2E202A;
  --bp-text-2: #6B5D67;
  --bp-muted: #776772;
  --bp-border: #E6DFE4;
  --bp-control: #91818B;
  --bp-primary: #A32142;
  --bp-primary-hover: #8A1A38;
  --bp-primary-pressed: #71132D;
  --bp-on-primary: #FFFFFF;
  --bp-link: #A32142;
  --bp-link-hover: #71132D;
  --bp-focus: #285F91;
  --bp-highlight: #FCF8DD;
  --bp-on-highlight: #3E2838;
  --bp-ok: #26734D;
  --bp-danger: #B42318;

  /* THE SHELL. Plum in both themes — it is a brand surface, not a light-mode surface, exactly as in
     the product. Everything that sits on it takes a token from THIS group and never from the page's,
     which is the rule the judges' one confirmed AA failure came from breaking: the page's focus blue
     is 2.00:1 on plum, and the berry link colour is unreadable on it. */
  --bp-shell: #3E2838;
  --bp-on-shell: #F8F3F6;
  --bp-shell-2: #C5B8C1;
  --bp-shell-hover: #52374A;
  --bp-shell-line: #5A4354;
  --bp-shell-focus: #F4E68A;

  /* THE PLATE IS PERMANENTLY LIGHT, IN BOTH THEMES, AND IT EXISTS FOR ONE REASON. The approved
     full-colour mark has three fills and no background: its crust is #3E2838, so on a plum shell the
     crust is literally invisible and the transparent separations fill with plum. The kit's own answer
     is "use the white logo on plum" — but the colour mark is the one the brand leads with, so instead
     of giving it up the page gives it a surface to live on. A physical object, mounted on the
     masthead the way a maker's badge is set into an instrument. */
  --bp-plate: #FFFFFF;
  --bp-on-plate: #2E202A;

  /* Elevation. Plum-tinted, because a neutral-black shadow over plum-tinted neutrals reads as dirt. */
  --e-ring: 0 0 0 1px var(--bp-border);
  --e-card: 0 0 0 1px var(--bp-border), 0 1px 2px rgb(46 32 42 / .05), 0 8px 20px -14px rgb(46 32 42 / .28);
  --e-plate: 0 0 0 1px rgb(46 32 42 / .10), 0 2px 6px rgb(27 21 27 / .18), 0 24px 56px -28px rgb(27 21 27 / .45);

  --maxw: 1120px;
  --r-sm: 8px; --r: 12px; --r-lg: 18px; --r-pill: 999px;
  --gut: 24px;
}

/* Dark. Three states: the un-stamped default follows the system, and either explicit choice beats it.
   The media query wraps the selector rather than nesting inside it, so this needs no CSS Nesting
   support to work. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bp-canvas: #1B151B;
    --bp-surface: #261E26;
    --bp-sunk: #312731;
    --bp-text: #F8F3F6;
    --bp-text-2: #C5B8C1;
    --bp-muted: #AB9BA6;
    --bp-border: #483B47;
    --bp-control: #8D7989;
    --bp-primary: #F28AA5;
    --bp-primary-hover: #F6A1B6;
    --bp-primary-pressed: #E87394;
    --bp-on-primary: #2A1420;
    --bp-link: #F28AA5;
    --bp-link-hover: #F6A1B6;
    --bp-focus: #F4E68A;
    --bp-highlight: #39331E;
    --bp-on-highlight: #F4E68A;
    --bp-ok: #8ED5AD;
    --bp-danger: #FFAAA0;
    /* THE SHELL GOES DARKER, NOT LIGHTER, AND THAT IS THE FIX FOR A MEASURED PROBLEM. Plum #3E2838
       against the dark page #261E26 is 1.21:1 — a tonal shift nobody can see, so a reverse-printed
       band would simply vanish and the brand would exist at full strength in light mode only. The
       product's own dark nav is #211820, and using it here keeps the band a band. */
    --bp-shell: #211820;
    --bp-shell-hover: #3E2838;
    --bp-shell-line: #483B47;
    --e-ring: 0 0 0 1px var(--bp-border);
    --e-card: 0 0 0 1px var(--bp-border), inset 0 1px 0 rgb(248 243 246 / .05);
    --e-plate: 0 0 0 1px rgb(0 0 0 / .5), 0 2px 8px rgb(0 0 0 / .5), 0 28px 60px -30px rgb(0 0 0 / .7);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bp-canvas: #1B151B;
  --bp-surface: #261E26;
  --bp-sunk: #312731;
  --bp-text: #F8F3F6;
  --bp-text-2: #C5B8C1;
  --bp-muted: #AB9BA6;
  --bp-border: #483B47;
  --bp-control: #8D7989;
  --bp-primary: #F28AA5;
  --bp-primary-hover: #F6A1B6;
  --bp-primary-pressed: #E87394;
  --bp-on-primary: #2A1420;
  --bp-link: #F28AA5;
  --bp-link-hover: #F6A1B6;
  --bp-focus: #F4E68A;
  --bp-highlight: #39331E;
  --bp-on-highlight: #F4E68A;
  --bp-ok: #8ED5AD;
  --bp-danger: #FFAAA0;
  --bp-shell: #211820;
  --bp-shell-hover: #3E2838;
  --bp-shell-line: #483B47;
  --e-ring: 0 0 0 1px var(--bp-border);
  --e-card: 0 0 0 1px var(--bp-border), inset 0 1px 0 rgb(248 243 246 / .05);
  --e-plate: 0 0 0 1px rgb(0 0 0 / .5), 0 2px 8px rgb(0 0 0 / .5), 0 28px 60px -30px rgb(0 0 0 / .7);
}
:root[data-theme="light"] { color-scheme: light; }

/* ---- Base ---------------------------------------------------------------------------------- */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; }
}
body {
  margin: 0;
  background: var(--bp-canvas);
  color: var(--bp-text);
  font: 16px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
        "Noto Sans JP", "Hiragino Sans", "Yu Gothic UI", Meiryo, Arial, sans-serif;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { line-height: 1.15; text-wrap: balance; margin: 0 0 .5em; letter-spacing: -.022em; }
h1 { font-size: clamp(2.1rem, 5.2vw, 3.4rem); font-weight: 800; }
h2 { font-size: clamp(1.55rem, 3vw, 2.15rem); font-weight: 750; }
h3 { font-size: 1.02rem; font-weight: 700; letter-spacing: -.01em; }
p { margin: 0 0 1em; }
a { color: var(--bp-link); text-underline-offset: 2px; }
a:hover { color: var(--bp-link-hover); }
:focus-visible { outline: 2px solid var(--bp-focus); outline-offset: 2px; border-radius: 4px; }
img { max-width: 100%; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: var(--gut); }
.skip { position: absolute; left: -9999px; }
.skip:focus {
  left: 12px; top: 12px; z-index: 60; background: var(--bp-surface); color: var(--bp-text);
  padding: 10px 14px; border-radius: var(--r-sm); box-shadow: var(--e-card);
}
.vh {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ---- The crust: masthead + hero, one continuous plum ground -------------------------------- */
.crust, .band-shell, .foot {
  background: var(--bp-shell); color: var(--bp-on-shell);
  /* THE SHELL IS A DARK SURFACE IN BOTH THEMES, SO IT TAKES THE DARK CONTROLS IN BOTH THEMES, and
     this is arithmetic rather than taste. A berry #A32142 button measures 1.82:1 against light plum
     and 2.35:1 against dark plum — a filled control whose fill is under the 3:1 non-text floor is a
     control you cannot see, which is 1.4.11 exactly. The kit's own dark-mode berry is a LIGHTER one
     "for controls", and it lands at 5.72:1 on light plum and 7.36:1 on dark, with its #2A1420 label
     at 7.34:1 on the fill. So the shell pins the dark ramp locally, once, and every button, border
     and ring on it inherits a checked pairing instead of the page's. */
  --bp-primary: #F28AA5;
  --bp-primary-hover: #F6A1B6;
  --bp-primary-pressed: #E87394;
  --bp-on-primary: #2A1420;
  /* An outlined button's border IS its boundary, so it is a CONTROL border and not a decorative
     divider: `--bp-shell-line` is 1.95:1 on dark plum and fails. 3.34:1 / 4.30:1. */
  --bp-shell-control: #8D7989;
}
/* EVERY FOCUSABLE THING ON PLUM TAKES THE LEMON RING. The page's focus blue is 2.00:1 against plum —
   below the 3:1 floor for a non-text indicator — so on this ground the ring is lemon (10.56:1) with a
   shell-coloured offset, which is the kit's own instruction for focus on a coloured surface. */
.crust :focus-visible { outline-color: var(--bp-shell-focus); box-shadow: 0 0 0 4px var(--bp-shell); }
.crust a { color: var(--bp-on-shell); }
.crust a:hover { color: var(--bp-shell-focus); }
/* …EXCEPT A FILLED BUTTON, which carries its own label colour. `.crust a` outranks `.btn-primary`, so
   the header's "Create account" was painted near-white on the pink fill — 2.14:1 — and lemon on hover.
   The shell's own pairing, #2A1420 on #F28AA5, is 7.34:1. */
.crust .btn-primary, .crust .btn-primary:hover { color: var(--bp-on-primary); }

/* THE MASTHEAD WRAPS INTO ROWS, NOT INTO A PILE. Left to `flex-wrap` alone the pickers drop under the
   mark and the nav floats where the pickers were, which reads as a layout that broke rather than one
   that responded. The nav takes a full row of its own instead, and the controls stay together.
   SINCE 2026-09-28 THE NAV ALWAYS HAS ITS OWN ROW. With "AI" and "Help & support" it holds six links,
   and the header's content box is capped at the page's 1120px: measured, the mark, six links, the two
   pickers and the two buttons need 1150-1235px in Polish, German, French and Japanese, so the single
   row that used to hold above 1080px would never hold again — the buttons wrapped under the mark at
   every width. Two rows at every width is one layout instead of one per language.
   THE ACCOUNT BUTTONS ARE ALWAYS THE RIGHT END OF THE FIRST ROW — top right is where a visitor looks
   for "Log in" — so each breakpoint below re-orders the rows around them rather than letting them
   wrap wherever they land:
     ≥701px    mark … pickers · buttons, then the nav
     481–700   mark … buttons, then the pickers, then the nav
     ≤480      the mark, then the buttons (right-aligned), then the pickers, then the nav
   The last split is measured, not guessed: the widest pair (French, 264px) beside the mark does not
   fit the 272px content box of a 320px phone, so on a phone the buttons take a row of their own. */
.top {
  display: flex; align-items: center; gap: 14px 20px; flex-wrap: wrap;
  max-width: var(--maxw); margin: 0 auto; padding: 14px var(--gut);
}
.top .picks { margin-inline-start: auto; }
.top .auth { display: flex; gap: 8px; align-items: center; margin-inline-start: auto; }
/* THE PICKER PILL'S SIZE, NOT THE PAGE BUTTON'S. At the full 15px/13px 22px every label is 25-30px
   wider and the French pair alone overflows a 320px phone. */
.top .auth .btn { font-size: 13.5px; padding: 7px 13px; border-radius: var(--r-pill); white-space: nowrap; line-height: 1.2; }
/* While the pickers share the buttons' row, the two are one group at the end of it. */
@media (min-width: 701px) {
  .top .auth { margin-inline-start: 0; }
}
/* On a phone the pickers get a row of their own, and a right-aligned pair alone on a line reads as
   something that fell off rather than as a control group. They align with everything else. */
@media (max-width: 700px) {
  .top .picks { margin-inline-start: 0; order: 2; flex-basis: 100%; }
  .top .auth { order: 1; }
}
@media (max-width: 480px) {
  .top .auth { flex-basis: 100%; justify-content: flex-end; }
}
/* THE PLATE. The full-colour mark's only home on a plum ground. */
/* A PLATE RE-DECLARES THE TOKENS OF THE THINGS ON IT, and that is not belt-and-braces. The plate is
   light in BOTH themes; the page's tokens are not. A dark-theme visitor reading `var(--bp-text)` on
   a white plate gets #F8F3F6 on #FFFFFF — 1.0:1, invisible — and a lemon focus ring on it measures
   1.16:1. So anything that is a plate pins the light values locally, once, and everything inside it
   inherits them by construction rather than by each rule remembering. */
.plate {
  background: var(--bp-plate);
  --bp-surface: #FFFFFF; --bp-sunk: #F1EDF0;
  --bp-text: #2E202A; --bp-text-2: #6B5D67; --bp-muted: #776772;
  --bp-border: #E6DFE4; --bp-control: #91818B;
  --bp-link: #A32142; --bp-link-hover: #71132D;
  --bp-focus: #285F91;
  --bp-ok: #26734D; --bp-danger: #B42318;
  color: var(--bp-text);
}
.crust .plate :focus-visible { outline-color: var(--bp-focus); box-shadow: none; }

.brand {
  display: inline-flex; align-items: center; gap: 10px; text-decoration: none;
  padding: 7px 14px 7px 10px; border-radius: var(--r-pill);
  font-weight: 800; font-size: 17px; letter-spacing: -.02em;
  box-shadow: 0 1px 2px rgb(0 0 0 / .22), 0 6px 16px -10px rgb(0 0 0 / .5);
}
.crust .brand, .crust .brand:hover { color: var(--bp-text); }
.brand img { display: block; width: 34px; height: auto; }

.topnav { display: flex; gap: 6px 22px; flex-wrap: wrap; order: 3; flex-basis: 100%; margin-inline-start: 0; }
.topnav a { color: var(--bp-shell-2); text-decoration: none; font-weight: 600; font-size: 14px; }
.topnav a:hover { color: var(--bp-on-shell); }
/* THE PAGE YOU ARE ON, SHOWN AS WELL AS ANNOUNCED. `aria-current="page"` is the semantic half; this is
   the visible half — the shell's own foreground and a lemon underline, not a colour change alone. */
.topnav a[aria-current="page"] {
  color: var(--bp-on-shell); text-decoration: underline; text-decoration-color: var(--bp-shell-focus);
  text-decoration-thickness: 2px; text-underline-offset: 6px;
}

/* ---- The two pickers ------------------------------------------------------------------------
   Both are a native <details>/<summary> disclosure: <summary> is mapped to a button with
   expanded/collapsed state by the browser itself, so Enter and Space work, screen readers announce
   it, and — for the language picker, which contains real <a href> — the whole control still works
   with no JavaScript at all and is crawlable. Zero ARIA, zero roving tabindex, zero focus trap. */
.picks { display: flex; gap: 8px; align-items: center; }
.pick { position: relative; }
.pick > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 11px; border-radius: var(--r-pill);
  /* A control border, not a divider — see the note on `--bp-shell-control`. */
  border: 1px solid var(--bp-shell-control); background: transparent; color: var(--bp-on-shell);
  font-size: 13px; font-weight: 650;
}
.pick > summary::-webkit-details-marker { display: none; }
.pick > summary::marker { content: ''; }
.pick > summary:hover { background: var(--bp-shell-hover); }
.pick > summary .chev { width: 9px; height: 9px; flex: none; opacity: .7; }
.pick[open] > summary .chev { transform: rotate(180deg); }
.pick-menu {
  position: absolute; inset-inline-end: 0; top: calc(100% + 7px); z-index: 40;
  min-width: 190px; padding: 6px;
  background: var(--bp-surface); color: var(--bp-text);
  border-radius: var(--r); box-shadow: var(--e-card);
  display: flex; flex-direction: column; gap: 2px;
}
.pick-menu a, .pick-menu button {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font: inherit; font-size: 14px; text-align: start; text-decoration: none;
  color: var(--bp-text); background: transparent; border: 0; border-radius: var(--r-sm);
  padding: 8px 10px; cursor: pointer; width: 100%;
}
.pick-menu a:hover, .pick-menu button:hover { background: var(--bp-sunk); color: var(--bp-text); }
/* THE CURRENT ITEM IS MARKED TWICE, and that is the "never by colour alone" rule: a lemon flag AND a
   check glyph AND `aria-current` / `aria-pressed` for anyone not looking at the page. */
.pick-menu [aria-current="true"], .pick-menu [aria-pressed="true"] { background: var(--bp-highlight); color: var(--bp-on-highlight); font-weight: 700; }
.pick-menu .tick { visibility: hidden; flex: none; }
.pick-menu [aria-current="true"] .tick, .pick-menu [aria-pressed="true"] .tick { visibility: visible; }
/* The theme picker cannot work without script, so it is not SHOWN without script. A control that is
   visible and dead is worse than a control that is absent. boot.js stamps `data-js` before paint. */
.pick-theme { display: none; }
:root[data-js="on"] .pick-theme { display: block; }

/* ---- Hero ---------------------------------------------------------------------------------- */
/* The hero is a full-width band whose TEXT is measured, not a 46rem block floated in the middle of
   the page: `.wrap`'s auto margins would centre the whole section and leave the headline starting a
   third of the way across. The measure belongs to the lines, not to the section. */
.hero { padding-block: 56px 36px; }
.hero h1, .hero .slogan, .hero .lead, .hero .ctas, .hero .note { max-width: 46rem; }
.kicker {
  display: inline-block; margin: 0 0 18px; padding: 4px 12px; border-radius: var(--r-pill);
  /* Lemon's whole budget on this page is: this pill, the two seams, the focus ring on plum, and the
     product frame's active nav item. The kit's most repeated instruction is "sparingly". */
  /* ON THE CANVAS THE PILL NEEDS AN EDGE. Lemon against the light canvas is 1.25:1 — the fill is
     invisible as a boundary — where against the plum it used to sit it was 10.56:1 and needed
     nothing. The plum text was always 10.56:1 on lemon and is unchanged; only the outline is new,
     and it makes the chip identical in both themes. */
  background: var(--bp-lemon); color: var(--bp-plum); border: 1px solid var(--bp-plum);
  font-size: 12px; font-weight: 800; letter-spacing: .10em; text-transform: uppercase;
}
/* CANVAS PAIRS, because the hero is on the canvas now. These read `--bp-on-shell` and
   `--bp-shell-2` while the hero lived inside `.crust`; left behind after the move they would be
   near-white text on a near-white page in the light theme — the exact half-applied-change failure
   this estate keeps shipping. --bp-text on --bp-canvas is 14.49:1 light / 16.37:1 dark, and
   --bp-text-2 is 5.80:1 / 9.40:1. The link colour is 6.89:1 light and 7.66:1 dark. */
/* THE SLOGAN LEADS AND THE H1 FOLLOWS, SMALLER (the owner, 2026-09-27). The two swapped their type
   and their colour: the rotating line takes the headline size and the text colour, and the h1 ("Your
   whole back office, in one place.") takes the slogan's former size and the link colour. The h1 stays
   the h1 — it is what the page is about, for a search engine and a screen reader's heading list. */
.hero h1 { font-size: clamp(1.2rem, 2.6vw, 1.6rem); font-weight: 700; letter-spacing: -.012em; color: var(--bp-link); margin: 0 0 14px; }
.hero .lead { color: var(--bp-text-2); font-size: 1.12rem; max-width: 62ch; }
/* THE ROTATING LINE, AT HEADLINE SIZE. Eight spans, one shown: the markup gives the rest `hidden`
   (the page without script shows the first), and boot.js stamps `data-slogan` on the root BEFORE the
   first paint, which the rules below turn into exactly one visible span — so the line is never
   swapped under the reader, and a display-size line that wraps differently cannot shift the page.
   Only these rules give a slogan span a `display`: the one keyed to the stamped index, after the
   rule that hides all eight. A `display` anywhere else would beat `hidden` and show all eight at
   once. The list has exactly eight lines (the build refuses any other count, SLOGAN_COUNT).
   `anywhere` keeps a long word from widening a phone. */
.slogan {
  font-size: clamp(2.1rem, 5.2vw, 3.4rem); font-weight: 800; line-height: 1.15; letter-spacing: -.022em;
  text-wrap: balance; color: var(--bp-text); margin: 0 0 .3em; overflow-wrap: anywhere;
}
/* JAPANESE BREAKS AFTER 、 AND 。, NOT BETWEEN ANY TWO CHARACTERS. At headline size the slogans
   wrap, and Japanese may otherwise break anywhere: "Butterpie。経理 / も、サクサク。" split the particle
   from its noun, and phrase detection (`auto-phrase`) still split いい/厨房 and ひと/味. Every line of
   the list is punctuated into its phrases, so `keep-all` breaks exactly there, in every browser;
   `overflow-wrap: anywhere` above still breaks a phrase too wide for its line, and that break puts
   the 、 at the start of the next line. So every phrase, WITH its 、, must fit the narrowest line: a
   320px phone leaves 272px, and at the Japanese floor of 1.9rem (30.4px, tracked -.022em) nine
   full-width characters measure about 267px (バックオフィスの、, 現地法人の数字が、, 事務の下ごしらえ、)
   and ten about 297px. A new Japanese slogan keeps each phrase to nine characters, the 、 included. */
:lang(ja) .slogan { word-break: keep-all; font-size: clamp(1.9rem, 5.2vw, 3.4rem); }
:root[data-slogan] .slogan > span { display: none; }
:root[data-slogan="0"] .slogan > span:nth-child(1),
:root[data-slogan="1"] .slogan > span:nth-child(2),
:root[data-slogan="2"] .slogan > span:nth-child(3),
:root[data-slogan="3"] .slogan > span:nth-child(4),
:root[data-slogan="4"] .slogan > span:nth-child(5),
:root[data-slogan="5"] .slogan > span:nth-child(6),
:root[data-slogan="6"] .slogan > span:nth-child(7),
:root[data-slogan="7"] .slogan > span:nth-child(8) { display: inline; }
@media (prefers-reduced-motion: no-preference) {
  .slogan > span { animation: slogan-in .35s ease-out; }
}
@keyframes slogan-in { from { opacity: 0; } to { opacity: 1; } }
.ctas { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 30px; }
.btn {
  display: inline-flex; align-items: center; gap: 8px; text-decoration: none; cursor: pointer;
  font: inherit; font-size: 15px; font-weight: 700; line-height: 1;
  padding: 13px 22px; border-radius: var(--r); border: 1px solid transparent;
  transition: background 140ms cubic-bezier(.2,0,0,1), color 140ms cubic-bezier(.2,0,0,1);
}
.btn-primary { background: var(--bp-primary); color: var(--bp-on-primary); }
.btn-primary:hover { background: var(--bp-primary-hover); color: var(--bp-on-primary); }
.btn-primary:active { background: var(--bp-primary-pressed); }
/* On plum, an outlined button takes the shell's own foreground — a `--bp-surface` fill would be a
   white chip on the crust and a berry fill would be a second primary. */
.crust .btn-outline, .band-shell .btn-outline { border-color: var(--bp-shell-control); color: var(--bp-on-shell); background: transparent; }
.crust .btn-outline:hover, .band-shell .btn-outline:hover { background: var(--bp-shell-hover); color: var(--bp-on-shell); }
.btn-outline { border-color: var(--bp-control); color: var(--bp-text); background: transparent; }
.btn-outline:hover { background: var(--bp-sunk); }
.btn:disabled { background: var(--bp-sunk); color: var(--bp-muted); border-color: transparent; cursor: default; }
.hero .note { color: var(--bp-muted); font-size: 13.5px; margin-top: 16px; }
/* THE TWO-DEMO CHOOSER (2026-09-29; built only with SITE_DEMO_CAFE=on) — the demo leaves the hero's
   button row and becomes a labelled pair: a heading line, the two companies, one note. The group is
   spaced as one unit, and its parts sit closer to each other than to the rest of the hero. A long
   company name may wrap inside its button on a phone, so the pair's buttons get a line height that
   survives a second line. */
.demo-pick { max-width: 46rem; margin-top: 26px; }
.demo-pick-h { margin: 0; font-size: 15px; font-weight: 700; color: var(--bp-text); }
.hero .demo-pick .ctas { margin-top: 12px; }
.hero .demo-pick .note { margin-top: 10px; }
.demo-pick .btn { line-height: 1.25; }

/* ---- The hero's ASCII object (site.fx.js) ----------------------------------------------------
   EYE CANDY THE OWNER ASKED FOR (2026-09-28), AND IT KEEPS THE PAGE'S RULES. "Depth is not decoration"
   gives way here, by request, and nowhere else. The box is RESERVED HERE, before the first paint, and
   the script only fills it with a canvas: nothing moves when it arrives (CLS 0). Without script the
   box is zero high — `data-js` is stamped by boot.js before the first paint — so a reader without it
   gets exactly the page. It takes no pointer events, and the script leaves every cell under a line of
   the hero's text blank, so no word's contrast changes.
   WHERE IT GOES. From 1000px up it is lifted out of the flow into the empty column beside the 46rem
   measure, behind the words (the hero isolates, the layer is -1), bleeding into the page margin to
   24px short of the window's edge and never past it: min() keeps it at the hero's own edge until
   there is margin to take. Below 1000px there is no column, and it is a strip AFTER the trust line —
   never between the headline and the buttons, so a phone's first screen still ends in its buttons. */
.hero { position: relative; isolation: isolate; }
.fx-ascii { display: block; height: 0; pointer-events: none; user-select: none; -webkit-user-select: none; }
.fx-ascii canvas { display: block; width: 100%; height: 100%; }
:root[data-js="on"] .fx-ascii { height: 200px; margin-top: 18px; }
@media (min-width: 600px) { :root[data-js="on"] .fx-ascii { height: 240px; } }
@media (min-width: 1000px) {
  :root[data-js="on"] .fx-ascii {
    position: absolute; z-index: -1; margin: 0; height: auto;
    top: 8px; bottom: 84px; left: calc(var(--gut) + 46rem + 16px);
    right: min(0px, calc((var(--maxw) - 100vw) / 2 + 24px));
  }
}
/* Printed, in forced colours (its inks are ours, not the reader's), or when the reader asks for more
   contrast: no drawing at all, and no reserved strip either. */
@media print, (forced-colors: active), (prefers-contrast: more) { .fx-ascii { display: none; } }

/* ---- The object that crosses the seam -------------------------------------------------------
   It sits half on the crust and half on the canvas, which is what makes the two read as separate
   sheets rather than as a background that changed colour.

   IT IS A REAL SCREENSHOT, AND THAT IS A CORRECTION. The first draft of this page put a hand-built
   HTML replica of the application here — plum rail, lemon active item, a plausible sales register —
   which themes and translates for free and costs no bytes, and which sits one band above a caption
   that reads "Real screens from the product, not mock-ups." A drawing of the product directly above
   that sentence makes the sentence false. The screenshots are the proof; this is the first of them,
   given the position the drawing wanted. */
/* NO LONGER CROSSING A SEAM. The -68px pulled the plate up over the boundary between the plum
   crust and the canvas, which was the whole device; with the hero on the canvas there is no
   boundary to cross and the negative margin just collided with the buttons above it. */
.hero-shot {
  max-width: var(--maxw); margin-inline: auto; margin-top: 8px; position: relative; z-index: 2;
  border-radius: var(--r-lg); box-shadow: var(--e-plate); overflow: hidden;
  padding: 10px;
}
.hero-shot img { display: block; width: 100%; height: auto; border-radius: 10px; }
.hero-shot figcaption { padding: 12px 8px 6px; color: var(--bp-text-2); font-size: .92rem; }
.hero-shot figcaption strong { color: var(--bp-text); display: block; font-size: 1.02rem; letter-spacing: -.01em; }
@media (max-width: 760px) { .hero-shot { margin-top: 4px; } }

/* A status is a word AND a shape, never a colour on its own. */
.tag { display: inline-block; padding: 1px 9px; border-radius: var(--r-pill); font-size: 11px; font-weight: 700; border: 1px solid; }
.tag-ok { color: var(--bp-ok); border-color: var(--bp-ok); }
.tag-late { color: var(--bp-danger); border-color: var(--bp-danger); }

/* ---- Bands --------------------------------------------------------------------------------- */
.band { padding-block: 74px; }
.band-canvas { background: var(--bp-canvas); }
/* RECESSED, not raised: a hairline top and bottom and a darker ground, with no shadow, reads as a
   well cut into the page. It is the ledger's shaded column. */
.band-sunk { background: var(--bp-sunk); border-block: 1px solid var(--bp-border); }
.band-shell { /* ground + control tokens: see the shared rule above */ }
/* THE SEAM. Three pixels of lemon where a sheet ends — the white gap between butter, filling and
   crust in the mark, translated. Used exactly twice on the page. */
.seam { height: 3px; background: var(--bp-lemon); }
.band .lead { color: var(--bp-text-2); font-size: 1.06rem; max-width: 68ch; }
.band-shell .lead { color: var(--bp-shell-2); }
.band-shell h2 { color: var(--bp-on-shell); }

/* ---- The index ------------------------------------------------------------------------------
   Thirteen capability areas, as a numbered index rather than thirteen cards. An accountant reads an
   index; thirteen cards is a wall nobody finishes. The number is real information — it says how many
   there are and where you are — so it earns its place.
   EACH ROW SHOWS ITS AREA (2026-09-28): the area's dashboard, captured in the page's language, sits
   beside the text, and the area's short tour video under the bullets. A row with neither is the text
   index row it always was, its bullets in two columns. */
.index { margin-top: 34px; border-top: 1px solid var(--bp-border); }
.idx {
  display: grid; grid-template-columns: 3.2rem minmax(0, 1fr);
  gap: 4px 26px; padding: 26px 0; border-bottom: 1px solid var(--bp-border);
  align-items: start;
}
.idx.has-shot { grid-template-columns: 3.2rem minmax(0, 1fr) minmax(0, 1.3fr); }
.idx-n { font-variant-numeric: tabular-nums; color: var(--bp-muted); font-size: 13px; font-weight: 700; letter-spacing: .04em; margin: 4px 0 0; }
.idx-text { min-width: 0; }
.idx h3 { margin: 0 0 4px; font-size: 1.12rem; }
.idx-blurb { color: var(--bp-text-2); font-size: .95rem; margin: 0; }
.idx ul {
  margin: 10px 0 0; padding: 0; list-style: none;
  color: var(--bp-text-2); font-size: .9rem;
}
.idx:not(.has-shot) ul { columns: 2; column-gap: 26px; }
.idx li { break-inside: avoid; padding-inline-start: 15px; position: relative; margin-bottom: 3px; }
.idx li::before { content: ''; position: absolute; inset-inline-start: 0; top: .62em; width: 6px; height: 1px; background: var(--bp-control); }
.idx-shot { margin: 0; padding: 8px; border-radius: var(--r-lg); box-shadow: var(--e-plate); min-width: 0; }
.idx-shot img { display: block; width: 100%; height: auto; border-radius: 8px; }
.idx .clip { margin-top: 18px; max-width: 480px; }
@media (max-width: 860px) {
  .idx, .idx.has-shot { grid-template-columns: 2.6rem minmax(0, 1fr); }
  .idx-shot { grid-column: 2 / -1; margin-top: 14px; }
  .idx:not(.has-shot) ul { columns: 1; }
}

/* ---- Screens --------------------------------------------------------------------------------- */

/* ================================================================================================
   MARKETING SURFACES — the trust strip, value cards, product tour, area list, plan table and FAQ.
   Every colour here is a token; the kit check in tests/unit refuses a literal it does not publish.
   ================================================================================================ */

/* ---- The compliance strip under the hero ---------------------------------------------------- */
.trust {
  list-style: none; margin: 30px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 10px 26px;
}
.trust li {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--bp-text-2); font-size: 14px; font-weight: 600;
}
.trust .tick { color: var(--bp-primary); flex: none; }

/* ---- Value cards ----------------------------------------------------------------------------- */
.values { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 22px; }
.value {
  background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: var(--r-lg);
  padding: 26px 24px;
  /* ONLY box-shadow AND transform MOVE. Transitioning a colour-bearing property is what produced a
     measured 1.27:1 mid-transition in the product's buttons; the rule is the same here. */
  transition: box-shadow .18s var(--ease, ease), transform .18s var(--ease, ease);
}
.value:hover { box-shadow: var(--e-card); transform: translateY(-2px); }
.value h2 { font-size: 1.12rem; margin: 0 0 10px; letter-spacing: -.01em; }
.value p { margin: 0; color: var(--bp-text-2); font-size: .96rem; }

/* ---- The product tour ------------------------------------------------------------------------
   A RADIO GROUP WEARING TABS. The inputs are visually hidden, the <label>s are the visible
   control, and the panel is shown by a sibling selector on :checked — so switching screens needs
   no script at all, which this page's CSP would not allow anyway. Arrow keys, the checked state
   and the "3 of 12" announcement are the browser's, not ours.
   The rules below are GENERATED by build-time string concatenation in the stylesheet's author, one
   per screen, so the markup and the CSS cannot disagree about how many screens there are. */
.tour { border: 0; margin: 0; padding: 0; min-width: 0; }
.tour-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin: 26px 0 22px; }
.tour-tab {
  padding: 8px 15px; border-radius: var(--r-pill); border: 1px solid var(--bp-border);
  background: var(--bp-surface); color: var(--bp-text-2);
  font-size: 13.5px; font-weight: 650; cursor: pointer; user-select: none;
  transition: box-shadow .15s ease, transform .15s ease;
}
.tour-tab:hover { color: var(--bp-text); border-color: var(--bp-control); transform: translateY(-1px); }
.tour-panel { display: none; margin: 0; padding: 10px; border-radius: var(--r-lg); box-shadow: var(--e-plate); }
.tour-panel img { display: block; width: 100%; height: auto; border-radius: 10px; }
.tour-panel figcaption { padding: 14px 8px 6px; color: var(--bp-text-2); font-size: .95rem; max-width: 74ch; }
.tour-panel figcaption strong { color: var(--bp-text); display: block; font-size: 1.05rem; letter-spacing: -.01em; margin-bottom: 4px; }
#tour-0:checked ~ .tour-tabs .tour-tab:nth-child(1) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-1:checked ~ .tour-tabs .tour-tab:nth-child(2) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-2:checked ~ .tour-tabs .tour-tab:nth-child(3) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-3:checked ~ .tour-tabs .tour-tab:nth-child(4) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-4:checked ~ .tour-tabs .tour-tab:nth-child(5) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-5:checked ~ .tour-tabs .tour-tab:nth-child(6) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-6:checked ~ .tour-tabs .tour-tab:nth-child(7) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-7:checked ~ .tour-tabs .tour-tab:nth-child(8) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-8:checked ~ .tour-tabs .tour-tab:nth-child(9) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-9:checked ~ .tour-tabs .tour-tab:nth-child(10) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-10:checked ~ .tour-tabs .tour-tab:nth-child(11) { background: var(--bp-primary); color: var(--bp-on-primary); border-color: transparent; }
#tour-0:checked ~ .tour-panels .tour-panel:nth-child(1) { display: block; }
#tour-1:checked ~ .tour-panels .tour-panel:nth-child(2) { display: block; }
#tour-2:checked ~ .tour-panels .tour-panel:nth-child(3) { display: block; }
#tour-3:checked ~ .tour-panels .tour-panel:nth-child(4) { display: block; }
#tour-4:checked ~ .tour-panels .tour-panel:nth-child(5) { display: block; }
#tour-5:checked ~ .tour-panels .tour-panel:nth-child(6) { display: block; }
#tour-6:checked ~ .tour-panels .tour-panel:nth-child(7) { display: block; }
#tour-7:checked ~ .tour-panels .tour-panel:nth-child(8) { display: block; }
#tour-8:checked ~ .tour-panels .tour-panel:nth-child(9) { display: block; }
#tour-9:checked ~ .tour-panels .tour-panel:nth-child(10) { display: block; }
#tour-10:checked ~ .tour-panels .tour-panel:nth-child(11) { display: block; }
#tour-0:focus-visible ~ .tour-tabs .tour-tab:nth-child(1) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-1:focus-visible ~ .tour-tabs .tour-tab:nth-child(2) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-2:focus-visible ~ .tour-tabs .tour-tab:nth-child(3) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-3:focus-visible ~ .tour-tabs .tour-tab:nth-child(4) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-4:focus-visible ~ .tour-tabs .tour-tab:nth-child(5) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-5:focus-visible ~ .tour-tabs .tour-tab:nth-child(6) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-6:focus-visible ~ .tour-tabs .tour-tab:nth-child(7) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-7:focus-visible ~ .tour-tabs .tour-tab:nth-child(8) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-8:focus-visible ~ .tour-tabs .tour-tab:nth-child(9) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-9:focus-visible ~ .tour-tabs .tour-tab:nth-child(10) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
#tour-10:focus-visible ~ .tour-tabs .tour-tab:nth-child(11) { outline: 2px solid var(--bp-focus); outline-offset: 2px; }

/* ---- The thirteen areas, now with their one-line blurb ---------------------------------------
   THIRTEEN NAMES, NOT THIRTEEN SECTIONS. The full index with its bullets lives on /product/; the
   overview says what the areas ARE and lets the reader choose. Numbered with counters rather than
   markup so the number is presentation and the list stays an ordered list to a screen reader.

   ONE RULE SET, AND NOTHING HERE MAY BE WIDER THAN ITS COLUMN (found by review, 2026-09-23). This
   file used to carry a SECOND, older `.areas` block further down — names only, a one-line flex row,
   230px tracks. Being lower, it won the cascade, and it put the blurb BESIDE the name in a row whose
   items cannot shrink below their longest word. Wherever the grid came out with columns near 230px
   (536–592px, 794–878px and 1052–1142px on the Polish home; 320px and 794–938px on the German one)
   that row was wider than its column and the whole page panned sideways. A check at 375px was green,
   because at 375px there is one wide column. Hence:
   · the track minimum is `min(320px, 100%)`, so one column never exceeds a 320px phone's content box;
   · the link's text column is `minmax(0, 1fr)`, so the blurb wraps inside its column instead of
     sizing the column to its longest word — and a word longer than the column breaks rather than
     sticking out. tests/unit/public-site-fits-a-phone.test.ts sweeps every page at every width. */
.areas {
  list-style: none; margin: 28px 0 0; padding: 0; counter-reset: area;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); gap: 2px 28px;
}
.areas li { counter-increment: area; border-top: 1px solid var(--bp-border); min-width: 0; }
.areas a {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 12px; padding: 14px 8px 14px 2px;
  color: var(--bp-text); text-decoration: none; border-radius: var(--r); overflow-wrap: break-word;
  transition: background .15s ease;
}
.areas a::before {
  content: counter(area, decimal-leading-zero); grid-row: 1 / 3;
  color: var(--bp-muted); font-variant-numeric: tabular-nums; font-size: 12px; font-weight: 700;
  padding-top: 3px;
}
.area-t { font-weight: 660; }
.area-b { color: var(--bp-text-2); font-size: .9rem; }
.areas a:hover { background: var(--bp-sunk); }
.areas a:hover .area-t { color: var(--bp-link); }

/* ---- The plan comparison table ----------------------------------------------------------------
   THE WRAP IS THE CONTAINING BLOCK, and that is what keeps the page from scrolling sideways. The
   table is wider than a phone and scrolls inside `.compare-wrap`, but every cell carries a
   visually-hidden `.vh` span, and `.vh` is `position: absolute`. An absolutely positioned box is
   clipped by an overflow ancestor only when that ancestor is (or contains) its containing block — the
   wrap was neither, so the spans in the last column escaped its clip and stretched the DOCUMENT: at
   375px the Polish home measured 443px wide, and the whole page panned sideways under a thumb
   (found by review, 2026-09-23). `position: relative` makes the wrap the containing block; at desktop
   widths it moves nothing, because nothing here is offset. */
.compare-wrap { overflow-x: auto; margin: 26px 0 34px; position: relative; }
.compare { border-collapse: collapse; width: 100%; min-width: 30rem; font-size: .95rem; }
.compare th, .compare td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--bp-border); }
.compare thead th { font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--bp-muted); }
.compare thead th + th, .compare td { text-align: center; width: 8.5rem; }
.compare tbody th { font-weight: 560; color: var(--bp-text); }
.compare tbody tr { transition: background .15s ease; }
.compare tbody tr:hover { background: var(--bp-sunk); }
.compare .yes .tick { color: var(--bp-ok); }
.compare .no { color: var(--bp-muted); }
/* ON A PHONE THE TABLE FITS rather than scrolling inside its wrap: 30rem is wider than any phone's
   column, and a comparison you have to pan to read is a comparison you read one column of. The two
   plan columns narrow and the feature names wrap. Only below 560px — the desktop table is unchanged. */
@media (max-width: 560px) {
  .compare { min-width: 0; font-size: .9rem; }
  .compare th, .compare td { padding: 10px 8px; }
  .compare thead th + th, .compare td { width: 5.5rem; }
}

/* ---- FAQ -------------------------------------------------------------------------------------- */
.faq { margin-top: 26px; max-width: 74ch; }
.qa { border-bottom: 1px solid var(--bp-border); }
.qa summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 16px 2px; cursor: pointer; font-weight: 640; list-style: none;
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary:hover { color: var(--bp-link); }
.qa summary .chev { flex: none; transition: transform .18s ease; }
.qa[open] summary .chev { transform: rotate(180deg); }
.qa p { margin: 0 0 18px; color: var(--bp-text-2); max-width: 70ch; }

/* ---- The closing call to action ---------------------------------------------------------------- */
.cta .wrap { text-align: center; }
.cta .lead { margin-inline: auto; }
.cta .more { justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  .value, .tour-tab, .areas a, .compare tbody tr, .qa summary .chev { transition: none; }
  .value:hover, .tour-tab:hover { transform: none; }
}

/* ---- Theme-matched screenshots ---------------------------------------------------------------
   THE PICTURE OF THE PRODUCT MATCHES THE THEME THE READER IS IN. Every shot is captured twice from
   the same signed-in session and the page shows one of the pair.

   THREE STATES, NOT TWO, and that is why this is CSS and not a <picture> element. The reader's
   choice is "light", "dark", or the default "follow the system" — and the default stamps NO
   attribute on :root at all. A <picture> with a prefers-color-scheme <source> can see the system
   preference but is blind to the data-theme the picker writes, so a reader who chose light on a
   dark machine would get the dark screenshot inside a light page. The rules below answer all
   three: the bare default is light, the media query flips it only when no explicit light choice
   has been made, and the two data-theme blocks come last so an explicit choice wins outright.

   Both halves are in the markup, so both are fetched. That is the cost of having no server-side
   theme and no inline script (the CSP forbids one); it buys a page that is correct on the first
   paint rather than one that swaps a picture after boot. Only the hero pair is eager.

   The hidden half carries alt="" and aria-hidden: it is the SAME picture of the SAME screen, and
   giving both the real alt text would have a screen reader announce every figure twice. */
/* `:root` IN FRONT, AND IT IS THE FIX FOR A DEFECT THE LIVE SITE SHIPPED (found 2026-09-28). The bare
   `.shot-dark { display: none }` is (0,1,0); every figure's own `.hero-shot img`, `.tour-panel img`
   and `.shot img { display: block }` is (0,1,1) and won — so in the light theme, the default, every
   screenshot on the home and product pages was drawn twice, the light one and the dark one under it.
   The markup test could not see it; tests/unit/public-site-media-and-pages.test.ts now measures it in
   a browser for every kind of figure, in both themes. */
:root .shot-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .shot-light { display: none; }
  :root:not([data-theme="light"]) .shot-dark { display: block; }
}
:root[data-theme="light"] .shot-light { display: block; }
:root[data-theme="light"] .shot-dark { display: none; }
:root[data-theme="dark"] .shot-light { display: none; }
:root[data-theme="dark"] .shot-dark { display: block; }

/* ---- The links into the branches --------------------------------------------------------------
   (The overview's area list is styled ONCE, under "The thirteen areas" above.) */

/* The link OUT of a summary and into the page that holds the detail. */
.more { margin-top: 30px; display: flex; gap: 12px; flex-wrap: wrap; }

.shots { display: grid; gap: 40px; margin-top: 32px; }
.shot { margin: 0; }
.shot img {
  display: block; width: 100%; height: auto; max-width: 880px;
  border-radius: var(--r); box-shadow: var(--e-card); background: var(--bp-surface);
}
.shot figcaption { color: var(--bp-text-2); font-size: .93rem; margin-top: 14px; max-width: 68ch; }
.shot figcaption strong { color: var(--bp-text); display: block; font-size: 1.02rem; letter-spacing: -.01em; }

/* ---- Pricing --------------------------------------------------------------------------------- */
.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: 20px; margin-top: 30px; max-width: 820px; }
.plan { background: var(--bp-surface); border-radius: var(--r); padding: 24px; box-shadow: var(--e-card); }
.plan h3 { font-size: 1.05rem; margin-bottom: .2em; }
.plan .amt { font-size: 2rem; font-weight: 800; color: var(--bp-text); margin: .18em 0 .1em; font-variant-numeric: tabular-nums; letter-spacing: -.03em; }
.plan .amt[data-state="pending"], .plan .amt[data-state="unavailable"] { font-size: .95rem; font-weight: 600; color: var(--bp-muted); letter-spacing: 0; }
.plan .tax { color: var(--bp-muted); font-size: .82rem; margin: 0 0 1em; }
.plan p:last-child { margin-bottom: 0; color: var(--bp-text-2); font-size: .94rem; }
/* The one-time top-up: an ADD-ON, not a third tier. A customer must not read it as an alternative to
   a subscription, because credits are spendable only on an AI-capable seat. */
.plan.topup { grid-column: 1 / -1; background: var(--bp-highlight); box-shadow: var(--e-ring); }
.plan.topup h3, .plan.topup .amt { color: var(--bp-on-highlight); }
.topup-tag {
  display: inline-block; margin: 0 0 .5em; padding: 2px 10px; border-radius: var(--r-pill);
  background: var(--bp-plum); color: #F8F3F6; font-size: 11px; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase;
}
.fine { color: var(--bp-muted); font-size: 13px; margin-top: 16px; max-width: 70ch; }
.band-shell .fine { color: var(--bp-shell-2); }

/* ---- Security (reverse-printed) -------------------------------------------------------------- */
.sec { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 26px; margin-top: 30px; }
.sec article { border-inline-start: 2px solid var(--bp-lemon); padding-inline-start: 18px; }
.sec h3 { color: var(--bp-on-shell); }
.sec p { color: var(--bp-shell-2); font-size: .95rem; margin: 0; }

/* ---- Contact --------------------------------------------------------------------------------- */
form { max-width: 560px; margin-top: 26px; display: grid; gap: 4px; }
label { font-weight: 650; font-size: 14px; margin-top: 12px; }
input, textarea {
  font: inherit; padding: 11px 13px; border-radius: var(--r-sm);
  /* AN ESSENTIAL OUTLINE, NOT A DECORATIVE DIVIDER. `--bp-border` is 1.3:1 and the kit says in as
     many words that it must not be used as an input outline; `--bp-control` is 3.67:1. The previous
     stylesheet used the divider here. */
  border: 1px solid var(--bp-control);
  background: var(--bp-surface); color: var(--bp-text); width: 100%;
}
input:focus-visible, textarea:focus-visible { outline: 2px solid var(--bp-focus); outline-offset: 2px; }
form .btn { justify-self: start; margin-top: 18px; }
.note { min-height: 1.4em; font-size: 14px; margin-top: 12px; font-weight: 600; }
.note[data-tone="ok"] { color: var(--bp-ok); }
.note[data-tone="err"] { color: var(--bp-danger); }

/* ---- Colophon -------------------------------------------------------------------------------- */
.foot { color: var(--bp-shell-2); }
.foot :focus-visible { outline-color: var(--bp-shell-focus); box-shadow: 0 0 0 4px var(--bp-shell); }
.foot-in { max-width: var(--maxw); margin: 0 auto; padding: 40px var(--gut) 56px; display: grid; gap: 18px; font-size: 13px; }
.foot nav { display: flex; gap: 18px; flex-wrap: wrap; }
.foot a { color: var(--bp-on-shell); text-decoration: none; }
.foot a:hover { color: var(--bp-shell-focus); text-decoration: underline; }

/* ---- The colophon's language picker ---------------------------------------------------------
   THE SAME DROP-DOWN AS THE HEADER'S, not a row of five links: the owner's rule is that languages
   are chosen from a drop-down, never listed side by side. Three things differ, and each is a defect
   the header's rules would otherwise produce down here:
   1. IT OPENS UPWARD, anchored to its own start edge. It is the last control on the page; a menu
      that drops down opens below the final pixel, and one anchored to the END edge (as the header's
      is, under a right-aligned button) hangs off the left of a phone screen from a left-aligned one.
   2. ITS LINKS TAKE THE MENU'S COLOURS. `.foot a` comes later than `.pick-menu a` at the same
      specificity, so without this the items would be painted in the shell's near-white on the
      menu's white surface — present, focusable, and invisible in the light theme.
   3. `.foot nav` makes every nav in the colophon a flex row; this one is a single control and is
      sized to its button. */
.foot .pick-lang { justify-self: start; }
.foot .pick-menu {
  top: auto; bottom: calc(100% + 7px);
  inset-inline-end: auto; inset-inline-start: 0;
}
.foot .pick-menu a, .foot .pick-menu a:hover { color: var(--bp-text); text-decoration: none; }
.foot .pick-menu a[aria-current="true"] { color: var(--bp-on-highlight); }
/* The chevron points the way the menu opens. */
.foot .pick > summary .chev { transform: rotate(180deg); }
.foot .pick[open] > summary .chev { transform: none; }
/* THE RING INSIDE A MENU IS THE PAGE'S, NOT THE SHELL'S. The shell's lemon ring exists because the
   page's blue is 2.00:1 on plum; inside the menu the ground is the page's own surface, where lemon is
   1.27:1 on white — a focus indicator nobody can see. That was true of the header's menu as well. */
.crust .pick-menu :focus-visible, .foot .pick-menu :focus-visible { outline-color: var(--bp-focus); box-shadow: none; }

/* ================================================================================================
   THE VIDEOS, AND THE AI AND HELP PAGES (ADR-US-071, 2026-09-28).
   ================================================================================================ */

/* ---- One video: the browser's own player, its caption, its transcript --------------------------
   The frame reserves 16:9 before the poster arrives, so nothing below it moves as the page loads.
   The letterbox is the shell's plum, in both themes — a recording of the product sits on the
   product's own ground. NOTHING HERE ANIMATES: the page never plays a video, and the only motion is
   what the reader starts. */
.clips {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(360px, 100%), 1fr));
  gap: 34px 26px; margin-top: 30px;
}
@media (min-width: 900px) {
  .clips { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .clips > .clip:first-child { grid-column: 1 / -1; }
}
.clip { margin: 0; min-width: 0; }
.clip-frame {
  display: block; width: 100%; height: auto; aspect-ratio: 16 / 9;
  border-radius: var(--r); background: var(--bp-shell); box-shadow: var(--e-card);
}
.clip figcaption { margin-top: 12px; }
.clip-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin: 0 0 4px; }
.clip-head strong { font-size: 1.05rem; letter-spacing: -.01em; color: var(--bp-text); }
.clip-len {
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--bp-text-2);
  border: 1px solid var(--bp-control); border-radius: var(--r-pill); padding: 0 8px; line-height: 1.6;
}
.clip-blurb { color: var(--bp-text-2); font-size: .95rem; margin: 0 0 6px; max-width: 70ch; }
/* THE AI-VOICE LINE IS PLAIN TEXT AT READING CONTRAST, not fine print: it is the disclosure the
   provider's policy and the AI Act ask for, and it sits on the sunk band where `--bp-muted` would
   fall under 4.5:1. */
.clip-ai { color: var(--bp-text-2); font-size: 13px; font-weight: 600; margin: 0 0 6px; }
.clip-tx > summary {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer; list-style: none;
  color: var(--bp-link); font-size: 13.5px; font-weight: 650; padding: 4px 0;
}
.clip-tx > summary::-webkit-details-marker { display: none; }
.clip-tx > summary::marker { content: ''; }
.clip-tx > summary:hover { color: var(--bp-link-hover); }
.clip-tx[open] > summary .chev { transform: rotate(180deg); }
.clip-tx-body {
  margin-top: 8px; padding: 14px 16px; border-radius: var(--r-sm);
  background: var(--bp-surface); box-shadow: var(--e-ring);
  color: var(--bp-text); font-size: .92rem; max-width: 74ch;
}
.clip-tx-body p { margin: 0 0 .7em; }
.clip-tx-body p:last-child { margin-bottom: 0; }
.tx-who { font-weight: 700; }
/* A preview build's placeholder (SITE_MEDIA_PREVIEW=1). A published page never carries one. */
.clip-soon {
  display: grid; place-items: center; aspect-ratio: 16 / 9; border-radius: var(--r);
  background: var(--bp-surface); border: 1px dashed var(--bp-control); color: var(--bp-text-2);
}
.clip-soon p { margin: 0; font-weight: 650; }
.clip-compact .clip-head strong { font-size: .98rem; }
.clip-compact .clip-blurb { font-size: .9rem; }

/* ---- The AI and Help pages: a hero, a table of contents, then one band per deep dive ---------- */
.page-hero { padding-block: 64px 52px; }
.page-hero h1 { max-width: 24ch; }
.page-hero .lead { max-width: 68ch; }
.page-hero .ctas { margin-top: 26px; }
.page-hero .note { color: var(--bp-text-2); font-size: 13.5px; font-weight: 500; max-width: 68ch; min-height: 0; }
.toc ol {
  list-style: none; counter-reset: toc; margin: 34px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr)); gap: 10px 16px;
}
.toc li { counter-increment: toc; min-width: 0; }
.toc a {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px; align-items: baseline;
  padding: 11px 14px; border-radius: var(--r); background: var(--bp-surface); box-shadow: var(--e-ring);
  color: var(--bp-text); text-decoration: none; font-weight: 620; font-size: .95rem; overflow-wrap: break-word;
  transition: box-shadow .15s ease;
}
.toc a::before {
  content: counter(toc, decimal-leading-zero); color: var(--bp-muted);
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.toc a:hover { box-shadow: var(--e-card); color: var(--bp-link); }
.deep { padding-block: 66px; }
.deep-in { display: grid; gap: 30px 46px; align-items: start; }
.deep-in.has-media { grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); }
@media (max-width: 900px) { .deep-in.has-media { grid-template-columns: minmax(0, 1fr); } }
.deep-text { min-width: 0; }
.deep-n { color: var(--bp-muted); font-size: 13px; font-weight: 800; letter-spacing: .08em; font-variant-numeric: tabular-nums; margin: 0 0 8px; }
.band-sunk .deep-n { color: var(--bp-text-2); }
.deep-media { display: grid; gap: 26px; min-width: 0; }
.deep-media .shot img { max-width: 100%; }
.checks { list-style: none; margin: 20px 0 0; padding: 0; display: grid; gap: 11px; }
.checks li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 11px; align-items: baseline; color: var(--bp-text); font-size: .98rem; }
.checks .tick { color: var(--bp-primary); position: relative; top: 2px; }
.asks-h { margin: 30px 0 12px; font-size: 1rem; }
.asks { margin: 0; display: grid; gap: 8px; }
.asks > div {
  display: grid; grid-template-columns: minmax(7rem, 11rem) minmax(0, 1fr); gap: 2px 16px;
  padding: 10px 14px; border-radius: var(--r-sm); background: var(--bp-surface); box-shadow: var(--e-ring);
}
.asks dt { font-weight: 700; font-size: 13px; color: var(--bp-text-2); padding-top: 2px; }
.asks dd { margin: 0; color: var(--bp-text); overflow-wrap: break-word; }
@media (max-width: 560px) { .asks > div { grid-template-columns: minmax(0, 1fr); } }
.chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.chips li {
  padding: 5px 12px; border-radius: var(--r-pill); background: var(--bp-surface); box-shadow: var(--e-ring);
  font-size: 13.5px; font-weight: 600; color: var(--bp-text); overflow-wrap: anywhere;
}
/* The product page's tile details, three reports side by side and one per row on a phone. */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); gap: 30px 26px; margin-top: 38px; }
.tile-shot img { max-width: 100%; }
@media (prefers-reduced-motion: reduce) {
  .toc a { transition: none; }
}

/* ---- The hover kit (site.kit.js): one light source -----------------------------------------------
   EYE CANDY THE OWNER ASKED FOR (2026-09-28). A soft berry light follows the pointer and the page's
   objects catch it: a card brightens under it and its edge glints nearest it; a screenshot plate
   leans toward it and its glass takes a sheen; the primary button's fill takes the light; a price
   card's edge turns a beam toward a pointer that comes within 300px. The script writes the numbers
   (custom properties, a transform, one class); these rules draw them.

   AT REST THE PAGE IS STILL THE PAGE THE HEADER DESCRIBES, WITH NO GRADIENT ON IT. Every rule below
   waits for `data-kit="live"` on the root AND `.fx-lit` on the element, which the script sets only
   while that element is lit and takes away when it is dark again. While they are on, the lights ARE
   gradients: the one departure from "There is no gradient on this page" the owner is asked to approve
   (with the ASCII object's "depth is not decoration"). On a touch screen, where no pointer exists, a
   card is lit while it crosses the middle of the screen. There is no lemon here: its budget stands.

   CONTRAST IS ARITHMETIC, NOT TASTE. A tint under text is capped at the mix where the weakest text on
   that ground still passes AA:
     light: surface (cards)    berry 7%  -> muted 4.72, text-2 5.52   (8% would be 4.63; 10% fails)
            canvas (rows)      berry 4%  -> muted 4.63                (6% is 4.49: fails)
            highlight (top-up) berry 3%  -> muted 4.70
     dark:  surface / canvas   pink 10%  -> muted 5.16 / 5.78
            highlight          pink 2%   -> muted 4.64                (4% is 4.50: too close)
   Edge glints and beams sit on the 1px border and carry no text. The button's light is a blend of
   --bp-primary and --bp-primary-hover, the two fills its label is already checked against; a button
   that is pressed or disabled takes no light at all (its own fill is the message).
   The numbers the script writes are plain custom properties: registered non-inherited (@property),
   the price cards' style work measured SLOWER at 4x CPU (0.61 against 0.47 ms a frame). */
:root { --fx-tint: 7%; --fx-tint-canvas: 4%; --fx-tint-hl: 3%; --fx-glare: rgb(255 255 255 / .30); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --fx-tint: 10%; --fx-tint-canvas: 10%; --fx-tint-hl: 2%; --fx-glare: rgb(255 255 255 / .13); }
}
:root[data-theme="dark"] { --fx-tint: 10%; --fx-tint-canvas: 10%; --fx-tint-hl: 2%; --fx-glare: rgb(255 255 255 / .13); }

/* 1. Lit surfaces: the tint under the pointer, and the edge nearest it. */
:root[data-kit="live"] .fx-lit:is(.value, .plan, .toc a, .asks > div, .areas a) {
  background-image: radial-gradient(var(--fx-r, 380px) circle at var(--fx-x, 50%) var(--fx-y, 50%),
    color-mix(in srgb, var(--bp-primary) calc(var(--fx-t, var(--fx-tint)) * var(--fx-on, 0)), transparent), transparent);
}
:root[data-kit="live"] .areas a { --fx-t: var(--fx-tint-canvas); --fx-r: 300px; }
:root[data-kit="live"] .plan.topup { --fx-t: var(--fx-tint-hl); }
/* The row's own hover ground is --bp-sunk; under a berry tint that is muted text at 4.3:1. The light
   replaces the ground rather than stacking on it. */
:root[data-kit="live"] .areas a:hover { background-color: transparent; }
:root[data-kit="live"] .fx-lit:is(.value, .plan, .toc a, .asks > div) { position: relative; }
:root[data-kit="live"] .fx-lit:is(.value, .plan, .toc a, .asks > div)::after {
  content: ""; position: absolute; inset: -1px; padding: var(--fx-edge, 1px); border-radius: inherit; pointer-events: none;
  background: radial-gradient(220px circle at calc(var(--fx-x, 50%) + 1px) calc(var(--fx-y, 50%) + 1px),
    color-mix(in srgb, var(--bp-primary) calc(100% * var(--fx-on, 0)), transparent), transparent);
  /* The ring: the whole box minus its content box, i.e. exactly the edge. */
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}

/* 2. The price cards' edge: a beam that turns to face the pointer. --fx-a is where it points (0deg
   up, clockwise, as a conic gradient counts), --fx-b how bright it is; both are absent at rest, so
   the card at rest is the card. `.plans >` outranks the ring rule above, whose :is() counts as its
   heaviest part. */
:root[data-kit="live"] .plan { --fx-edge: 1.5px; }
:root[data-kit="live"] .plans > .plan.fx-lit::after {
  background:
    radial-gradient(220px circle at calc(var(--fx-x, 50%) + 1px) calc(var(--fx-y, 50%) + 1px),
      color-mix(in srgb, var(--bp-primary) calc(100% * var(--fx-on, 0)), transparent), transparent),
    conic-gradient(from calc(var(--fx-a, 315deg) - 70deg), transparent 0deg,
      color-mix(in srgb, var(--bp-primary) calc(100% * var(--fx-b, 0)), transparent) 70deg, transparent 140deg, transparent 360deg);
}

/* 3. Screenshot plates: the glass's sheen (the lean itself is the script's transform). A highlight
   where the light is and a faint plum shade toward the far side: on a light screenshot a white
   highlight alone is white on white; the shade says where the light is.
   THE SHEEN IS MOVED, NOT REPAINTED: painted once at twice the plate's size, then only translated
   and faded (compositor work); the plate clips it, and its padding keeps the clip from moving
   anything. NO TRANSITIONS: restarted by every write, they restyled or repainted the plate on every
   frame (+1 ms a frame at 4x CPU), so the hover shadow is instant.
   THE WORDS STAY ABOVE IT: a white sheen over a caption's grey line measured 3.1:1, so a lit plate's
   caption paints above it, and a pointer ON the caption lays the plate flat and dark (the script). */
:root[data-kit="live"] :is(.hero-shot, .tour-panel, .idx-shot):hover { box-shadow: var(--e-plate), 0 42px 80px -44px rgb(46 32 42 / .55); }
:root[data-kit="live"] .fx-lit:is(.hero-shot, .tour-panel, .idx-shot) { position: relative; overflow: hidden; }
:root[data-kit="live"] .fx-lit:is(.hero-shot, .tour-panel) figcaption { position: relative; z-index: 1; }
:root[data-kit="live"] .fx-lit:is(.hero-shot, .tour-panel, .idx-shot)::after {
  content: ""; position: absolute; left: 0; top: 0; width: 200%; height: 200%; pointer-events: none;
  background:
    radial-gradient(27.5% 37.5% at 50% 50%, var(--fx-glare), transparent 72%),
    radial-gradient(closest-side, transparent 55%, rgb(46 32 42 / .07));
  transform: translate(calc(var(--fx-x, 25%) - 50%), calc(var(--fx-y, 0%) - 50%));
  opacity: var(--fx-on, 0);
  will-change: transform, opacity;
}

/* 4. The primary button's light: its centre is the LIGHTER of the two fills and its edge the darker,
   whichever theme and ground it is on — berry is lighter than its hover on the light page; on the
   dark page and on the plum shell (which pins the dark ramp in both themes) the hover pink is. The
   button itself never moves. Pressed or disabled (the contact form while it sends) it shows its own
   fill: the light outranked both, and put a disabled button's muted label at 1.4:1. */
:root[data-kit="live"] .btn-primary { --fx-spot: var(--bp-primary); --fx-rim: var(--bp-primary-hover); }
@media (prefers-color-scheme: dark) {
  :root[data-kit="live"]:not([data-theme="light"]) .btn-primary { --fx-spot: var(--bp-primary-hover); --fx-rim: var(--bp-primary); }
}
:root[data-kit="live"][data-theme="dark"] .btn-primary,
:root[data-kit="live"] :is(.crust, .band-shell) .btn-primary { --fx-spot: var(--bp-primary-hover); --fx-rim: var(--bp-primary); }
:root[data-kit="live"] .btn-primary:not(:disabled):not(:active):hover {
  background-image: radial-gradient(120px circle at var(--fx-x, 50%) var(--fx-y, 50%), var(--fx-spot), var(--fx-rim));
}
/* Printed, in forced colours or with more contrast asked for: no light (the script stands still too),
   and a plate printed under a resting pointer prints flat (!important outranks the inline lean). */
@media print, (forced-colors: active), (prefers-contrast: more) { .fx-lit::after { display: none; } }
@media print { :root[data-kit="live"] :is(.hero-shot, .tour-panel, .idx-shot) { transform: none !important; will-change: auto !important; } }
