
  /* Light only. The site has its own palette, drawn from British railway
     heritage rather than the app's chrome: Rail Blue for structure, the
     loco-front warning yellow as the flash, signal red and green as the
     semantic pair, blood-and-custard on the coaches, BR totem region colours
     for categories. The logo is unchanged. */
  :root {
    color-scheme: light;
    /* Washed, like enamel and paint that have been out in the weather. Every
       hue is pulled toward grey; the hero ground is a darker rail grey-blue. */
    --paper: #f7f6f1;
    --surface: #ffffff;
    --chrome: #eceff3;
    --border: #d2d8e0;
    --border-strong: #96a2b2;
    --ink: #1b2a3f;
    --muted: #5a6a80;
    --label: #66748a;
    --blue: #34567f;           /* faded Rail Blue: structure, primary action */
    --blue-deep: #243d5e;      /* the band, the footer */
    --on-blue: #ffffff;
    --yellow: #e6c35e;         /* faded warning-panel yellow: the flash. Fills only; ink text on it */
    --on-yellow: #1b2a3f;
    --red: #c2453f;            /* weathered signal red */
    --red-text: #a63a34;
    --green: #3e8a5e;          /* weathered signal green: graphics */
    --green-text: #2e6e4a;
    --crimson: #8e3a45;        /* faded blood */
    --cream: #f1e6c8;          /* custard */
    --rail: #8a95a4;
    --sleeper: #c4b59f;
    --bp-board: #3a5375;       /* hero ground: a proper blueprint: muted dark blue, white lines */
    --bp-rail: #93a6b5;
    --bp-sleeper: #cfd9e2;
    --bp-edge: #a5b3c2;
    --bp-grid: rgba(255, 255, 255, 0.13);
    --band-muted: #c3d0e0;
    --wire-pos: #c2453f;
    --wire-neg: #46525f;
    --shadow: rgba(27, 42, 63, 0.14);
    --shadow-strong: rgba(27, 42, 63, 0.28);
    --display: "Barlow Condensed", "Arial Narrow", Impact, sans-serif;
    --sans: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;
    --mono: "IBM Plex Mono", Consolas, "Courier New", monospace;
    --cabin: "Cabin", "Gill Sans", "Gill Sans MT", "Trebuchet MS", sans-serif;
  }

  * { box-sizing: border-box; }
  body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--sans);
    font-size: 17px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
  }
  h1, h2, h3, h4, p { margin: 0; }
  a { color: var(--blue); text-decoration: none; }
  a:hover { text-decoration: underline; }
  :focus-visible { outline: 2px solid var(--border-strong); outline-offset: 3px; }
  .wrap { max-width: 1160px; margin: 0 auto; padding: 0 32px; }
  .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
  .display { font-family: var(--display); font-weight: 800; text-transform: uppercase; letter-spacing: 0.01em; line-height: 0.95; }

  /* ---------- the totem: the BR station sign, used as every section header ----------
     The classic shape is a wide pill with a narrower rounded "flash" above and
     below, a cream rim, cream Gill-style capitals, and two brass screws. The
     flashes are the pseudo-elements; each carries its own rim on three sides and
     none on the side that meets the pill, so the outline reads as one silhouette.
     Region colours as on the real signs. Cream on the page ground is nearly
     invisible (1.2:1), so the whole sign gets a soft shadow, like enamel on a wall. */
  .totem {
    --tf: #1d4f91;
    --rim: 3px; --flash: 9px;
    position: relative; z-index: 0; display: inline-flex; align-items: center; justify-content: center;
    margin: var(--flash) 0;
    padding: 8px 36px; border: var(--rim) solid transparent; border-radius: 999px;
    color: var(--cream);
    font-family: "Cabin", "Gill Sans", "Gill Sans MT", "Trebuchet MS", sans-serif; font-weight: 700; font-size: 21px; line-height: 1;
    letter-spacing: 0.05em; text-transform: uppercase; white-space: nowrap;
    filter: drop-shadow(0 1.5px 2px rgba(16, 30, 51, .38));
  }
  /* As on the real sign: the centre bar is a complete outlined pill sitting in
     FRONT of a taller outlined lobe. Both are pseudo-elements stacked under the
     text (negative z-index inside the totem's own stacking context), so the
     bar's rim runs unbroken top and bottom and the lobe shows above and below. */
  .totem::after {
    content: ""; position: absolute; z-index: -1; inset: calc(-1 * var(--rim));
    border: var(--rim) solid var(--cream); border-radius: 999px;
    background:
      radial-gradient(circle at 16px 50%, #e2b45c 0 3px, #a87a2a 3.6px, transparent 4.6px),
      radial-gradient(circle at calc(100% - 16px) 50%, #e2b45c 0 3px, #a87a2a 3.6px, transparent 4.6px),
      var(--tf);
  }
  .totem::before {
    content: ""; position: absolute; z-index: -2; left: 15%; right: 15%;
    top: calc(-1 * (var(--flash) + var(--rim))); bottom: calc(-1 * (var(--flash) + var(--rim)));
    background: var(--tf); border: var(--rim) solid var(--cream); border-radius: 14px;
  }
  .totem.eastern { --tf: #2b4a7d; }
  .totem.southern { --tf: #2a7a4d; }   /* cream on this is 4.2:1: large signs only */
  .totem.black { --tf: #2a2a2a; }
  .totem.western { --tf: #63482f; }
  .totem.maroon { --tf: #8e3a45; }
  .totem.scottish { --tf: #335c85; }
  .totem.ne { --tf: #94511f; }
  .totem.mini {
    --rim: 2px; --flash: 5px;
    padding: 4px 16px; font-size: 13px; letter-spacing: .08em;
  }
  .totem.mini::after { background: var(--tf); } /* too small for screws */
  .totem.mini::before { border-radius: 9px; }

  /* the tank engine that pulls a totem into place */
  /* arrives from the right, engine first, and tows the sign into place */
  .title-train { display: inline-flex; align-items: center; gap: 0; opacity: 0; transform: translateX(36px); transition: opacity .7s ease, transform .9s cubic-bezier(.2, .8, .2, 1); }
  .title-train.in { opacity: 1; transform: none; }
  .title-train svg { height: 46px; width: auto; display: block; flex-shrink: 0; }
  .title-train .coupler { width: 14px; height: 4px; background: var(--ink); border-radius: 2px; flex-shrink: 0; }

  /* ---------- buttons ---------- */
  /* ---------- buttons are tickets: notched ends, a perforated stub, punched on hover ----------
     Cream is the everyday ticket, yellow the paid/primary one, blue the structural one.
     The notches are a mask, which also clips anything painted outside the box: so
     no outer shadows, and the focus ring is an inset one. */
  .btn {
    --rim: #cbb98d; --stub: #b9a87e; --punch: var(--ink);
    position: relative; display: inline-flex; align-items: center; gap: 10px;
    padding: 14px 24px 14px 42px; border-radius: 5px; border: 0;
    background: var(--cream); color: var(--ink);
    font-family: var(--cabin); font-weight: 700; font-size: 14px; letter-spacing: .035em; text-transform: uppercase; line-height: 1;
    cursor: pointer; text-decoration: none; white-space: nowrap;
    box-shadow: inset 0 0 0 1.5px var(--rim);
    -webkit-mask: radial-gradient(circle at 0 50%, transparent 6px, #000 6.6px), radial-gradient(circle at 100% 50%, transparent 6px, #000 6.6px); -webkit-mask-composite: source-in;
    mask: radial-gradient(circle at 0 50%, transparent 6px, #000 6.6px), radial-gradient(circle at 100% 50%, transparent 6px, #000 6.6px); mask-composite: intersect;
    transition: transform .15s ease, background .2s ease, color .2s ease;
  }
  .btn::before { content: ""; position: absolute; left: 29px; top: 7px; bottom: 7px; border-left: 2px dashed var(--stub); }
  .btn::after { content: ""; position: absolute; left: 13px; top: 50%; width: 8px; height: 8px; border-radius: 50%; transform: translateY(-50%); border: 1.5px solid var(--stub); transition: background .15s ease, border-color .15s ease; }
  .btn:hover { text-decoration: none; transform: translateY(-1px) rotate(-.6deg); }
  .btn:hover::after { background: var(--punch); border-color: var(--punch); }
  .btn:focus-visible { outline: 0; box-shadow: inset 0 0 0 3px var(--blue); }
  .btn-yellow { background: var(--yellow); color: var(--ink); --rim: #b8973a; --stub: #8a6f22; }
  .btn-primary { background: var(--blue); color: var(--cream); --rim: #1f3a5c; --stub: rgba(241, 230, 200, .55); --punch: var(--cream); }
  .btn-primary:focus-visible { box-shadow: inset 0 0 0 3px var(--yellow); }
  .btn-ghost, .btn-light, .btn-paper { background: var(--cream); color: var(--ink); }

  /* ---------- nav ---------- */
  .nav { border-bottom: 1px solid var(--border); background: var(--paper); position: sticky; top: 0; z-index: 10; }
  .nav .wrap { height: 72px; display: flex; align-items: center; justify-content: space-between; gap: 32px; }
  .brand { display: flex; align-items: center; gap: 10px; color: var(--blue); font-family: var(--display); font-weight: 800; font-size: 26px; letter-spacing: .06em; text-transform: uppercase; }
  /* the real lockup; its white ground multiplies away against the bar */
  .nav .brand img { height: 54px; width: auto; display: block; mix-blend-mode: multiply; }
  .nav-links { display: flex; align-items: center; gap: 28px; font-size: 15px; }
  .nav-links a { color: var(--ink); }
  .nav-links .btn { padding: 10px 16px 10px 34px; font-size: 11.5px; }
  .nav-links .btn::before { left: 24px; top: 6px; bottom: 6px; }
  .nav-links .btn::after { left: 11px; width: 7px; height: 7px; }
  /* the platform marks on the download buttons: the Windows mark, and the penguin on the Linux button and beside the
     Windows mark on the header ticket, which goes to the fares page where both downloads are (Mike, 2026-10-31) */
  .btn .win { width: 1.15em; height: 1.15em; flex: none; margin: -1px 0; }
  .nav-links .btn { gap: 8px; }
  /* a platform that is not out yet: the grey .is-off ticket, faded, with a "Coming soon" sticker stuck over its corner. It
     is a disabled <button>, not a link, so nothing can be downloaded from it. (Mike, 2026-10-26: "we dont want that
     available yet". When a platform ships as a preview it goes back to an ordinary ticket with a sticker and a
     link to /download?os=...) The class keeps its old name. Linux went live as a beta on 2026-10-31: an ordinary
     ticket with a "Beta Build" sticker (Mike: "the linux buttons on the website must show 'Beta Build' sticker").
     The sticker is a sibling, not a child: .btn is masked and would clip it. */
  .soon { position: relative; display: block; container-type: inline-size; }
  .soon .btn { display: flex; width: 100%; }
  .soon .btn.is-off { opacity: .6; }
  .sticker {
    position: absolute; right: 8px; top: 50%; transform: translateY(-50%) rotate(4deg); pointer-events: none;
    width: min-content; text-align: center;
    padding: 4px 7px 3px; border-radius: 3px; background: var(--yellow); color: var(--ink);
    font-family: var(--cabin); font-weight: 700; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; line-height: 1.15;
    box-shadow: inset 0 0 0 1.5px #b8973a, 0 1px 2px rgba(27, 42, 63, .25);
  }
  /* "Coming soon" breaks onto two lines so the sticker stays narrow enough to sit centred on the button without covering
     its label. When the button itself is narrower than about 300px (most phones) even that is too wide, so the sticker
     goes back up onto the corner. It is measured against the button, not the screen, because the ticket's width varies. */
  @container (max-width: 305px) {
    .sticker { top: -10px; transform: rotate(4deg); width: max-content; line-height: 1; padding: 5px 9px 4px; }
  }

  /* ---------- intro video: a poster until clicked ---------- */
  .watch { padding: 96px 0 24px; }
  .watch .line-head { margin-bottom: 32px; }
  .watch h2 { font-size: clamp(44px, 5.2vw, 72px); color: var(--ink); text-wrap: balance; }
  .watch .vid, .watch iframe { display: block; width: 100%; max-width: 960px; aspect-ratio: 16 / 9; border-radius: 14px; }
  .watch .vid { position: relative; overflow: hidden; border: 2px solid var(--border-strong, #96a2b2); background: var(--blue-deep); }
  .watch .vid img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .25s ease; }
  .watch .vid:hover img { transform: scale(1.015); }
  .watch .vid:focus-visible { outline: 3px solid var(--blue); outline-offset: 3px; }
  .watch iframe { border: 0; }
  .watch .watch-note { max-width: 62ch; margin-top: 20px; font-size: 17px; color: var(--muted); }
  .watch .vid .play { position: absolute; left: 50%; top: 50%; width: 88px; height: 62px; margin: -31px 0 0 -44px; display: flex; align-items: center; justify-content: center; border-radius: 14px; background: var(--yellow); color: var(--ink); box-shadow: inset 0 0 0 2px #b8973a, 0 3px 10px rgba(27, 42, 63, .35); transition: transform .15s ease; }
  .watch .vid .play svg { width: 34px; height: 34px; margin-left: 3px; }
  .watch .vid:hover .play { transform: scale(1.08); }

  /* ---------- mobile menu: the burger (nav.js opens it) ---------- */
  .nav-toggle { display: none; flex: none; width: 44px; height: 44px; margin: 0; padding: 0; flex-direction: column; align-items: center; justify-content: center; gap: 5px; background: transparent; border: 0; border-radius: 8px; cursor: pointer; }
  .nav-toggle span { display: block; width: 20px; height: 2px; border-radius: 1px; background: var(--ink); transition: transform .2s ease, opacity .15s ease; }
  .nav-toggle:hover { background: var(--chrome); }
  .nav-toggle:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
  .nav.open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav.open .nav-toggle span:nth-child(2) { opacity: 0; }
  .nav.open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
  .nav-menu { display: none; }
  .nav-menu a { display: block; padding: 16px 24px; font-size: 17px; color: var(--ink); border-top: 1px solid var(--border); }
  .nav-menu a:first-child { border-top: 0; }
  .nav-menu a.active, .nav-menu a[aria-current="page"] { color: var(--blue); font-weight: 600; box-shadow: inset 4px 0 0 var(--yellow); }
  @media (max-width: 900px) {
    .nav .wrap { gap: 10px; padding-left: 16px; padding-right: 16px; }
    .nav-links { margin-left: auto; }
    .nav.has-toggle .nav-toggle { display: inline-flex; }
    .nav.has-toggle.open .nav-menu { display: block; position: absolute; top: 100%; left: 0; right: 0; background: var(--paper); border-bottom: 1px solid var(--border); }
  }
  @media (max-width: 420px) {
    .nav .brand img { height: 42px; }
    .nav-links .btn { padding: 10px 12px 10px 30px; }
    .nav-links .btn::before { left: 21px; }
    .nav-links .btn::after { left: 9px; }
  }
  /* the tightest phones: the logo, the ticket and the burger have to share about 290px */
  @media (max-width: 380px) {
    .nav-links .btn .win { display: none; }
  }
  @media (max-width: 340px) {
    .nav .wrap { gap: 6px; }
    .nav .brand img { height: 38px; }
    .nav-links .btn { font-size: 10.5px; padding-right: 10px; }
  }
  @media (prefers-reduced-motion: reduce) { .nav-toggle span { transition: none; } }

  /* ---------- track separators, with a train crossing ---------- */
  /* full-bleed whatever the page is wrapped in: viewport-wide, pulled out to the edges */
  .sep { position: relative; height: 96px; overflow: hidden; width: 100vw; margin-left: calc(50% - 50vw); }
  .sep .track {
    position: absolute; left: 0; right: 0; bottom: 18px; height: 18px;
    background:
      linear-gradient(var(--rail), var(--rail)) 0 4px / 100% 3px no-repeat,
      linear-gradient(var(--rail), var(--rail)) 0 11px / 100% 3px no-repeat,
      repeating-linear-gradient(90deg, var(--sleeper) 0 7px, transparent 7px 22px) 0 1px / 22px 16px repeat-x;
  }
  /* Trains run right-to-left: the locos are drawn chimney-left, and the loco
     sits at x=0 of each composition, so leftward travel puts it at the front. */
  .sep .train { position: absolute; left: 0; bottom: 22px; height: 60px; width: auto; transform: translateX(100vw); will-change: transform; }
  .sep.in .train { animation: cross var(--dur, 18s) linear infinite; animation-delay: var(--delay, 0s); }
  @keyframes cross { from { transform: translateX(100vw); } to { transform: translateX(-110%); } }
  /* Alternate separators run the other way. Mirroring the whole train puts the
     loco at the leading end facing right, and turns the wheels the right way. */
  .sep.rev .train { transform: translateX(-110%) scaleX(-1); }
  .sep.rev.in .train { animation-name: cross-rev; }
  @keyframes cross-rev { from { transform: translateX(-110%) scaleX(-1); } to { transform: translateX(100vw) scaleX(-1); } }
  .sep.on-blue .track {
    background:
      linear-gradient(#5a78a8, #5a78a8) 0 4px / 100% 3px no-repeat,
      linear-gradient(#5a78a8, #5a78a8) 0 11px / 100% 3px no-repeat,
      repeating-linear-gradient(90deg, #2b5a9c 0 7px, transparent 7px 22px) 0 1px / 22px 16px repeat-x;
  }

  /* ---------- hero ---------- */
  /* the hero fills the first screen (less the nav); content centred, track along the bottom */
  .hero {
    position: relative; overflow: hidden;
    min-height: calc(100vh - 72px); display: flex; flex-direction: column;
    background: var(--bp-board);
    background-image:
      linear-gradient(var(--bp-grid) 1px, transparent 1px),
      linear-gradient(90deg, var(--bp-grid) 1px, transparent 1px);
    background-size: 24px 24px;
  }
  .hero .wrap { flex: 1 1 auto; width: 100%; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 48px; align-items: center; padding-top: 72px; padding-bottom: 56px; }
  .hero-copy { display: flex; flex-direction: column; gap: 22px; align-items: flex-start; }
  .made-uk { display: flex; align-items: center; gap: 9px; margin: 0; font-size: 15px; letter-spacing: .02em; color: var(--cream); opacity: .8; }
  .made-uk svg { flex: none; display: block; outline: 1px solid rgba(241,230,200,.35); }
  .hero h1 { font-size: clamp(64px, 8.5vw, 116px); color: var(--cream); text-wrap: balance; }
  /* the highlighter box is a pseudo-element so the frayed wires can sit behind it */
  .hero h1 .hi {
    position: relative; z-index: 0; display: inline-block; color: var(--on-yellow);
    padding: 0 .14em; margin: 0 -.02em; line-height: 0.9;
    transform: rotate(-1.2deg);
  }
  .hero h1 .hi::after { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--yellow); }
  .hero h1 .hi .wires {
    position: absolute; z-index: -2; left: 100%; top: 50%; width: .74em; height: 1.2em;
    margin-left: -.22em; transform: translateY(-50%); transform-origin: 0 50%;
    animation: sway 4.5s ease-in-out infinite;
  }
  @keyframes sway { 0%, 100% { transform: translateY(-50%) rotate(-2deg); } 50% { transform: translateY(-50%) rotate(2.5deg); } }
  @media (prefers-reduced-motion: reduce) { .hero h1 .hi .wires { animation: none; } }
  /* light text on the blueprint ground */
  .hero .lead { font-family: var(--display); font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; font-size: clamp(30px, 3.8vw, 48px); line-height: 1.05; color: var(--cream); max-width: 20ch; text-wrap: balance; }
  .hero .facts { display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 15px; color: #dfe6ee; }
  .hero .facts b { color: #ffffff; font-weight: 500; }
  .hero .facts .sep-dot { color: #8fa3ba; }
  /* .btn-light is the cream ticket; it holds up on the blueprint and the band as-is */
  .plan { position: relative; }
  /* ---------- the layout build-up: the tutorial layout drawn straight on the blueprint ----------
     The sequencer adds p1..p7 in turn (earlier ones stay), then .out to fade, then clears to restart.
     Per-element delays use --i (its place in the running order); phase timing is when the class lands. */
  .build { width: 100%; display: flex; justify-content: center; transition: opacity .7s ease; }
  .build.out { opacity: 0; }
  .build-svg { width: 100%; height: auto; display: block; overflow: visible; filter: drop-shadow(0 6px 18px rgba(0, 0, 0, .28)); }
  .build-svg.portrait { width: auto; max-width: 100%; height: auto; max-height: calc(100vh - 72px - 150px); }

  /* p1 · the edge draws round from the corner */
  .build .edge { stroke-dasharray: 1000; stroke-dashoffset: 1000; }
  .build.p1 .edge { animation: draw 1.6s cubic-bezier(.4, 0, .2, 1) forwards; }
  /* p2 · the fill sweeps across as a soft wave: each line fades in and out, staggered by position */
  .build .hl { opacity: 0; }
  .build.p2 .hl { animation: wave 1s ease-in-out forwards; animation-delay: calc(var(--i) * 24ms); }
  /* p3 · pieces drop on, one after another */
  .build .pc { opacity: 0; transform: translateY(-46px); }
  .build.p3 .pc { animation: drop .32s cubic-bezier(.2, .9, .2, 1) forwards; animation-delay: calc(var(--i) * 85ms); }
  /* p4 · power blocks appear, wires draw */
  .build .pw { opacity: 0; transform: translateY(-46px); }
  .build.p4 .pw { animation: drop .3s cubic-bezier(.2, .9, .2, 1) forwards; animation-delay: calc(var(--i) * 110ms); }
  .build .wire { stroke-dasharray: 1000; stroke-dashoffset: 1000; }
  .build.p4 .wire { animation: draw .38s ease-out forwards; animation-delay: calc(.28s + var(--i) * .17s); }
  .build .wire-end { opacity: 0; }
  .build.p4 .wire-end { animation: appear .15s ease forwards; animation-delay: calc(.6s + var(--i) * .17s); }
  /* p5 · the live line runs round the loop, then pulses */
  .build .power, .build .power-siding { stroke-dasharray: 1000; stroke-dashoffset: 1000; opacity: .95; }
  /* draw round (1.7s), pulse three times, then fade away */
  .build.p5 .power { animation: draw 1.7s linear forwards, pulse .55s ease-in-out 1.7s 3, fadeout .6s ease 3.4s forwards; }
  /* the siding's orange line sets off the moment the green line passes the point (timings from the renderer) */
  .build.p5 .power-siding { animation: draw var(--dur) linear forwards, pulse .55s ease-in-out 3, fadeout .6s ease forwards; animation-delay: var(--at), 1.7s, 3.4s; }
  /* p6 · ballast fades in, scenery drops on */
  .build .b-ballast { opacity: 0; }
  .build.p6 .b-ballast { animation: appear .6s ease forwards; }
  .build .pd { opacity: 0; transform: translateY(-46px); }
  .build.p6 .pd { animation: drop .3s cubic-bezier(.2, .9, .2, 1) forwards; animation-delay: calc(.2s + var(--i) * 70ms); }
  /* p7 · the train appears (its motion is started by the sequencer) */
  .build .b-train { opacity: 0; transition: opacity .5s ease; }
  .build.p7 .b-train { opacity: 1; }
  /* until their motion is running the vehicles sit at the board origin: never show them there */
  .build .veh { visibility: hidden; }
  .build.p7 .veh { visibility: visible; }
  /* in the quarter-turned board a screen "drop" is a local -x move */
  .build-svg.portrait .pc, .build-svg.portrait .pw, .build-svg.portrait .pd { transform: translateX(-46px); }
  .build-svg.portrait .pc, .build-svg.portrait .pw, .build-svg.portrait .pd { animation-name: none; }
  .build.p3 .build-svg.portrait .pc, .build.p4 .build-svg.portrait .pw, .build.p6 .build-svg.portrait .pd { animation-name: drop-x; }

  @keyframes draw { to { stroke-dashoffset: 0; } }
  @keyframes wave { 0% { opacity: 0; } 45% { opacity: 1; } 100% { opacity: 0; } }
  @keyframes drop { from { opacity: 0; transform: translateY(-46px); } to { opacity: 1; transform: none; } }
  @keyframes drop-x { from { opacity: 0; transform: translateX(-46px); } to { opacity: 1; transform: none; } }
  @keyframes appear { from { opacity: 0; } to { opacity: 1; } }
  @keyframes pulse { 0%, 100% { stroke-width: 6; opacity: .95; } 50% { stroke-width: 14; opacity: .55; } }
  @keyframes fadeout { to { opacity: 0; } }
  @media (prefers-reduced-motion: reduce) {
    .build .edge, .build .wire, .build .power, .build .power-siding { stroke-dashoffset: 0 !important; animation: none !important; }
    .build .pc, .build .pw, .build .pd, .build .b-ballast, .build .b-train, .build .wire-end { opacity: 1 !important; transform: none !important; animation: none !important; }
    .build .hl { display: none; }
  }

  /* ---------- inner pages ----------
     Router toggles the native `hidden` attribute; this rule makes that authoritative
     on its own (never rely on a host page's reset for this) rather than leaving
     shown pages to the default `display: block`, which a hidden page also gets
     unless something enforces `[hidden]`: the previous unconditional
     `main[data-page] { display: block }` did exactly that and defeated hidden. */
  main[data-page][hidden] { display: none !important; }
  main[data-page]:not([hidden]) { display: block; }
  .nav-links a.active { color: var(--blue); font-weight: 600; box-shadow: inset 0 -2px 0 var(--yellow); padding-bottom: 2px; }
  .page-hero {
    background: var(--bp-board);
    background-image: linear-gradient(var(--bp-grid) 1px, transparent 1px), linear-gradient(90deg, var(--bp-grid) 1px, transparent 1px);
    background-size: 24px 24px; overflow: hidden;
  }
  .page-hero .wrap { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 48px; align-items: center; padding-top: 80px; padding-bottom: 56px; }
  .page-hero-copy { display: flex; flex-direction: column; gap: 20px; align-items: flex-start; }
  .page-hero h1 { font-size: clamp(48px, 6vw, 84px); color: var(--cream); text-wrap: balance; }
  .page-hero .lead { font-size: 19px; color: #d6dfea; max-width: 46ch; }
  .page-hero .row { display: flex; gap: 12px; flex-wrap: wrap; }
  .page-hero .sep .track {
    background: linear-gradient(#a3b5cb, #a3b5cb) 0 4px / 100% 3px no-repeat, linear-gradient(#a3b5cb, #a3b5cb) 0 11px / 100% 3px no-repeat,
      repeating-linear-gradient(90deg, #5a7392 0 7px, transparent 7px 22px) 0 1px / 22px 16px repeat-x;
  }
  .block { padding: 104px 0; }
  .block.alt { background: var(--chrome); }
  .block.first { padding-top: 80px; }
  .block-head { display: flex; flex-direction: column; gap: 18px; max-width: 760px; margin-bottom: 40px; align-items: flex-start; }
  .block-head.centre { align-items: center; text-align: center; margin-left: auto; margin-right: auto; }
  .block h1.display { font-size: clamp(48px, 6vw, 84px); color: var(--ink); text-wrap: balance; }
  .block h2.display { font-size: clamp(40px, 5vw, 64px); color: var(--ink); text-wrap: balance; }
  .block .lead { font-size: 19px; color: var(--muted); }
  .two { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 56px; align-items: start; }
  .two > div { display: flex; flex-direction: column; gap: 16px; }
  .two p { color: var(--muted); }
  /* feature blocks alternate which side the clip sits on; copy stays first in the DOM for reading order */
  .two.rev { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); }
  .two.rev > :first-child { order: 2; }
  .table { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
  .table .r { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-bottom: 1px solid var(--chrome); }
  .table .r:last-of-type { border-bottom: 0; }
  .table .h { background: var(--chrome); border-bottom: 1px solid var(--border); }
  .table .h > div { font-family: var(--display); font-weight: 700; font-size: 14px; letter-spacing: .12em; text-transform: uppercase; color: var(--label); padding: 12px 18px; }
  .table .c { padding: 14px 18px; font-family: var(--mono); font-size: 15px; font-variant-numeric: tabular-nums; }
  .table .c.g { color: var(--green-text); font-weight: 500; }
  .table .c.m { color: var(--muted); }
  .cat-scale { margin-bottom: 32px; }
  .cat-scale:last-child { margin-bottom: 0; }
  .cat-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 16px; margin-bottom: 12px; }
  .cat-head h3 { font-size: 34px; line-height: 1; margin: 0; }
  .cat-head .mono { font-size: 14px; color: var(--ink); }
  .cat-head .cat-reg { font-size: 14px; color: var(--muted); }
  .table.cat .r { grid-template-columns: minmax(0,1.1fr) minmax(0,1.6fr) minmax(0,.8fr) minmax(7rem,.6fr) minmax(9rem,.7fr); align-items: center; }
  .table.cat .c { font-size: 14.5px; font-family: inherit; }
  .table.cat .c.m, .table.cat .c.g { font-family: var(--mono); }
  .table.cat .c.g { white-space: nowrap; }
  .table.cat .c.t { font-weight: 600; color: var(--ink); }
  .table.cat .tag { font-family: var(--mono); font-size: 12px; color: var(--blue-deep); background: var(--chrome); border: 1px solid var(--border); border-radius: 5px; padding: 3px 8px; white-space: nowrap; }
  @media (max-width: 860px) {
    .table.cat .r.h { display: none; }
    .table.cat .r { grid-template-columns: minmax(0,1fr); padding: 8px 0; }
    .table.cat .c { padding: 3px 18px; }
    .table.cat .c.t { padding-top: 12px; font-size: 17px; }
    .table.cat .c:empty { display: none; }
  }
  .table .note { padding: 14px 18px; background: var(--chrome); border-top: 1px solid var(--border); font-size: 13.5px; color: var(--muted); }
  .warn { display: flex; gap: 14px; align-items: flex-start; background: #f5eedd; border: 1px solid #dfcfa6; border-radius: 12px; padding: 22px 24px; }
  .warn h4 { font-size: 17px; color: #7a5a1e; margin-bottom: 4px; }
  .warn p { font-size: 15px; color: #7a5a1e; }
  .warn p + p { margin-top: 10px; }
  /* The SmartScreen notice is not a warning about LiveRail, it is a heads-up
     that Windows shows a blue box. Blue so the page rhymes with the dialog
     the visitor is about to see. The amber .warn stays for the genuine
     safety disclaimer on the wiring and features pages. */
  .warn.win { background: #e8eef6; border-color: #b9c8db; }
  .warn.win h4, .warn.win p { color: #243d5e; }
  .band.cta .wrap { display: flex; align-items: center; justify-content: space-between; gap: 48px; padding: 88px 32px; }
  .band.cta h2 { font-size: clamp(36px, 4.2vw, 54px); }
  .band.cta p { font-size: 17px; color: var(--band-muted); max-width: 52ch; }
  .band.cta > .wrap > div { display: flex; flex-direction: column; gap: 10px; }
  /* ---------- parked 2026-09-09: the guides index and the one guide article were pulled from the site pending a proper build. The rules below (.filters, .feature, .article and children) style nothing today, and are kept because the markup they dress is kept too, in design/guides-removed-2026-09-09.html ---------- */
  .filters { display: flex; gap: 10px; flex-wrap: wrap; margin: 24px 0 28px; }
  .filters .totem { cursor: pointer; }
  .filters .totem.off { --tf: var(--surface); color: var(--label); }
  .filters .totem.off::after, .filters .totem.off::before { border-color: var(--border-strong); }
  .feature { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); background: var(--surface); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
  .feature .fig { background: var(--bp-board); padding: 28px; display: flex; align-items: center; }
  .feature .fig svg { width: 100%; height: auto; }
  .feature .txt { padding: 36px; display: flex; flex-direction: column; gap: 12px; justify-content: center; align-items: flex-start; }
  .feature h2 { font-size: 30px; font-weight: 600; line-height: 1.15; letter-spacing: -.01em; }
  .feature p { color: var(--muted); }
  .feature .rt { font-family: var(--mono); font-size: 13px; color: var(--label); }
  .article .wrap { max-width: 800px; }
  .article { padding: 48px 0 80px; }
  .article .crumb { font-size: 15px; font-weight: 600; display: inline-block; margin-bottom: 20px; }
  .article h1 { font-size: clamp(34px, 4.5vw, 50px); font-weight: 600; line-height: 1.1; letter-spacing: -.015em; margin: 14px 0 12px; text-wrap: balance; }
  .article .meta { font-family: var(--mono); font-size: 13px; color: var(--label); margin-bottom: 28px; }
  .article .lead { font-size: 20px; color: var(--muted); margin-bottom: 8px; }
  .article p { max-width: 68ch; margin: 0 0 18px; }
  .article h2 { font-size: 26px; font-weight: 600; line-height: 1.2; margin: 40px 0 12px; }
  .article figure { margin: 28px 0; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 20px; }
  .article figure svg { width: 100%; height: auto; display: block; }
  .article figcaption { font-family: var(--mono); font-size: 12.5px; color: var(--label); margin-top: 10px; }
  .article .note { background: var(--chrome); border-left: 4px solid var(--green); border-radius: 0 12px 12px 0; padding: 20px 22px; margin: 36px 0; display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
  .article .note h3 { font-size: 18px; font-weight: 600; }
  .article .note p { margin: 0; font-size: 15.5px; color: var(--muted); }
  .article .related { margin-top: 48px; }
  .article .related h3 { font-family: var(--display); font-weight: 700; font-size: 20px; letter-spacing: .08em; text-transform: uppercase; color: var(--label); margin-bottom: 16px; }
  .votes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .vote { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 26px; display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
  .vote h3 { font-family: var(--display); font-weight: 800; font-size: 36px; letter-spacing: .02em; text-transform: uppercase; line-height: 1; }
  .vote p { font-size: 15px; color: var(--muted); }
  .plan-tag {
    margin-top: auto; font-family: var(--mono); font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
    color: var(--blue-deep); background: var(--chrome); border: 1px solid var(--border); border-radius: 5px; padding: 5px 12px;
  }
  .plan-tag.is-live { color: var(--green-text); background: #eef5f0; border-color: #c2d9cb; }
  .vote-note { margin-top: 20px; font-size: 14px; color: var(--label); display: flex; gap: 8px; align-items: flex-start; }
  .community-block { margin-top: 48px; padding-top: 40px; border-top: 1px solid var(--border); }
  .community-empty { font-size: 14.5px; color: var(--label); margin-top: 4px; }

  .suggest-form { margin-top: 4px; margin-bottom: 24px; display: flex; flex-direction: column; gap: 10px; }
  .suggest-form textarea {
    width: 100%; max-width: 560px; font: 15px/1.5 var(--sans); color: var(--ink); background: var(--surface);
    border: 1px solid var(--border-strong); border-radius: 8px; padding: 12px 14px; resize: vertical;
  }
  .suggest-form textarea:focus-visible { outline: 2px solid var(--border-strong); outline-offset: 2px; }
  .suggest-row { display: flex; align-items: center; gap: 14px; }
  .suggest-status { font-size: 13.5px; color: var(--muted); }
  .suggest-note { font-size: 13.5px; line-height: 1.5; color: var(--label); }
  .suggest-status.ok { color: var(--green-text); }
  .suggest-status.err { color: var(--red-text); }
  /* ---------- mailing list signup: one slim band per page ---------- */
  .signup { background: var(--chrome); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
  .signup .wrap { padding: 44px 32px; display: flex; align-items: center; justify-content: space-between; gap: 40px; flex-wrap: wrap; }
  .signup-copy { display: flex; flex-direction: column; gap: 6px; }
  .signup h2 { font-size: 30px; color: var(--ink); }
  .signup-copy p { font-size: 15px; color: var(--muted); max-width: 54ch; }
  .signup-act { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
  .signup-form { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .signup-form input {
    font: 15px/1.5 var(--sans); color: var(--ink); background: var(--surface);
    border: 1px solid var(--border-strong); border-radius: 8px; padding: 12px 14px; min-width: 250px;
  }
  .signup-form input:focus-visible { outline: 2px solid var(--border-strong); outline-offset: 2px; }
  .signup-form .btn:disabled { opacity: .6; cursor: default; }
  .signup-note { font-size: 13px; color: var(--label); }
  .signup-status { font-size: 13.5px; color: var(--muted); }
  .signup-status.ok { color: var(--green-text); }
  .signup-status.err { color: var(--red-text); }
  /* the Turnstile slot is empty until a visitor actually submits: only the form
     they used ever renders a widget, and it stays out of the layout until then */
  .signup-ts:empty { display: none; }
  .idea-list { margin-top: 4px; display: flex; flex-direction: column; gap: 10px; }
  .idea-card {
    background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
    padding: 14px 18px; display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  }
  .idea-copy { min-width: 0; flex: 1; }
  .idea-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
  .idea-card h4 { font-size: 17px; font-weight: 600; color: var(--ink); margin-bottom: 3px; }
  .idea-card p { font-size: 15px; line-height: 1.5; color: var(--ink); max-width: 60ch; }
  /* with a title above it the submission becomes supporting text, so it steps back a shade */
  .idea-card h4 + p { color: var(--muted); }
  /* Mike's mark on an idea: a green tick for planned or shipped, and an optional reply.
     Planned is the pale outline, shipped fills solid so the finished ones read first. */
  .idea-tag {
    display: flex; align-items: center; gap: 6px;
    font-family: var(--mono); font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
    color: var(--green-text); background: #eef5f0; border: 1px solid #c2d9cb; border-radius: 5px; padding: 3px 10px 3px 7px;
    flex-shrink: 0;
  }
  .idea-tag svg { width: 14px; height: 14px; flex-shrink: 0; }
  .idea-tag.is-shipped { color: #fff; background: var(--green-text); border-color: var(--green-text); }
  .idea-tag.is-preview { color: #fff; background: var(--blue); border-color: var(--blue); }
  .idea-reply { margin-top: 10px; padding: 2px 0 2px 14px; border-left: 3px solid var(--green); }
  .idea-reply b { display: block; margin-bottom: 2px; font-family: var(--mono); font-size: 11.5px; font-weight: 500; letter-spacing: .06em; text-transform: uppercase; color: var(--label); }
  /* left padding must clear the punch hole and perforation drawn by .btn::before/::after */
  .idea-actions .btn { padding: 9px 16px 9px 34px; font-size: 12px; white-space: nowrap; }
  .idea-actions .btn::before { left: 24px; top: 6px; bottom: 6px; }
  .idea-actions .btn::after { left: 11px; width: 7px; height: 7px; }
  @media (max-width: 900px) {
    .page-hero .wrap, .two, .feature, .votes { grid-template-columns: minmax(0, 1fr); }
    .two.rev { grid-template-columns: minmax(0, 1fr); }
    .two.rev > :first-child { order: 0; }
    .band.cta .wrap { flex-direction: column; align-items: flex-start; }
    /* the totem can be as wide as the column here, so a 36px intro slide would push the page sideways */
    .title-train { transform: translateX(14px); }
  }
  /* phones: 32px gutters and 104px block padding are desktop rhythm. On a 375px
     screen they take a fifth of the width off every capture and leave a blank
     screen between one block and the next. */
  @media (max-width: 560px) {
    .wrap { padding: 0 20px; }
    .block { padding: 72px 0; }
    .block.first { padding-top: 56px; }
    .page-hero .wrap { padding-top: 56px; padding-bottom: 44px; }
  }
  /* ---------- product capture slots: a labelled placeholder until a real capture lands, then the real thing, object-fit cover ---------- */
  .cap { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: repeating-linear-gradient(135deg, var(--chrome) 0 12px, var(--border) 12px 24px); }
  .cap > span { font-family: var(--mono); font-size: 12px; letter-spacing: .04em; color: var(--label); background: var(--surface); border: 1px dashed var(--border-strong); border-radius: 6px; padding: 8px 14px; }
  .cap.has-media { background: var(--surface); }
  .cap img, .cap video { width: 100%; height: 100%; object-fit: contain; display: block; background: var(--chrome); }
  /* the single framed capture on a feature page, e.g. the Wiring page hero */
  .shot { border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--surface); box-shadow: 0 8px 24px var(--shadow); }
  .shot .bar { height: 34px; background: var(--chrome); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 7px; padding: 0 12px; }
  .shot .bar i { width: 10px; height: 10px; border-radius: 50%; background: var(--border); display: block; }
  /* a long label truncates like a real window title rather than wrapping into the 34px bar */
  .shot .bar span { font-family: var(--mono); font-size: 11.5px; color: var(--label); margin-left: 8px;
    min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .shot .cap { position: relative; aspect-ratio: var(--cap-ar, 2167 / 1280); }
  .plan .callout {
    position: absolute; left: 6%; bottom: 8%;
    display: flex; gap: 9px; align-items: flex-start;
    background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--red);
    border-radius: 6px; padding: 9px 12px; max-width: 300px;
    font-size: 13px; line-height: 1.45; color: var(--ink);
    box-shadow: 0 4px 16px var(--shadow);
  }
  .plan .callout b { color: var(--red-text); }
  .hero .sep { margin-top: 8px; }
  .hero .sep .track {
    background:
      linear-gradient(#a3b5cb, #a3b5cb) 0 4px / 100% 3px no-repeat,
      linear-gradient(#a3b5cb, #a3b5cb) 0 11px / 100% 3px no-repeat,
      repeating-linear-gradient(90deg, #5a7392 0 7px, transparent 7px 22px) 0 1px / 22px 16px repeat-x;
  }

  /* ---------- line diagram ---------- */
  .line { padding: 112px 0; }
  .line-head { display: flex; flex-direction: column; gap: 18px; max-width: 760px; margin-bottom: 44px; align-items: flex-start; }
  .line h2 { font-size: clamp(44px, 5.2vw, 72px); color: var(--ink); text-wrap: balance; }
  .line .lead { font-size: 19px; color: var(--muted); }
  .diagram { overflow-x: auto; padding-bottom: 8px; }
  .diagram-inner { min-width: 900px; }
  .diagram svg { width: 100%; height: auto; display: block; }
  .stations { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px; margin-top: 8px; }
  .station { display: flex; flex-direction: column; gap: 6px; text-align: center; padding: 0 6px; opacity: 0; transform: translateY(8px); transition: opacity .5s ease, transform .5s ease; cursor: pointer; }
  .station.in { opacity: 1; transform: none; }
  .station h3 { font-family: var(--display); font-weight: 700; font-size: 24px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink); }
  .station p { font-size: 14px; color: var(--muted); line-height: 1.45; }
  .station .sum { font-family: var(--mono); font-size: 12.5px; color: var(--label); }
  .line-path { stroke-dasharray: 1000; stroke-dashoffset: 1000; transition: stroke-dashoffset 1.6s cubic-bezier(.4, 0, .2, 1); }
  .diagram.in .line-path { stroke-dashoffset: 0; }
  .stn { opacity: 0; transform-box: fill-box; transform-origin: center; transform: scale(.4); transition: opacity .35s ease, transform .35s cubic-bezier(.34, 1.56, .64, 1); }
  .diagram.in .stn { opacity: 1; transform: scale(1); }
  .stn circle { transition: fill .3s ease, stroke .3s ease; }
  /* the stop the train is calling at */
  .diagram.in .stn.active { transform: scale(1.28); }
  .stn.active circle:first-child { fill: var(--yellow); }
  .station h3 { transition: color .3s ease; }
  .station .sum { transition: color .3s ease; }
  .station.active h3 { color: var(--blue); text-decoration: underline; text-decoration-color: var(--yellow); text-decoration-thickness: 3px; text-underline-offset: 4px; }
  .station.active .sum { color: var(--ink); }
  /* the stopping service: the script moves it stop to stop; CSS does the run */
  .line-train { opacity: 0; transform: translate(100px, 45px); transition: opacity .4s ease 1.6s, transform 1.1s cubic-bezier(.45, .05, .2, 1); }
  .diagram.in .line-train { opacity: 1; }
  .line-train.express { transition: opacity .4s ease 1.6s, transform 2.4s cubic-bezier(.45, .05, .2, 1); }

  /* ---------- the product, stage by stage: real captures in a slide view ---------- */
  .showcase { margin-top: 56px; }
  .sc-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
  .sc-tab { font: 600 14px var(--sans); color: var(--muted); background: none; border: 1px solid var(--border); border-radius: 999px; padding: 8px 16px; cursor: pointer; transition: background .15s ease, color .15s ease; }
  .sc-tab:hover { color: var(--ink); }
  .sc-tab.active { background: var(--blue); color: #ffffff; border-color: var(--blue); }
  .sc-stage { position: relative; }
  .sc-slides { position: relative; aspect-ratio: 2167 / 1280; border-radius: 12px; overflow: hidden; border: 1px solid var(--border); background: var(--chrome); box-shadow: 0 8px 24px var(--shadow); }
  .sc-slide { position: absolute; inset: 0; opacity: 0; }
  .sc-slide.active { opacity: 1; }
  .sc-cap { position: absolute; left: 0; right: 0; bottom: 0; margin: 0; padding: 40px 18px 14px; background: linear-gradient(transparent, rgba(27, 42, 63, .78)); color: #ffffff; font-size: 15px; }
  .sc-arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--border); background: var(--surface); color: var(--ink); font-size: 26px; line-height: 1; cursor: pointer; box-shadow: 0 2px 8px var(--shadow); }
  .sc-arrow.prev { left: -20px; }
  .sc-arrow.sc-next { right: -20px; }
  @media (max-width: 900px) { .sc-arrow.prev { left: 8px; } .sc-arrow.sc-next { right: 8px; } }

  /* ---------- next stops ---------- */
  .next {
    margin-top: 56px; padding: 28px 32px;
    background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
    display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 40px; align-items: center;
  }
  .next-line svg { width: 100%; height: auto; display: block; }
  .next-labels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); text-align: center; margin-top: 6px; }
  .next-labels span { font-family: var(--display); font-weight: 700; font-size: 20px; letter-spacing: .08em; text-transform: uppercase; color: var(--label); }
  .next-copy { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
  .next-copy h3 { font-family: var(--display); font-weight: 800; font-size: 34px; letter-spacing: .02em; text-transform: uppercase; line-height: 1; color: var(--ink); }
  .next-copy p { font-size: 16px; color: var(--muted); max-width: 44ch; }

  /* ---------- band ---------- */
  .band { background: var(--blue-deep); color: var(--on-blue); }
  .band .wrap { padding: 112px 32px; display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: 64px; align-items: center; }
  .band h2 { font-size: clamp(44px, 5.2vw, 72px); color: var(--on-blue); text-wrap: balance; }
  .band h2 .hi { color: var(--yellow); }
  .band .lead { font-size: 19px; color: var(--band-muted); }
  .band .story { display: flex; flex-direction: column; gap: 18px; align-items: flex-start; }
  .band .story .sig { font-family: var(--display); font-weight: 700; font-size: 22px; letter-spacing: .06em; text-transform: uppercase; color: var(--yellow); }
  .points { display: flex; flex-direction: column; gap: 12px; }
  .point { display: flex; gap: 16px; background: var(--blue); border: 1px solid rgba(255, 255, 255, .12); border-radius: 10px; padding: 20px 22px; transition: transform .15s ease; }
  .point:hover { transform: translateX(4px); }
  .point svg { flex-shrink: 0; margin-top: 3px; }
  .point h4 { font-size: 17px; font-weight: 600; color: var(--on-blue); margin-bottom: 4px; }
  .point p { font-size: 15px; color: var(--band-muted); }

  /* ---------- tickets ---------- */
  .fares { padding: 112px 0; }
  .fares-head { display: flex; flex-direction: column; gap: 18px; max-width: 760px; margin-bottom: 44px; align-items: flex-start; }
  .fares h2 { font-size: clamp(44px, 5.2vw, 72px); color: var(--ink); text-wrap: balance; }
  .fares .lead { font-size: 19px; color: var(--muted); }
  .fares-head .quip { font-size: 16px; color: var(--muted); font-style: italic; }
  .tickets { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
  .ticket {
    position: relative;
    display: grid; grid-template-columns: 64px 1fr;
    background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
    overflow: hidden; box-shadow: 0 1px 3px var(--shadow);
    transition: transform .15s ease, box-shadow .15s ease;
  }
  .ticket:hover { transform: translateY(-3px); box-shadow: 0 10px 28px var(--shadow); }
  .ticket::before, .ticket::after {
    content: ""; position: absolute; left: 55px; width: 18px; height: 18px; border-radius: 50%;
    background: var(--paper); border: 1px solid var(--border);
  }
  .ticket::before { top: -10px; }
  .ticket::after { bottom: -10px; }
  .ticket .stub {
    display: flex; align-items: center; justify-content: center;
    border-right: 2px dashed var(--border);
    font-family: var(--display); font-weight: 700; font-size: 18px; letter-spacing: .18em; text-transform: uppercase;
    writing-mode: vertical-rl; transform: rotate(180deg);
  }
  .ticket.free .stub { background: var(--cream); color: var(--tot-western); border-right-color: #d9c9a2; }
  .ticket.paid .stub { background: var(--yellow); color: var(--on-yellow); border-right-color: rgba(16, 30, 51, .35); }
  .ticket.paid { border-color: var(--blue); }
  .ticket .body { padding: 30px 32px; display: flex; flex-direction: column; gap: 18px; }
  .ticket .top { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
  .ticket .name { font-family: var(--display); font-weight: 800; font-size: 34px; letter-spacing: .04em; text-transform: uppercase; }
  .ticket .price { font-family: var(--mono); font-weight: 500; font-size: 40px; line-height: 1; }
  .ticket .validity { font-family: var(--mono); font-size: 12.5px; color: var(--label); letter-spacing: .04em; text-transform: uppercase; }
  .ticket .quip { font-size: 13.5px; color: var(--muted); font-style: italic; }
  .ticket ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
  .ticket li { display: flex; gap: 10px; align-items: flex-start; font-size: 15.5px; }
  .ticket li svg { flex-shrink: 0; margin-top: 4px; }
  .ticket .foot { margin-top: auto; display: flex; flex-direction: column; gap: 10px; }
  .ticket .note { font-size: 13.5px; color: var(--muted); }

  /* ---------- not on sale yet ----------
     The paid ticket while checkout is shut: an inert stub, no lift and no
     punch. UNUSED SINCE CHECKOUT OPENED and kept on purpose, because it is
     the way back: swap either .lemonsqueezy-button for
     <button class="btn is-off" type="button" disabled>Not on sale yet</button>
     and the ticket reads as closed again. */
  .btn.is-off { background: #dfe3ea; color: #75808f; --rim: #c6ccd6; --stub: #b4bdc9; cursor: default; }
  .btn.is-off:hover { transform: none; }
  .btn.is-off:hover::after { background: transparent; border-color: var(--stub); }

  /* ---------- release log ---------- */
  .release { max-width: 980px; }
  .release + .release { border-top: 1px solid var(--border); margin-top: 56px; padding-top: 48px; }
  .release-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
  .release-head .when { font-family: var(--mono); font-size: 12.5px; color: var(--label); letter-spacing: .04em; text-transform: uppercase; }
  /* Each entry collapses. The summary is the whole head: totem, date, chevron, headline. */
  .release > summary { list-style: none; cursor: pointer; }
  .release > summary::-webkit-details-marker { display: none; }
  .release > summary { position: relative; padding-right: 36px; }
  .release > summary:focus-visible { outline: 2px solid var(--blue); outline-offset: 6px; border-radius: 10px; }
  .release-head h2.display { flex: 1 0 100%; margin: 0; }
  .release > summary:hover h2.display { color: var(--blue); }
  .rel-chev { position: absolute; right: 0; top: 2px; color: var(--label); transition: transform .18s ease; }
  .release[open] > summary .rel-chev { transform: rotate(180deg); }
  .release:not([open]) > summary { margin-bottom: 0; }
  @media (prefers-reduced-motion: reduce) { .rel-chev { transition: none; } }
  .release h2.display { font-size: clamp(28px, 3.2vw, 38px); color: var(--ink); text-wrap: balance; }
  .release .rel-lead { font-size: 18px; color: var(--muted); max-width: 66ch; margin-top: 12px; }
  .rel-group { margin-top: 34px; }
  .rel-group h3 { font-family: var(--display); font-weight: 800; font-size: 21px; letter-spacing: .05em; text-transform: uppercase; color: var(--blue); margin-bottom: 14px; }
  .rel-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px 34px; }
  .rel-list li { display: flex; gap: 10px; align-items: flex-start; font-size: 15.5px; line-height: 1.5; }
  .rel-list svg { flex: 0 0 auto; margin-top: 3px; }
  .rel-note { font-size: 13.5px; color: var(--muted); font-style: italic; margin-top: 14px; }
  @media (max-width: 860px) { .rel-list { grid-template-columns: minmax(0, 1fr); } }

  /* The small ticket carrying the live version, under the download button.
     Same geometry the nav's ticket uses, which is the one other place a
     button has to sit in a tight row. */
  .btn-sm { padding: 9px 16px 9px 34px; font-size: 11.5px; }
  .btn-sm::before { left: 24px; top: 6px; bottom: 6px; }
  .btn-sm::after { left: 11px; width: 7px; height: 7px; }

  /* ---------- guides: parked, see the note above .filters ---------- */
  .guides { background: var(--chrome); padding: 112px 0; }
  .guides-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 40px; margin-bottom: 40px; }
  .guides-head > div { display: flex; flex-direction: column; gap: 18px; max-width: 700px; align-items: flex-start; }
  .guides h2 { font-size: clamp(44px, 5.2vw, 72px); color: var(--ink); text-wrap: balance; }
  .guides .lead { font-size: 19px; color: var(--muted); }
  .guides-head a { font-weight: 600; white-space: nowrap; }
  .cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
  .card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 24px; display: flex; flex-direction: column; gap: 12px; align-items: flex-start; transition: transform .15s ease, box-shadow .15s ease; }
  .card:hover { transform: translateY(-3px); box-shadow: 0 10px 28px var(--shadow); }
  .card h3 { font-size: 19px; font-weight: 600; line-height: 1.3; }
  .card p { font-size: 15px; color: var(--muted); }
  .card .rt { font-family: var(--mono); font-size: 12.5px; color: var(--label); margin-top: auto; padding-top: 6px; }

  /* ---------- features: a departure-board list, one row per shipped feature ---------- */
  .features { background: var(--chrome); padding: 112px 0; }
  .features-head { display: flex; flex-direction: column; gap: 18px; max-width: 760px; margin-bottom: 40px; align-items: flex-start; }
  .features h2 { font-size: clamp(44px, 5.2vw, 72px); color: var(--ink); text-wrap: balance; }
  .features .lead { font-size: 19px; color: var(--muted); }
  .board { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
  .frow { display: grid; grid-template-columns: 56px 1fr auto; gap: 20px; align-items: center; padding: 22px 28px; border-bottom: 1px solid var(--border); }
  .frow:last-child { border-bottom: none; }
  .frow:nth-child(even) { background: var(--chrome); }
  .frow.flash { background: #fbf3de; }
  .frow .ic { width: 40px; height: 40px; border-radius: 8px; background: var(--surface); border: 1.5px solid var(--border-strong); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
  .frow.flash .ic { border-color: var(--yellow); }
  .frow h3 { font-size: 17px; font-weight: 600; color: var(--ink); }
  .frow p { font-size: 14.5px; color: var(--muted); margin-top: 4px; max-width: 56ch; }
  .frow .tag { font-family: var(--mono); font-size: 12.5px; color: var(--blue-deep); background: var(--chrome); border: 1px solid var(--border); border-radius: 5px; padding: 5px 10px; white-space: nowrap; }
  .frow.flash .tag { background: var(--yellow); border-color: var(--yellow); color: var(--ink); }

  /* ---------- closing ---------- */
  .closing { padding: 128px 0 104px; text-align: center; }
  .closing .wrap { display: flex; flex-direction: column; align-items: center; gap: 22px; }
  .closing h2 { font-size: clamp(56px, 7vw, 96px); color: var(--ink); text-wrap: balance; max-width: 14ch; }
  .closing .lead { font-size: 19px; color: var(--muted); max-width: 52ch; }
  .closing .row { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
  .closing .req { font-size: 13.5px; color: var(--muted); margin: -10px 0 0; }
  /* .soon is a size container, so in a flex row it needs a width of its own; wide enough that the sticker clears the label */
  .closing .row .soon { flex: 0 1 340px; }

  /* ---------- footer ---------- */
  .footer { background: var(--blue-deep); color: var(--band-muted); }
  .footer .wrap { padding: 48px 32px 40px; display: grid; grid-template-columns: minmax(0, 1.7fr) repeat(3, minmax(0, 1fr)); gap: 40px; }
  .footer .brand { color: var(--on-blue); }
  .footer p { font-size: 15px; color: var(--band-muted); max-width: 32ch; margin-top: 12px; }
  .footer .email { display: inline-block; margin-top: 12px; font-size: 15px; color: var(--on-blue); }
  .footer .col { display: flex; flex-direction: column; gap: 9px; font-size: 15px; }
  .footer .col span:first-child { font-family: var(--display); font-weight: 700; font-size: 15px; letter-spacing: .14em; text-transform: uppercase; color: var(--yellow); margin-bottom: 4px; }
  .footer .col a { color: var(--on-blue); }
  .footer .legal { border-top: 1px solid var(--blue); }
  .footer .legal .wrap { padding: 20px 32px 36px; display: flex; justify-content: space-between; gap: 24px; font-size: 13.5px; }
  .footer .legal span:last-child { max-width: 62ch; text-align: right; opacity: .8; }

  @media (max-width: 900px) {
    .hero .wrap, .band .wrap, .next { grid-template-columns: minmax(0, 1fr); }
    .tickets, .cards { grid-template-columns: minmax(0, 1fr); }
    .footer .wrap { grid-template-columns: 1fr 1fr; }
    .nav-links a:not(.btn) { display: none; }
    .guides-head { flex-direction: column; align-items: flex-start; }
    .frow { grid-template-columns: 40px 1fr; }
    .frow .tag { grid-column: 2; margin-top: 4px; }
    .footer .legal .wrap { flex-direction: column; }
    .footer .legal span:last-child { text-align: left; }
    .sep .train { height: 44px; }
  }
  @media (prefers-reduced-motion: reduce) {
    .btn, .point, .ticket, .card, .station, .stn, .line-path, .title-train { transition: none; }
    .station, .stn, .title-train, .line-train { opacity: 1; transform: none; }
    .line-path { stroke-dashoffset: 0; }
    .sep.in .train { animation: none; transform: translateX(10vw); }
    .sep.rev.in .train { transform: translateX(10vw) scaleX(-1); }
  }
