/* Unseenly site styles.

   Ported from design/site/index.html, the design package's reference
   implementation — README-FOR-AGENT is explicit that when the docs and
   that file disagree, the file wins. Structure, class names and states
   are kept as delivered so the two stay diffable.

   Token definitions are NOT here: tokens.css is the design system's own
   file and is used byte-for-byte. Only the two aliases the reference
   expects, plus its chip tokens, are bridged below. */

:root {
  --sans: var(--font-sans);
  --mono: var(--font-mono);
  --chip-bg: #0f1114cc;
  --chip-ink: #eaeef3;
}

/* The reference sets `hidden` on .scrim, .viewer and .toast, but also
   gives them `display: grid/flex` — an author rule that beats the user
   agent's [hidden] { display: none }. In design/site/index.html the
   checkout and the story viewer are therefore both on screen at load.
   Verified against that file directly; this restores the intent without
   touching any design value. */
[hidden] { display: none !important; }

* { box-sizing: border-box; }
  /* One overflowing row anywhere (the mobile header nav had zero margin
     for error — real device font metrics tipped it over) used to drag
     the whole page into horizontal scroll. html, not body, so
     position:sticky on the header keeps working. */
  html { overflow-x: hidden; }
  body {
    margin: 0; background: var(--surface-000); color: var(--ink);
    font-family: var(--sans); font-size: 16px; line-height: 24px;
    -webkit-font-smoothing: antialiased;
  }
  h1, h2, h3 { margin: 0; text-wrap: balance; letter-spacing: -0.02em; }
  p { margin: 0; }
  a { color: var(--accent-ink); }
  :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
  body.locked { overflow: hidden; }

  .shell { max-width: 1120px; margin: 0 auto; padding-inline: var(--space-5); }
  .mono { font-family: var(--mono); }
  .muted { color: var(--ink-muted); }
  .caption { font-size: 12px; line-height: 16px; font-weight: 500; letter-spacing: 0.02em; }
  .sm { font-size: 14px; line-height: 20px; }

  /* header */
  header {
    position: sticky; top: env(safe-area-inset-top, 0px); z-index: 30;
    background: color-mix(in srgb, var(--surface-000) 88%, transparent);
    backdrop-filter: blur(8px); border-bottom: 1px solid var(--line);
  }
  .bar { display: flex; align-items: center; gap: var(--space-4); padding-block: var(--space-3); }
  .logo { display: flex; align-items: center; gap: var(--space-2); background: none; border: 0;
    color: var(--ink); font: 600 20px/24px var(--sans); letter-spacing: -0.02em; cursor: pointer; padding: 0; }
  .logo svg { display: block; }
  .bar nav { margin-left: auto; display: flex; align-items: center; gap: var(--space-2); }

  /* buttons */
  .btn { font-family: var(--sans); font-size: 16px; line-height: 24px; font-weight: 500;
    border: 1px solid transparent; border-radius: var(--radius-md); padding: var(--space-3) var(--space-5); cursor: pointer; }
  .btn-primary { background: var(--accent); color: var(--on-accent); font-weight: 600; }
  .btn-primary:hover { background: var(--accent-hover); }
  .btn-secondary { background: transparent; border-color: var(--line-strong); color: var(--ink); }
  .btn-secondary:hover { background: var(--surface-200); }
  .btn-ghost { background: transparent; color: var(--ink-muted); padding: var(--space-2) var(--space-3); font-size: 14px; }
  .btn-ghost:hover { color: var(--ink); }
  .btn-lg { padding: var(--space-4) var(--space-6); }
  .btn-block { width: 100%; }
  /* A link dressed as a button (the Telegram pay link) must look like one. */
  a.btn { text-decoration: none; box-sizing: border-box; }
  a.btn-block { display: flex; justify-content: center; align-items: center; }
  .btn[disabled] { background: var(--surface-200); color: var(--ink-faint); border-color: transparent; cursor: default; }

  /* hero */
  .hero { padding-block: var(--space-8) var(--space-6); display: grid; gap: var(--space-5); justify-items: start; }
  .hero h1 { font-size: clamp(32px, 6vw, 44px); line-height: 1.08; max-width: 12ch; }
  .hero .lede { font-size: 17px; color: var(--ink-muted); max-width: 46ch; }

  .search { width: 100%; max-width: 560px; display: grid; gap: var(--space-3); }
  .field { display: flex; align-items: center; gap: var(--space-2); background: var(--surface-200);
    border: 1px solid var(--line-strong); border-radius: var(--radius-md); padding: var(--space-2); }
  .field.err { border-color: var(--danger); }
  .seg { display: flex; gap: 2px; background: var(--surface-100); border-radius: var(--radius-full); padding: 2px; flex: none; }
  .seg button { border: 0; background: transparent; color: var(--ink-muted); border-radius: var(--radius-full);
    padding: 6px 12px; font: 500 12px/16px var(--sans); cursor: pointer; letter-spacing: 0.02em;
    display: inline-flex; align-items: center; gap: 6px; }
  .seg button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
  /* Brand marks, not Lucide: handoff §49 mandates Lucide but it ships
     no platform logos, and TG / IG as letters read worse than the
     marks people already recognise. Filled paths, currentColor, so
     they invert with the pill like the labels did. Shown next to the
     name on desktop too — text alone read flat, and the marks are what
     makes the switch legible at a glance instead of just decorative. */
  .p-short { display: inline-flex; order: -1; }
  .p-icon { width: 16px; height: 16px; display: block; }
  .at { font-family: var(--mono); font-size: 13px; color: var(--ink-muted); padding-left: var(--space-2); }
  .field input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--ink);
    font: 400 13px/18px var(--mono); padding: 10px 0; }
  .field input::placeholder { color: var(--ink-faint); }
  .field input:focus { outline: none; }
  /* The reference labels this button "View". A word there costs the
     input roughly 70px on a phone and reads as a second action next to
     the platform switch; a magnifier says the same in a square. Lucide
     glyph per handoff §49 — 20px, 1.5px stroke, currentColor. The name
     survives for screen readers via aria-label. */
  .go { border: 0; background: var(--accent); color: var(--on-accent); border-radius: var(--radius-md);
    width: 40px; height: 40px; padding: 0; cursor: pointer; flex: none;
    display: grid; place-items: center; }
  .go svg { width: 20px; height: 20px; display: block; }
  .go:hover { background: var(--accent-hover); }
  .trust { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); color: var(--ink-muted); }
  .trust span { display: flex; align-items: center; gap: var(--space-2); }
  .tick { width: 5px; height: 5px; border-radius: var(--radius-full); background: var(--success); flex: none; }
  .err-msg { color: var(--danger); }
  .samples { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; color: var(--ink-muted); }
  .chip { border: 1px solid var(--line); background: var(--surface-100); color: var(--ink-muted);
    border-radius: var(--radius-full); padding: 4px 10px; font: 400 12px/16px var(--mono); cursor: pointer; }
  .chip:hover { color: var(--ink); border-color: var(--line-strong); }

  /* sections */
  section.block { padding-block: var(--space-8); border-top: 1px solid var(--line); }
  .eyebrow { color: var(--ink-faint); text-transform: uppercase; }
  .eyebrow.err { color: var(--danger); }
  h2 { font-size: 26px; line-height: 32px; margin-top: var(--space-2); }
  .steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-5); margin-top: var(--space-6); }
  .step-n { font: 500 13px/18px var(--mono); color: var(--accent-ink); }
  .step h3 { font-size: 18px; line-height: 24px; margin-top: var(--space-2); }
  .step p { color: var(--ink-muted); margin-top: var(--space-1); }

  .honest { margin-top: var(--space-6); display: grid; gap: 1px; background: var(--line);
    border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; }
  .honest div { background: var(--surface-100); padding: var(--space-4) var(--space-5); display: flex; gap: var(--space-4); align-items: baseline; }
  .no { color: var(--danger); font-weight: 600; flex: none; }

  /* pricing */
  .plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-3); margin-top: var(--space-6); }
  .plan { position: relative; text-align: left; background: var(--surface-100); border: 1px solid var(--line);
    border-radius: var(--radius-lg); padding: var(--space-5) var(--space-4); cursor: pointer; font-family: var(--sans); color: var(--ink); }
  .plan[aria-checked="true"] { border-color: var(--accent); background: var(--accent-soft); }
  .plan .term { font-size: 14px; line-height: 20px; color: var(--ink-muted); }
  .plan .price { font-size: 22px; line-height: 28px; font-weight: 600; margin-top: var(--space-2); font-variant-numeric: tabular-nums; }
  .plan .desc { font-size: 14px; line-height: 20px; color: var(--ink-muted); margin-top: var(--space-1); }
  .best { position: absolute; top: -9px; right: var(--space-3); background: var(--accent-soft); color: var(--accent-ink);
    border: 1px solid var(--accent); border-radius: var(--radius-sm); padding: 1px 8px; }

  /* faq */
  details { border-top: 1px solid var(--line); padding-block: var(--space-4); }
  details summary { cursor: pointer; font-weight: 500; list-style: none; display: flex; justify-content: space-between; gap: var(--space-4); }
  details summary::-webkit-details-marker { display: none; }
  details summary::after { content: "+"; color: var(--ink-faint); }
  details[open] summary::after { content: "–"; }
  details p { color: var(--ink-muted); margin-top: var(--space-2); max-width: 68ch; }

  footer { border-top: 1px solid var(--line); padding-block: var(--space-6) var(--space-8); color: var(--ink-muted); }
  .foot { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
  .foot .age { border: 1px solid var(--line-strong); border-radius: var(--radius-sm); padding: 1px 6px; color: var(--ink); }
  .foot-links { margin-left: auto; display: flex; flex-wrap: wrap; gap: var(--space-3); }
  .link-btn { background: none; border: 0; color: var(--ink-muted); font: 500 12px/16px var(--sans);
    letter-spacing: 0.02em; cursor: pointer; padding: 0; text-decoration: underline; text-underline-offset: 3px; }
  .link-btn:hover { color: var(--ink); }

  /* result view */
  .account { display: flex; align-items: center; gap: var(--space-4); background: var(--surface-100);
    border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--space-4); box-shadow: var(--shadow-card); }
  .ava { width: 56px; height: 56px; border-radius: var(--radius-full); background: var(--surface-200);
    color: var(--ink-muted); display: grid; place-items: center; font-size: 20px; font-weight: 600; flex: none; }
  /* The card used to say "Instagram" only in the muted meta line under
     the handle — easy to skim past. A platform badge on the avatar,
     the way a cross-post badge works elsewhere, reads at a glance. */
  .ava-wrap { position: relative; flex: none; }
  .ava-platform { position: absolute; right: -2px; bottom: -2px; width: 22px; height: 22px;
    border-radius: var(--radius-full); background: var(--surface-100); border: 2px solid var(--surface-100);
    display: grid; place-items: center; color: var(--ink); }
  .ava-platform .p-icon { width: 14px; height: 14px; }
  .account .nick { font: 600 18px/24px var(--mono); overflow-wrap: anywhere; }
  .badge { display: inline-flex; align-items: center; gap: var(--space-2); border-radius: var(--radius-sm);
    padding: var(--space-1) var(--space-2); background: var(--surface-200); color: var(--ink-muted); flex: none; }
  .badge .dot { width: 6px; height: 6px; border-radius: var(--radius-full); background: currentColor; }
  .badge.ok { color: var(--success); }
  .badge.bad { color: var(--danger); }
  .badge.acc { background: var(--accent-soft); color: var(--accent-ink); }
  /* Same badge, worn as a header button — access open in this browser,
     reachable from anywhere on the site, not just the result page it
     was unlocked from. */
  .access-pill { border: 1px solid var(--accent); font: 500 12px/16px var(--sans); cursor: pointer; }
  .access-pill:hover { background: color-mix(in srgb, var(--accent-soft) 70%, var(--accent)); }
  .access-wrap { position: relative; }
  /* Opens only when more than one handle is unlocked at once — with
     just one, the pill jumps straight there, same as clicking a single
     result would. */
  /* Anchored to the pill's right edge: the pill sits at the right of the
     header, so a left-anchored menu ran off the screen. */
  .access-menu { position: absolute; top: calc(100% + 6px); right: 0; min-width: 260px;
    background: var(--surface-100); border: 1px solid var(--line); border-radius: var(--radius-md);
    box-shadow: var(--shadow-pop); z-index: 40; overflow: hidden; }
  .access-menu-item { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3);
    width: 100%; padding: var(--space-3) var(--space-4); background: none; border: 0; border-bottom: 1px solid var(--line);
    color: var(--ink); font: 500 13px/18px var(--mono); cursor: pointer; text-align: left; }
  .access-menu-item:last-child { border-bottom: 0; }
  .access-menu-item:hover { background: var(--surface-200); }
  .access-menu-head { display: grid; gap: 2px; padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--line); background: var(--accent-soft); }
  .access-menu-head strong { font: 600 13px/18px var(--sans); color: var(--ink); }
  .access-menu-head span { font: 400 12px/16px var(--sans); color: var(--ink-muted); }
  .access-menu-item .left { color: var(--ink-muted); font-family: var(--sans); font-weight: 400; font-size: 12px; }

  .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--space-4); margin-top: var(--space-5); }
  .tile { position: relative; aspect-ratio: 3/4; max-width: 100%; border-radius: var(--radius-md);
    background: var(--lock); border: 0; padding: 0; cursor: pointer; overflow: hidden; display: block;
    background-image: radial-gradient(var(--line-strong) 1px, transparent 1px); background-size: 10px 10px; }
  .tile .lockdot { position: absolute; inset: 0; margin: auto; width: 26px; height: 26px;
    border-radius: var(--radius-full); border: 2px solid var(--ink-faint); }
  .tile .lockdot::after { content: ""; position: absolute; inset: 7px; border-radius: var(--radius-full); background: var(--ink-faint); }
  .tile .time { position: absolute; left: var(--space-2); bottom: var(--space-2); background: var(--chip-bg);
    color: var(--chip-ink); border-radius: var(--radius-sm); padding: 3px 6px; }
  .tile.open { background-image: none; }
  .tile.open .lockdot { display: none; }
  /* Marks a video tile now that the grid shows its poster frame instead
     of a broken-image icon — otherwise nothing distinguishes it from a
     photo until it's tapped. */
  .tile .playdot { position: absolute; inset: 0; margin: auto; width: 34px; height: 34px;
    border-radius: var(--radius-full); background: color-mix(in srgb, black 40%, transparent);
    display: grid; place-items: center; }
  .tile .playdot i { width: 0; height: 0; margin-left: 3px;
    border-style: solid; border-width: 7px 0 7px 11px; border-color: transparent transparent transparent var(--on-accent); }
  .tile .sample { position: absolute; inset: 0; display: grid; place-items: center; color: var(--on-accent); }
  .tile .sample span { font: 500 11px/14px var(--mono); opacity: 0.8; }

  /* Loading feedback. Anything the native Instagram fetch can take
     several real seconds to answer — search, the locked preview, paying
     — needs a visible "working" state, not just a disabled button that
     looks stuck. */
  @keyframes uspin { to { transform: rotate(360deg); } }
  @keyframes upulse { 0%, 100% { opacity: 0.45; } 50% { opacity: 0.9; } }

  .spinner { width: 16px; height: 16px; border-radius: var(--radius-full);
    border: 2px solid currentColor; border-top-color: transparent;
    animation: uspin 0.7s linear infinite; flex: none; }

  .go .spinner { display: none; }
  .go.busy svg { display: none; }
  .go.busy .spinner { display: block; color: var(--on-accent); }

  .btn.busy { color: transparent; pointer-events: none; position: relative; }
  .btn.busy::after { content: ""; position: absolute; left: 50%; top: 50%;
    width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: var(--radius-full);
    border: 2px solid var(--on-accent); border-top-color: transparent;
    animation: uspin 0.7s linear infinite; }

  .tile.skel { animation: upulse 1.1s ease-in-out infinite; }
  .tile.skel .lockdot { visibility: hidden; }

  /* Media still on its way. A Telegram story is downloaded by our server
     on first open — a video can take several seconds — and an empty
     tile or a black stage in the meantime reads as broken. */
  .tile.loading { animation: upulse 1.1s ease-in-out infinite; }
  .tile.loading::after, .vstage.loading::after { content: ""; position: absolute;
    left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px;
    border-radius: var(--radius-full); border: 2px solid var(--ink-muted);
    border-top-color: transparent; animation: uspin 0.7s linear infinite; pointer-events: none; }
  .tile.loading .playdot { visibility: hidden; }
  .vstage.loading { min-height: 320px; }
  .vstage.loading::after { width: 32px; height: 32px; margin: -16px 0 0 -16px; border-width: 3px; }
  .vstage.loading img, .vstage.loading video { visibility: hidden; }

  /* Full-page loader for a restored search (see the inline script at the
     top of body). Hides the hero before it ever paints, instead of
     showing it for a beat and then snapping to the result screen. */
  html.restoring #landing { display: none !important; }
  .page-loader { position: fixed; inset: 0; z-index: 999; display: grid;
    place-items: center; background: var(--surface-000); }
  .page-loader .spinner { width: 28px; height: 28px; border-width: 3px; color: var(--ink-muted); }

  /* Sticky, per the reference — with two preview tiles alone routinely
     running past one screen's height, "Open stories" needs to stay
     reachable without a hunt, not sit wherever normal flow happens to
     leave it. It briefly looked like sticky itself was the bug: on the
     error state, the grid used to stay full of stuck skeleton tiles
     forever (fixed separately — see showPreviewError), and *that* is
     what the sticky bar ended up parked on top of. An empty grid has
     nothing left below this to overlap. */
  .paybar { position: sticky; bottom: 0; z-index: 20; margin-top: var(--space-5);
    background: var(--surface-100); border: 1px solid var(--line); border-radius: var(--radius-lg);
    padding: var(--space-4); padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
    box-shadow: var(--shadow-pop); display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
  .paybar .copy { flex: 1 1 220px; }
  .paybar .copy strong { font-size: 18px; }
  .paybar .acts { display: flex; gap: var(--space-2); flex-wrap: wrap; }

  /* overlays */
  .scrim { position: fixed; inset: 0; background: var(--veil); display: grid; place-items: center;
    padding: var(--space-4); z-index: 50; overflow: auto; }
  .modal { width: min(560px, 100%); max-height: 88vh; overflow: auto; background: var(--surface-100);
    border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--space-5); box-shadow: var(--shadow-pop); }
  .modal h3 { font-size: 22px; line-height: 28px; }
  /* Checkout specifically: three plan cards plus email plus payment
     methods routinely run taller than the sheet on a phone, and Pay
     scrolling out of view read as the modal not fitting at all. Only
     the plans/email/methods area scrolls; Pay stays put at the bottom
     so it's never more than one glance away. */
  .modal.checkout { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
  .modal.checkout .modal-body { overflow: auto; padding: var(--space-5); }
  .modal.checkout .modal-foot { flex: none; padding: var(--space-4) var(--space-5);
    padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--line); background: var(--surface-100); border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
  .modal.doc p { color: var(--ink-muted); margin-top: var(--space-3); max-width: 68ch; }
  .modal.doc ul { color: var(--ink-muted); padding-left: 18px; margin: var(--space-3) 0 0; }
  .modal.doc li { margin-top: var(--space-2); }
  .input { width: 100%; background: var(--surface-200); border: 1px solid var(--line-strong);
    border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); color: var(--ink);
    font: 400 15px/22px var(--sans); }
  .input::placeholder { color: var(--ink-faint); }
  .methods { display: flex; flex-wrap: wrap; gap: var(--space-2); }
  .method { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 4px 10px; color: var(--ink-muted); }
  .stack { display: grid; gap: var(--space-3); }
  .row-between { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); }

  /* story viewer */
  .viewer { position: fixed; inset: 0; z-index: 60; background: #07080a;
    display: grid; grid-template-rows: auto 1fr auto; padding: var(--space-3);
    padding-top: calc(var(--space-3) + env(safe-area-inset-top, 0px));
    padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px)); }
  .vtop { width: min(440px, 100%); margin: 0 auto; display: grid; gap: var(--space-2); }
  .progress { display: flex; gap: 4px; }
  .pseg { flex: 1; height: 3px; border-radius: var(--radius-full); background: #ffffff2e; overflow: hidden; }
  .pseg i { display: block; height: 100%; width: 0; background: #f2f4f7; }
  .pseg.done i { width: 100%; }
  .pseg.now i { width: 100%; }
  .vhead { display: flex; align-items: center; gap: var(--space-3); color: #f2f4f7; }
  .vhead .who { font: 500 14px/20px var(--mono); }
  .vhead .when { font: 400 12px/16px var(--sans); color: #c3c8d2; }
  .vclose { margin-left: auto; background: none; border: 0; color: #f2f4f7; font: 500 14px/20px var(--sans); cursor: pointer; padding: var(--space-2); }
  .vstage { position: relative; width: min(440px, 100%); margin: var(--space-3) auto; border-radius: var(--radius-lg);
    overflow: hidden; display: grid; place-items: center; min-height: 0; }
  .vstage img, .vstage video { display: block; width: auto; height: auto; max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--radius-lg); }
  .zone { position: absolute; top: 0; bottom: 0; width: 34%; background: none; border: 0; cursor: pointer; }
  .zone.prev { left: 0; } .zone.next { right: 0; width: 66%; }
  .vbar { width: min(440px, 100%); margin: 0 auto; display: flex; gap: var(--space-2); align-items: center; }
  .vbar .count { color: #c3c8d2; font: 400 12px/16px var(--mono); margin-right: auto; }
  .vbtn { background: #ffffff1f; border: 1px solid #ffffff3d; color: #f2f4f7; border-radius: var(--radius-md);
    padding: 10px 16px; font: 500 14px/20px var(--sans); cursor: pointer; }
  .vbtn:hover { background: #ffffff2e; }
  .vbtn.primary { background: var(--accent); border-color: transparent; color: var(--on-accent); font-weight: 600; }

  /* toast */
  .toast { position: fixed; left: 50%; transform: translateX(-50%); top: calc(var(--space-5) + env(safe-area-inset-top, 0px));
    z-index: 70; background: var(--surface-100); color: var(--ink); border: 1px solid var(--line-strong);
    border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); box-shadow: var(--shadow-pop);
    max-width: min(520px, calc(100% - 32px)); }

  .demo-note { display: inline-flex; align-items: center; gap: var(--space-2); border: 1px dashed var(--line-strong);
    border-radius: var(--radius-full); padding: 4px 12px; color: var(--ink-muted); }

  /* app-style hero: the search is the page */
  .hero { justify-items: center; padding-block: calc(var(--space-8) * 1.4) var(--space-8); }
  .hero-main { display: grid; gap: var(--space-5); justify-items: center; text-align: center; width: 100%; }
  .hero h1 { max-width: 16ch; }
  .hero .trust, .hero .samples { justify-content: center; }

  @media (prefers-reduced-motion: no-preference) {
    .btn, .go, .plan, .tile, .chip { transition: background-color 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out; }
  }
  @media (max-width: 560px) {
    /* The reference drops the input onto its own row here, which makes
       the block ~100px tall. Shortening the platform labels to TG / IG
       buys back enough width to keep everything on one 52px row; the
       full names stay in aria-label. */
    .field { flex-wrap: nowrap; }
    .field input { flex: 1 1 60px; min-width: 0; padding-left: 0; }
    .p-full { display: none; }
    .seg button { padding: 6px 10px; }
    .foot-links { margin-left: 0; }
  }

  /* Real story media. The reference drew demo frames on a canvas; the
     live product shows the fetched image, so the tile needs a fill rule
     the canvas version did not. */
  .tile .shot { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

  /* ---- Mobile ---------------------------------------------------------
     design/site/index.html carries no <meta name="viewport">, so on a
     phone it renders into a 980px virtual viewport and the browser scales
     the whole page down. It looks intact only because everything is
     shrunk; it was never laid out for 375px, and its single 560px query
     is all it needs at that zoom.

     A live site must declare the viewport, so the page actually reflows —
     and handoff §101 makes mobile the primary scenario. These rules are
     the layout the reference never had to write. Tokens only, no new
     colours, structure unchanged. */

  @media (max-width: 560px) {
    /* 24px of shell padding on each side left the header nav fitting
       with zero px to spare in testing — any real device rendering
       "How it works" a hair wider than that tips the whole row over
       and drags the page into horizontal scroll. 16px buys real margin,
       here and for every other section on the same shell padding. */
    .shell { padding-inline: var(--space-4); }
    /* "How it works" was breaking across three lines and crushing the
       wordmark. Nav labels never wrap. */
    .bar { gap: var(--space-2); }
    .bar nav { gap: 0; }
    .logo { font-size: 17px; }
    .logo svg { width: 22px; height: 22px; }
    .btn-ghost { padding: var(--space-2); font-size: 13px; white-space: nowrap; }
    /* The header nav already fits with nothing to spare at this width
       (see the shell-padding note below) — a third item risks the exact
       overflow that caused. Access still shows on the result page
       itself (the access-until badge, the panel); the header pill is a
       desktop convenience, not the only way to see it. */
    .access-pill { display: none; }
    /* No header nav on mobile at all: both sections are a short scroll
       away on the landing page itself. */
    #howLink, #priceLink { display: none; }

    /* The reference's own rule drops the input to its own row but leaves
       the @ stranded beside the View button. Put the platform switch on
       one row and the whole entry on the next. */

    /* Avatar + handle + status badge on one row leaves the handle about
       80px at 375px, and it collapses into a vertical stack of letters.
       The badge takes its own line instead. */
    .account { flex-wrap: wrap; }
    .account::before { content: ""; order: 2; flex-basis: 100%; height: 0; }
    .account .badge { order: 3; }

    /* Same squeeze, same fix: "Open — 3 stories" next to the "Access
       until …" badge don't fit one row once access is unlocked, and
       without wrap the label gets crushed down to one word per line
       instead of just dropping the badge underneath it. */
    .row-between { flex-wrap: wrap; }

    .hero { padding-block: var(--space-6) var(--space-6); }
    /* flex:1 split "Save all" and "Extend" into two equal shares of a
       narrow row — not wide enough for "Save all" on one line, so it
       wrapped and doubled the button's (and the whole panel's) height.
       Sized to content instead; two short labels fit side by side with
       room to spare even at 320px. */
    .paybar .acts .btn { white-space: nowrap; padding-inline: var(--space-4); }

    /* Three stacked plan cards at var(--space-5) padding each ran the
       checkout body noticeably taller than it needed to be on a phone —
       less to scroll past before Pay's own space (which now never
       moves) comes into view. */
    .plan { padding: var(--space-4); }
    .plans { gap: var(--space-2); margin-top: var(--space-4) !important; }

    /* Two 140px+ columns meant two rows for as few as 3 stories, and
       each tile alone (3:4) ran taller than a phone keyboard. Three
       tighter columns get most story counts onto one row, so "Open
       stories" is a scroll away, not two. */
    .grid { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: var(--space-3); }

    /* sticky follows the page — on a short one it just settles wherever
       normal flow puts it and never visibly "sticks" to anything,
       which is why it kept reading as not pinned at all. fixed glues
       it to the screen itself, permanently, regardless of scroll or
       how short the page is — an actual bottom bar. Content needs
       bottom padding to match or the fixed bar sits on top of it. */
    .paybar { position: fixed; left: var(--space-4); right: var(--space-4); bottom: var(--space-4); margin-top: 0; z-index: 30; }
    #openState { padding-bottom: 210px; }
  }
