  /* Fonts are self-hosted: the page is also the demonstration that nothing is fetched
     from a third party. Same files and licences as the app (app/public/fonts). */
  @font-face { font-family: "Inter"; src: url("/fonts/InterVariable-latin.woff2") format("woff2-variations"); font-weight: 100 900; font-style: normal; font-display: swap; }
  @font-face { font-family: "IBM Plex Mono"; src: url("/fonts/IBMPlexMono-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
  @font-face { font-family: "IBM Plex Mono"; src: url("/fonts/IBMPlexMono-Medium.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }

  /* ── Tokens, verbatim from docs/DESIGN-SYSTEM.md §2 ─────────────────────────── */
  :root {
    /* ── Colour, light ─────────────────────────────────────────────────────── */
    --ground: #f2f2f2;        /* the window; every card sits on it            */
    --card: #ffffff;          /* the surface you read and act on              */
    --ink: #111111;           /* text, filled buttons, selected marks         */
    --ink-2: #3a3a3a;         /* body text on white, secondary labels         */
    --muted: #6b6b6b;         /* captions, meta, placeholders (4.6:1 on ground)*/
    --rule: #e4e4e4;          /* hairline dividers inside a card              */
    --hover: #ededed;         /* row and ghost-button hover fill              */
    --pressed: #e0e0e0;       /* the same, pressed                            */
    --on-ink: #ffffff;        /* text on an ink fill                          */

    /* The three colours that mean something.                                  */
    --recording: #d94f2b;     /* only while audio is being captured           */
    --on-recording: #ffffff;
    --offline: #2e7d46;       /* only the offline / on-this-machine indicator */
    --on-offline: #ffffff;
    --highlight: #ffd21e;     /* one yellow chip: "look here", never a state  */
    --on-highlight: #111111;

    /* ── Radius ───────────────────────────────────────────────────────────── */
    --r-chip: 8px;            /* tags, keycaps, the update badge               */
    --r-control: 12px;        /* buttons, fields, selects, the toggle track    */
    --r-card: 20px;           /* cards in windows ≤ 460 px wide                */
    --r-card-lg: 28px;        /* cards in the meetings window and the website  */
    --r-pill: 999px;          /* status chips, the timer pill, the dictation   */
                              /* overlay, the collapsed recorder               */

    /* ── Spacing, 4 px base ───────────────────────────────────────────────── */
    --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 20px;
    --s-6: 24px; --s-7: 28px; --s-8: 32px; --s-10: 40px; --s-12: 48px;
    --card-pad: var(--s-5);   /* inside a card, narrow windows                 */
    --card-pad-lg: var(--s-7);/* inside a card, meetings window and website    */
    --window-pad: var(--s-4); /* between the window edge and the first card    */

    /* ── Type ─────────────────────────────────────────────────────────────── */
    --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
    --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    --t-display: 600 32px/1.1 var(--font);   /* website hero only; -0.02em     */
    --t-title:   600 22px/1.25 var(--font);  /* window titles; -0.015em        */
    --t-heading: 600 17px/1.3 var(--font);   /* card titles; -0.01em           */
    --t-body:    400 15px/1.5 var(--font);   /* everything you read            */
    --t-body-sm: 400 13px/1.45 var(--font);  /* captions under a row title     */
    --t-label:   500 15px/1 var(--font);     /* buttons, row titles, chips     */
    --t-meta:    500 11px/1 var(--font);     /* +0.1em, uppercase, --muted     */
    --t-code:    400 13px/1.5 var(--mono);   /* timecodes, paths, keycaps      */
    --t-clock:   500 20px/1 var(--mono);     /* the recorder bar clock; tabular*/

    /* ── Shadow ───────────────────────────────────────────────────────────── */
    --shadow: none;           /* flat; floating windows use the native shadow  */

    /* ── Motion ───────────────────────────────────────────────────────────── */
    --dur-fast: 120ms;        /* hover, pressed, colour                        */
    --dur: 200ms;             /* toggle, segmented control, window arrival     */
    --dur-slow: 320ms;        /* the recorder folding, a card expanding        */
    --ease: cubic-bezier(0.2, 0, 0, 1);        /* the default; settles fast    */
    --ease-out: cubic-bezier(0.2, 0.7, 0.3, 1);/* arrivals only                */

    color-scheme: light dark;
    color: var(--ink);
    background: var(--ground);
    font: var(--t-body);
    font-synthesis: none;
    -webkit-font-smoothing: antialiased;
  }

  @media (prefers-color-scheme: dark) {
    :root {
      --ground: #0e0e0e;
      --card: #1b1b1b;
      --ink: #f2f2f2;
      --ink-2: #c9c9c9;
      --muted: #9a9a9a;        /* 5.4:1 on --card                              */
      --rule: #2c2c2c;
      --hover: #262626;
      --pressed: #303030;
      --on-ink: #111111;

      --recording: #ff6a45;    /* lifted so the square glyph reads on it       */
      --on-recording: #111111;
      --offline: #6ac98a;
      --on-offline: #111111;
      --highlight: #ffd24d;
      --on-highlight: #111111;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    :root { --dur-fast: 0ms; --dur: 0ms; --dur-slow: 0ms; }
  }

  /* ── Base ───────────────────────────────────────────────────────────────── */
  *, *::before, *::after { box-sizing: border-box; }
  html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
  @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
  body {
    margin: 0; background: var(--ground); color: var(--ink);
    /* The app reads --t-body at 15 px inside a 340 px window; a page is read at arm's
       length and by every age, so body copy here is one step up. Everything else keeps
       the token sizes. */
    font: var(--t-body); font-size: 16px; line-height: 1.55;
    overflow-x: hidden;
  }
  img { max-width: 100%; height: auto; display: block; }
  a { color: inherit; }
  p { margin: 0; }
  h1, h2, h3 { margin: 0; color: var(--ink); }
  h1 { font: var(--t-display); letter-spacing: -.02em; text-wrap: balance; }
  h2 { font: var(--t-title); letter-spacing: -.02em; text-wrap: balance; }
  h3 { font: var(--t-heading); letter-spacing: -.01em; }
  code, kbd { font: var(--t-code); }
  code { background: var(--hover); border-radius: var(--r-chip); padding: 1px 6px; color: var(--ink); }
  :focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: var(--r-control); }

  .skip {
    position: absolute; left: var(--s-4); top: -100px; z-index: 10;
    background: var(--ink); color: var(--on-ink); padding: 10px 16px;
    border-radius: var(--r-control); font: var(--t-label); text-decoration: none;
  }
  .skip:focus { top: var(--s-4); }

  /* One column, 1040 wide: three cards of 320 with two 40 px gutters, or one measure of
     about 65 characters at 18 px with room either side. Wider and the eye has to travel. */
  .wrap { width: 100%; max-width: 1040px; margin: 0 auto; padding: 0 var(--s-5); }
  @media (min-width: 720px) { .wrap { padding: 0 var(--s-8); } }
  /* Running text never exceeds a comfortable measure, whatever the card around it does. */
  p, li, dd, figcaption, .answer { max-width: 66ch; }

  /* ── Card ───────────────────────────────────────────────────────────────── */
  .card {
    background: var(--card); border-radius: var(--r-card-lg);
    padding: var(--s-6); box-shadow: var(--shadow);
  }
  @media (min-width: 720px) { .card { padding: var(--s-10); } }
  .card > * + * { margin-top: var(--s-3); }
  .card p, .card li { color: var(--ink-2); }
  .card ul { margin: var(--s-3) 0 0; padding-left: 1.2em; }
  .card li + li { margin-top: var(--s-2); }
  .stack { display: grid; gap: var(--s-4); }
  /* Cards in one row share its height; each row takes only the height its own cards need.
     Every row at the height of the tallest card left 300 px of white under the German text. */
  .cols-2 { display: grid; gap: var(--s-4); grid-template-columns: 1fr; }
  .cols-3 { display: grid; gap: var(--s-4); grid-template-columns: 1fr; }
  .cols-4 { display: grid; gap: var(--s-4); grid-template-columns: 1fr; }
  @media (min-width: 720px) {
    .cols-2 { grid-template-columns: 1fr 1fr; }
    .cols-3 { grid-template-columns: repeat(3, 1fr); }
    .cols-4 { grid-template-columns: 1fr 1fr; }
  }
  @media (min-width: 1024px) { .cols-4 { grid-template-columns: repeat(4, 1fr); } }

  /* ── Sections ───────────────────────────────────────────────────────────── */
  /* 64 px between ideas on a phone, 96 on a laptop: enough that scrolling from one section
     to the next feels like turning a page rather than reading a list. */
  section { padding: 64px 0 0; }
  section:last-of-type { padding-bottom: 64px; }
  @media (min-width: 720px) { section { padding-top: 96px; } section:last-of-type { padding-bottom: 96px; } }
  .section-head { margin-bottom: var(--s-8); max-width: 640px; }
  .section-head > * + * { margin-top: var(--s-3); }
  .section-head .sub { color: var(--ink-2); font-size: 17px; }
  @media (min-width: 720px) { h2 { font-size: 32px; line-height: 1.15; } }
  .meta {
    display: block; font: var(--t-meta); letter-spacing: .1em; text-transform: uppercase;
    color: var(--muted);
  }

  /* ── Buttons ────────────────────────────────────────────────────────────── */
  .btn {
    display: inline-flex; align-items: center; justify-content: center;
    height: 40px; padding: 0 var(--s-5); border: 0; border-radius: var(--r-control);
    font: var(--t-label); text-decoration: none; cursor: pointer; white-space: nowrap;
    transition: background-color var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease);
  }
  .btn-primary { background: var(--ink); color: var(--on-ink); }
  .btn-primary:hover { opacity: .85; }
  .btn-primary:active { opacity: .75; }
  .btn-secondary { background: var(--hover); color: var(--ink); }
  .btn-secondary:hover { background: var(--pressed); }
  .btn-secondary:active { background: var(--rule); }
  .btn-ghost { background: none; color: var(--ink-2); }
  .btn-ghost:hover { background: var(--hover); }
  .btn-ghost:active { background: var(--pressed); }
  .actions { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; }

  /* ── Chips ──────────────────────────────────────────────────────────────── */
  .chip {
    display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 var(--s-3);
    border-radius: var(--r-pill); font: var(--t-label); font-size: 13px; white-space: nowrap;
    vertical-align: middle;
  }
  .chip svg { width: 16px; height: 16px; flex: none; }
  .chip-offline { background: var(--offline); color: var(--on-offline); }
  .chip-highlight { background: var(--highlight); color: var(--on-highlight); }
  .chip-neutral { background: var(--hover); color: var(--ink); }
  kbd.chip { height: 24px; padding: 0 var(--s-2); font: var(--t-code); font-weight: 500; }

  .num {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 32px; height: 32px; border-radius: 50%; background: var(--ink); color: var(--on-ink);
    font: var(--t-label);
  }

  /* ── Header ─────────────────────────────────────────────────────────────── */
  .site-header { padding: var(--s-4) 0; border-bottom: 1px solid var(--rule); }
  .header-inner { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
  .brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; margin-right: auto; }
  .mark { width: 28px; height: 28px; flex: none; }
  .wordmark { font: var(--t-label); font-weight: 600; font-size: 17px; color: var(--ink); }
  .site-nav { display: flex; flex-wrap: wrap; gap: var(--s-1); align-items: center; }
  .site-nav .btn-ghost { height: 36px; padding: 0 var(--s-3); color: var(--muted); font-weight: 500; }
  .site-nav .btn-ghost:hover { color: var(--ink); }
  @media (max-width: 719px) {
    .site-nav { width: 100%; order: 3; }
    .site-nav .btn-ghost { font-size: 14px; padding: 0 var(--s-2); }
  }

  /* ── Hero ───────────────────────────────────────────────────────────────── */
  /* No card: the ground is the hero. Centred copy, then the meetings window at a size the
     column cannot hold, ending in a fade to the ground rather than on a hard cut — the
     transcript inside it scrolls, so the window has no natural bottom to show. */
  .hero { padding-top: 64px; overflow: hidden; }
  .hero-copy { text-align: center; }
  .hero-copy > * + * { margin-top: var(--s-5); }
  .hero-copy h1 { max-width: 20ch; margin-left: auto; margin-right: auto; }
  .hero-copy .lead { font-size: 18px; line-height: 1.55; color: var(--ink-2); max-width: 52ch; margin-left: auto; margin-right: auto; }
  .hero-copy .actions { justify-content: center; margin-top: var(--s-8); }
  /* Centred blocks must escape the 66ch measure cap on paragraphs, or they centre inside a
     left-flush box and land off-centre. */
  .hero-note { margin-top: 0; max-width: none; }
  .hero-copy p { margin-left: auto; margin-right: auto; }
  .hero-shot { margin-top: 64px; margin-bottom: 0; }
  .hero-shot figcaption { font: var(--t-body-sm); color: var(--muted); text-align: center; margin: var(--s-4) auto 0; max-width: 60ch; }
  .hero-shot img {
    width: 100%; height: auto; display: block; margin: 0 auto;
    border-radius: var(--r-card-lg) var(--r-card-lg) 0 0;
    -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
  }
  .hero-page { padding-top: var(--s-8); }
  .hero-page .hero-copy { text-align: left; max-width: 720px; }
  .hero-page .hero-copy h1, .hero-page .hero-copy .lead { margin-left: 0; }
  .hero-page + section { padding-top: 64px; }
  @media (min-width: 720px) {
    .hero { padding-top: 96px; }
    .hero-shot { margin-top: 80px; }
    /* Wider than the column on purpose. Auto margins cannot centre a box that overflows
       its container, so the image is shifted by half its own width instead. */
    .hero-shot img { width: min(1120px, 108vw); margin-left: 50%; transform: translateX(-50%); }
    h1 { font-size: 40px; line-height: 1.08; letter-spacing: -.025em; }
  }
  @media (min-width: 960px) { h1 { font-size: 48px; } }
  @media (min-width: 1100px) { h1 { font-size: 56px; letter-spacing: -.03em; } .hero-page h1 { font-size: 48px; } }

  /* ── Benefits ───────────────────────────────────────────────────────────── */
  /* A title and a few sentences, nothing else. The glyph circles and then the numbers that
     led each card were more things to look at before the first word, and said nothing the
     title did not. A title takes the lines it needs: two reserved for every title left a
     blank line under each short one. */
  .benefit h3 + p { margin-top: var(--s-2); }
  @media (min-width: 720px) { .cols-3 .card { padding: var(--s-8); } }
  .benefit .chip { margin-top: var(--s-2); }
  .card.wide { grid-column: 1 / -1; }

  /* ── The ink band ───────────────────────────────────────────────────────── */
  .band { background: var(--ink); color: var(--on-ink); padding-bottom: 96px; margin-top: 96px; }
  .band .section-head { max-width: 720px; }
  .band h2, .band .meta { color: var(--on-ink); }
  .band .meta { opacity: .6; }
  .band-p { font-size: 20px; line-height: 1.55; max-width: 60ch; color: var(--on-ink); opacity: .85; }
  .band code { background: rgba(127, 127, 127, .25); color: inherit; }
  .band + section { padding-top: 96px; }
  @media (max-width: 719px) { .band { padding-bottom: 64px; margin-top: 64px; } .band-p { font-size: 17px; } }

  /* ── Steps ──────────────────────────────────────────────────────────────── */
  .step { display: flex; gap: var(--s-4); align-items: flex-start; }
  .step > * + * { margin-top: 0; }
  .step h3 + p { margin-top: var(--s-1); }

  /* ── Screens ────────────────────────────────────────────────────────────── */
  .screens { display: grid; gap: var(--s-6) var(--s-3); grid-template-columns: 1fr; }
  @media (min-width: 720px) { .screens { grid-template-columns: 1fr 1fr; } }
  .screens .wide { grid-column: 1 / -1; }
  figure.screen { margin: 0; }
  figure.screen img { margin: 0 auto; }
  figure.screen figcaption { font: var(--t-body-sm); color: var(--muted); margin-top: var(--s-3); max-width: 560px; }
  figure.screen figcaption strong { color: var(--ink); font-weight: 600; }
  .shot-settings img { width: 340px; }
  .shot-setup img { width: 380px; }
  .shot-welcome img { width: 460px; }
  .shot-recorder img { width: 560px; }
  .shot-dictation img { width: 420px; }
  figure.screen.start img { margin-left: 0; }
  /* Two captures keep the app's opaque window ground to their edge; the page rounds them
     so they read as cards like the rest. */
  .shot-meetings img, .shot-welcome img { border-radius: var(--r-card); }
  .modes-shot { margin-top: var(--s-4); }
  .card p, .card li, .card dd, .answer { overflow-wrap: anywhere; }

  /* ── Table ──────────────────────────────────────────────────────────────── */
  .table-wrap { overflow-x: auto; margin: 0 calc(-1 * var(--s-6)); padding: 0 var(--s-6); }
  @media (min-width: 720px) { .table-wrap { margin: 0 calc(-1 * var(--s-10)); padding: 0 var(--s-10); } }
  table.compare { width: 100%; border-collapse: collapse; min-width: 560px; }
  table.compare th, table.compare td { text-align: left; vertical-align: top; padding: var(--s-4) var(--s-4) var(--s-4) 0; }
  table.compare thead th { font: var(--t-meta); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); padding-top: 0; }
  table.compare tbody th { font: var(--t-label); line-height: 1.4; color: var(--ink); width: 30%; }
  table.compare tbody td { color: var(--ink-2); }
  table.compare tbody tr { border-top: 1px solid var(--rule); }

  /* ── List rows ──────────────────────────────────────────────────────────── */
  .rows { padding-top: 0; padding-bottom: 0; }
  .rows > * + * { margin-top: 0; }
  .row { padding: var(--s-5) 0; border-top: 1px solid var(--rule); }
  .row:first-child { border-top: 0; }
  .facts { margin: 0; }
  .facts dt { font: var(--t-label); line-height: 1.4; color: var(--ink); }
  .facts dd { margin: var(--s-1) 0 0; color: var(--ink-2); }

  /* ── Figures band ───────────────────────────────────────────────────────── */
  .stats { display: grid; gap: var(--s-4); grid-template-columns: 1fr 1fr; }
  @media (min-width: 720px) { .stats { grid-template-columns: repeat(4, 1fr); } }
  .stat-figure { font: var(--t-display); letter-spacing: -.02em; color: var(--ink); font-variant-numeric: tabular-nums; }
  .stat-caption { font: var(--t-body-sm); color: var(--muted); margin-top: var(--s-2); }

  /* ── Download ───────────────────────────────────────────────────────────── */
  /* Every card in a grid is a column; whatever comes after its text — a button, a note —
     is pushed to the bottom so the rows of buttons line up across the grid. */
  .cols-2 > .card, .cols-3 > .card, .cols-4 > .card { display: flex; flex-direction: column; }
  .cols-2 > .card > .btn, .cols-3 > .card > .btn, .cols-4 > .card > .btn,
  .cols-2 > .card > .actions, .cols-3 > .card > .actions { margin-top: auto; align-self: flex-start; }
  /* The gap above a pinned button lives on the element before it, so the button's own
     auto margin can collapse to zero in the tallest card without the two touching. */
  .card > :has(+ .btn), .card > :has(+ .actions) { padding-bottom: var(--s-5); }
  .dl .req { font: var(--t-code); color: var(--muted); }
  .dl .note { font: var(--t-body-sm); color: var(--muted); }
  .dl .note strong { color: var(--ink); font-weight: 600; }
  .after { color: var(--ink-2); margin-top: var(--s-6); }

  /* ── FAQ ────────────────────────────────────────────────────────────────── */
  details { border-top: 1px solid var(--rule); }
  details:first-child { border-top: 0; }
  summary {
    cursor: pointer; list-style: none; display: flex; align-items: center; gap: var(--s-3);
    padding: var(--s-5) 0; font: var(--t-label); font-size: 16px; line-height: 1.4; color: var(--ink);
    min-height: 56px;
  }
  summary::-webkit-details-marker { display: none; }
  summary::after {
    content: ""; flex: none; margin-left: auto; width: 16px; height: 16px;
    background: currentColor; color: var(--muted);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform var(--dur) var(--ease);
  }
  details[open] summary::after { transform: rotate(180deg); }
  .answer { padding: 0 0 var(--s-5); color: var(--ink-2); }

  /* ── Raised sections ────────────────────────────────────────────────────── */
  /* Every section on one grey, told apart only by 96 px of air, read as one long run (owner,
     2026-11-05). So the home page alternates the ground with the card colour, edge to edge, and
     a card inside takes the ground: the same two surfaces, swapped. Screenshots cannot go here,
     they are cut on the ground grey (tools/gallery.py). */
  .raised { background: var(--card); padding-bottom: 96px; margin-top: 96px; }
  .raised .card { background: var(--ground); box-shadow: none; }
  .raised input, .raised textarea { background: var(--card); }
  .raised + section { padding-top: 96px; }
  @media (max-width: 719px) { .raised { padding-bottom: 64px; margin-top: 64px; } .raised + section { padding-top: 64px; } }
  main:has(> .raised:last-child) + .site-footer { margin-top: 0; border-top: 0; }

  /* ── Contact ────────────────────────────────────────────────────────────── */
  /* Flush left like every section above it; only the hero is centred. */
  #contact .card, #kontakt .card { max-width: 640px; }
  .contact-form { display: grid; gap: var(--s-4); }
  .field { display: grid; gap: var(--s-2); }
  .field label { font: var(--t-label); color: var(--ink); }
  input, textarea {
    width: 100%; border: 0; border-radius: var(--r-control); background: var(--hover);
    color: var(--ink); font: var(--t-body); font-size: 16px; padding: 0 var(--s-4);
  }
  input { height: 44px; }
  textarea { min-height: 140px; padding: var(--s-3) var(--s-4); resize: vertical; }
  input::placeholder, textarea::placeholder { color: var(--muted); }
  .contact-form .btn { justify-self: start; }

  /* ── Footer ─────────────────────────────────────────────────────────────── */
  .site-footer { padding: var(--s-10) 0 64px; border-top: 1px solid var(--rule); margin-top: var(--s-8); }
  .footer-inner { display: grid; gap: var(--s-6) var(--s-8); grid-template-columns: 1fr; font: var(--t-body-sm); color: var(--muted); }
  @media (min-width: 720px) { .footer-inner { grid-template-columns: auto 1fr; align-items: start; } .footer-inner .colophon { grid-column: 2; } }
  .footer-inner .brand { margin-right: 0; }
  /* One run of short links that wraps where the line ends. Columns sized to the longest
     link left gaps on a laptop and pushed past the edge of a phone. */
  .footer-inner nav { display: flex; flex-wrap: wrap; gap: 0 var(--s-5); }
  .footer-inner .btn-ghost { height: 32px; padding: 0; font: var(--t-body-sm); color: var(--muted); justify-content: flex-start; }
  .footer-inner .btn-ghost:hover { background: none; color: var(--ink); }

  /* ── Content pages ──────────────────────────────────────────────────────── */
  .crumbs { display: flex; flex-wrap: wrap; gap: var(--s-2); font: var(--t-body-sm); color: var(--muted); margin-bottom: var(--s-4); }
  .crumbs a { color: var(--muted); }
  .prose h2 { margin-top: 0; }
  .prose p + p, .prose ul + p, .prose p + ul { margin-top: var(--s-3); }
  .prose ul { margin: 0; padding-left: 1.2em; }
  .prose li + li { margin-top: var(--s-2); }
  .prose pre { margin: var(--s-3) 0 0; padding: var(--s-4); background: var(--hover); border-radius: var(--r-control); font: var(--t-code); overflow-x: auto; color: var(--ink); }
  .prose pre code { background: none; padding: 0; }
  .cta { display: flex; flex-wrap: wrap; gap: var(--s-6); align-items: center; justify-content: space-between; }
  .cta > * + * { margin-top: 0; }
  .cta h2 + p { margin-top: var(--s-2); }
  .cta p { max-width: 560px; }
  .lang { font: var(--t-body-sm); }
  table.plain { width: 100%; min-width: 520px; border-collapse: collapse; }
  table.plain th, table.plain td { text-align: left; vertical-align: top; padding: var(--s-3) var(--s-3) var(--s-3) 0; }
  table.plain th { white-space: nowrap; }
  table.plain thead th { font: var(--t-meta); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); padding-top: 0; }
  table.plain tbody th { font: var(--t-label); line-height: 1.4; color: var(--ink); }
  table.plain tbody td { color: var(--ink-2); }
  table.plain tbody tr { border-top: 1px solid var(--rule); }
  table.compare { min-width: 860px; table-layout: fixed; }
  /* Whole words in the narrow columns: automatic hyphenation split "because" after "be". */
  table.compare th, table.compare td { font-size: 14px; white-space: normal; hyphens: manual; overflow-wrap: break-word; }
  /* On a phone the table scrolls sideways; the row names stay put, so the scroll shows. */
  @media (max-width: 719px) {
    table.compare tbody th, table.compare thead th:first-child { position: sticky; left: 0; z-index: 1; background: var(--card); box-shadow: 8px 0 8px -8px rgba(0, 0, 0, .15); }
  }
  table.compare tbody th { width: 16%; }
  table.compare tbody td:first-of-type { color: var(--ink); font-weight: 500; }
  .placeholder { background: var(--highlight); color: var(--on-highlight); padding: 0 4px; border-radius: 4px; }

  /* ── Gallery: tabs, then the 16:10 frame, then its caption, straight on the page. The
     frames come from tools/gallery.py in the page ground colour, so the window in each
     floats on the page itself; a white card around them made a frame in a frame. */
  .gallery { margin-top: 0; }
  .gallery > * + * { margin-top: 0; }
  .gallery-head { display: flex; align-items: flex-start; gap: var(--s-4); margin-bottom: var(--s-4); }
  .gallery-tabs { display: flex; flex-wrap: wrap; gap: var(--s-1); }
  .gallery-tabs [role="tab"] { height: 36px; padding: 0 var(--s-3); font-size: 14px; color: var(--muted); background: none; }
  .gallery-tabs [role="tab"]:hover { background: var(--hover); color: var(--ink); }
  .gallery-tabs [role="tab"][aria-selected="true"] { background: var(--ink); color: var(--on-ink); }
  .gallery figure { margin: 0; }
  .gallery img { width: 100%; height: auto; aspect-ratio: 16 / 10; border-radius: var(--r-card); background: var(--ground); }
  .gallery figcaption { font: var(--t-body-sm); color: var(--muted); padding-top: var(--s-3); }
  .gallery-nav { display: flex; gap: var(--s-2); margin-left: auto; flex: none; }
  .gallery-nav .btn { width: 36px; height: 36px; padding: 0; }
  .gallery-nav .btn svg { width: 16px; height: 16px; }
  @media (max-width: 719px) { .gallery-nav { display: none; } }
  .gallery.js [role="tabpanel"][hidden] { display: none; }
  .gallery:not(.js) .gallery-head { display: none; }
  .gallery:not(.js) figure + figure { margin-top: var(--s-6); }
  /* The Transcribe page on the home page (1.0): one frame on the page, as in the gallery. */
  .files-shot { margin: 0; }
  .files-shot img { display: block; width: 100%; height: auto; border-radius: var(--r-card); background: var(--ground); }
  .hero-screen { margin: 0; }
  .hero-screen img { border-radius: var(--r-card-lg); }
  .hero-screen figcaption { font: var(--t-body); font-size: 16px; color: var(--ink-2); margin-top: var(--s-4); }
