  *, *::before, *::after { box-sizing: border-box; }
  :root { --ts: 1; --tk: -0.018em; }   /* tweakable: display scale + tracking */
  /* Nav height, as a variable because three unrelated rules depend on it: the
     bar itself, the hero's `100vh minus the bar`, and every anchored section's
     scroll-margin-top (which has to clear the sticky bar or the heading lands
     underneath it). Those all carried the literal 72/88 before, so growing the
     bar on wide screens silently broke the other two. Override --nav-h alone
     and all three follow. */
  :root { --nav-h: 72px; }
  html { scroll-behavior: smooth; }
  body {
    margin: 0;
    background: var(--surface-canvas);
    color: var(--text-primary);
    font-family: var(--font-sans);
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
  }
  /* Body links on a light surface: rest --text-accent, hover
     --interactive-active. One convention, and hover always moves toward MORE
     contrast with the surface — darker here, lighter on the dark band.
     There were four conventions before, three of them broken: .contact-mail ran
     backwards (iris-700 → iris-600, lighter on hover); .auth-alt hovered from
     --iris-700 to --action-primary, which is the same colour; and
     .faq-foot-cta reached for --text-accent-strong, a variable nothing defines,
     so it fell back to its own resting colour and changed only the underline. */
  a { color: inherit; text-decoration: none; }
  button { font-family: inherit; }

  /* ---- Colour: roles, not ramps ----------------------------------
     The design system's rule is to read role tokens (--interactive,
     --action-primary, --text-inverse, --text-accent, --surface-inverse,
     --interactive-subtle) rather than the ramps they alias, so retuning a role
     repaints the page instead of leaving it pinned to a swatch. 29 of the 47
     ramp usages this file had were swapped to the role that is BOTH the same
     value and the right meaning; the remaining 17 stay, for two reasons:

       1. No role carries that value. --iris-300 / --iris-200 (the light accents
          on the dark band and in the date picker) and --iris-700-as-text (link
          colour in .auth-alt, .contact-mail, .legal a:hover) have no role
          equivalent in the pinned 2026-06 build — the closest, --text-accent,
          is --iris-600, a different colour. Swapping would silently restyle.
       2. The value matches but the meaning does not. --slate-400 is the
          secondary text on the dark band (.metric .cap, .demo-copy p.csub);
          it happens to equal --border-strong, and writing a border role into
          a text colour would be worse than the ramp, not better.

     The 2026-08 system adds --cta-fill / --on-cta-fill for exactly the first
     case. This page loads the pinned 2026-06 build, which does not define them
     — so those swaps wait for the landing page to be rebuilt on the current
     system (see ui_kits/marketing/landing-pinned.css). */
  .wrap { max-width: var(--content-wide); margin: 0 auto; padding: 0 40px; }
  .serif { font-family: var(--font-serif); font-weight: 400; letter-spacing: var(--tk, -0.018em); }
  .mono  { font-family: var(--font-mono); font-feature-settings: "tnum" 1, "lnum" 1; }

  .overline {
    font-size: 12px; font-weight: 500; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--text-tertiary);
  }

  /* ---- Chinese body leading --------------------------------------
     Latin body copy sits comfortably at 1.5–1.65; Chinese does not. Han
     glyphs fill their em box with no ascender/descender whitespace, so the
     same ratio puts consecutive lines visibly closer together — the design
     system asks for ~1.75 on Chinese (see its Bilingual type specimen).
     Scoped to html[lang^="zh"] so English keeps its tighter, airier setting
     rather than both languages compromising on one number.
     Not listed here, on purpose: .legal and .about-prose already run 1.72
     (long-form pages were set correctly from the start); .metric .cap and
     .form-error are short single-line labels where extra leading would just
     detach them from what they annotate. */
  html[lang^="zh"] .hero p.sub,
  html[lang^="zh"] .coverage p.cov-sub,
  html[lang^="zh"] .feat-head p,
  html[lang^="zh"] .feat .copy p.lead,
  html[lang^="zh"] .sol-head p,
  html[lang^="zh"] .sol-card p,
  html[lang^="zh"] .pricing-head p,
  html[lang^="zh"] .demo-copy p.csub,
  html[lang^="zh"] .demo-success p,
  html[lang^="zh"] .faq-answer,
  html[lang^="zh"] .foot-tag,
  html[lang^="zh"] .auth-head .auth-sub,
  html[lang^="zh"] .page-head p.page-sub,
  html[lang^="zh"] .help-card p,
  html[lang^="zh"] .contact-card p,
  html[lang^="zh"] .blog-card p,
  html[lang^="zh"] .blog-empty { line-height: 1.75; }

  /* ---- Headline line semantics ----------------------------------
     Each .ln is one curated, hard line (set via data-i18n-html in the
     dict). Lines never re-wrap (white-space: nowrap) — the curated break
     holds at every width; instead, JS (fitHeadings() in landing.js) scales
     the font down so the longest line fits its column. Chinese keep-all is
     belt-and-suspenders. */
  .ln { display: block; white-space: nowrap; }
  /* balance only on headings that still wrap naturally (no curated .ln lines) */
  .demo-copy h2, .faq-head h2, .page-head h1 { text-wrap: balance; }
  /* Explicit lines drive the wrap, so drop the ch-based max-width that was
     tuned for natural wrapping (it would otherwise re-wrap each line). */
  h1:has(.ln), h2:has(.ln), h3:has(.ln) { max-width: none; }
  html[lang^="zh"] .ln { word-break: keep-all; }

  /* ---- Buttons --------------------------------------------------- */
  /* Label sizes are 16 / 17, not the 15 / 16 this shipped with until 2026-09-08.
     The heights are the marketing scale and stay — what was wrong is that the
     labels never grew with them. At 46/15 the height was 3.07× the label; at
     54/16 .btn-lg was 3.38×, the loosest control on either surface. (Chinese ink
     now fills 33% of .btn and 29–30% of .btn-lg. Earlier figures of 30/27% here
     were taken while the CSP was blocking the webfonts — see .brand .name — so
     they described Noto Sans SC's system fallback, not Noto Sans SC.) The app's
     own primitive (design-system/innex/controls.tsx, the same numbers as the
     design system's core/Button) runs md 42/14 = 3.00 and lg 52/16 = 3.25, so
     the landing page's large button had drifted past both.
     The second half of it, and the reason Neo read the labels as *small* rather
     than the buttons as tall: on this page the surrounding prose is 17–19px, so
     a 15px label sits BELOW its own body copy, where the app's 14px label sits
     level with 14px body text. Same dosage rule as everywhere else in the
     system — marketing scales the whitespace and the type together; the button
     is not exempt.
     16 and 17 restore the ratios (2.88 and 3.18) without touching the heights,
     which carry the CTA's weight in a page this large — shrinking the pill to
     fix the ratio would have made the primary action quieter, not better. */
  .btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    height: 46px; padding: 0 22px; border-radius: var(--radius-pill);
    font-size: 16px; font-weight: 500; cursor: pointer; border: 1px solid transparent;
    transition: background var(--duration-fast) var(--ease-standard),
                color var(--duration-fast) var(--ease-standard),
                border-color var(--duration-fast) var(--ease-standard),
                transform var(--duration-fast) var(--ease-standard);
    white-space: nowrap;
  }
  .btn:active { transform: scale(0.97); }
  .btn-ink   { background: var(--action-primary); color: var(--text-on-accent); }
  .btn-ink:hover { background: var(--action-primary-hover); }
  .btn-ghost { background: transparent; color: var(--text-primary); }
  .btn-ghost:hover { background: var(--surface-hover); }
  .btn-out   { background: var(--surface-card); color: var(--text-primary); border-color: var(--border-default); }
  .btn-out:hover { background: var(--surface-hover); }
  .btn-soon  { background: var(--surface-sunken); color: var(--text-tertiary); cursor: default; pointer-events: none; }
  .btn-soon:active { transform: none; }
  .btn-lg    { height: 54px; padding: 0 30px; font-size: 17px; }
  .btn-block { width: 100%; }

  /* ---- Language dropdown (footer, opens upward) ------------------ */
  .lang-dd { position: relative; display: inline-flex; }
  .lang-dd-btn {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: var(--font-sans); font-size: 13px; font-weight: 500;
    color: var(--text-secondary); background: var(--surface-sunken);
    border: 1px solid transparent; border-radius: var(--radius-pill);
    padding: 9px 13px; cursor: pointer;
    transition: background var(--duration-fast) var(--ease-standard),
                color var(--duration-fast) var(--ease-standard),
                box-shadow var(--duration-fast) var(--ease-standard);
  }
  .lang-dd-btn .globe { width: 15px; height: 15px; color: var(--text-tertiary); flex: 0 0 auto; }
  .lang-dd-btn .chev  { width: 14px; height: 14px; color: var(--text-tertiary); flex: 0 0 auto; transition: transform var(--duration-base) var(--ease-standard); }
  .lang-dd-btn:hover { color: var(--text-primary); }
  .lang-dd-btn:focus-visible { outline: none; border-color: var(--interactive); box-shadow: var(--shadow-focus); }
  .lang-dd.open .lang-dd-btn { color: var(--text-primary); background: var(--surface-active); }
  .lang-dd.open .lang-dd-btn .chev { transform: rotate(180deg); }

  .lang-dd-menu {
    position: absolute; bottom: calc(100% + 8px); right: 0;
    min-width: 156px; margin: 0; padding: 6px; list-style: none;
    background: var(--surface-card); border-radius: var(--radius-md);
    box-shadow: var(--shadow-dropdown);
    opacity: 0; transform: translateY(6px) scale(0.98); transform-origin: bottom right;
    pointer-events: none; z-index: 40;
    transition: opacity var(--duration-fast) var(--ease-standard),
                transform var(--duration-base) var(--ease-out);
  }
  .lang-dd.open .lang-dd-menu { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
  .lang-dd-menu li {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    padding: 9px 11px; border-radius: var(--radius-sm);
    font-size: 14px; color: var(--text-secondary); cursor: pointer;
    transition: background var(--duration-fast) var(--ease-standard),
                color var(--duration-fast) var(--ease-standard);
  }
  .lang-dd-menu li:hover { background: var(--surface-hover); color: var(--text-primary); }
  .lang-dd-menu li[aria-selected="true"] { color: var(--text-primary); font-weight: 500; }
  .lang-dd-menu li .tick { width: 15px; height: 15px; color: var(--text-accent); opacity: 0; flex: 0 0 auto; }
  .lang-dd-menu li[aria-selected="true"] .tick { opacity: 1; }

  /* ---- Nav ------------------------------------------------------- */
  nav.bar {
    position: sticky; top: 0; z-index: 30;
    /* Must track --surface-canvas (#faf9f7, warm). The neutral #fafafa of the
       2026-08 system reads as a cool grey band over this page's warm canvas —
       most visible as a grey strip behind the mobile menu header. */
    background: rgba(250,249,247,0.82); backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--border-subtle);
  }
  .nav-in { display: flex; align-items: center; gap: 24px; height: var(--nav-h); }
  /* Three columns: logo (left) · links (centered) · auth (right).
     Equal-flex side columns keep the links group centered in the bar. */
  .nav-side { flex: 1 1 0; min-width: 0; display: flex; align-items: center; }
  .brand { display: flex; align-items: center; gap: 10px; }
  /* 26, not 30. innex-mark.svg draws its darts from 1→11 inside a 0 0 12 12
     viewBox, so 1/6 of the box is padding and the rendered glyph is only 10/12
     of whatever size is set here. At 30px that put 25px of ink against the
     wordmark's 15.5px cap height — a ratio of 1.61, which is why the two read
     as different sizes however they are aligned. 26px brings the ink to 21.7px
     against a 17.6px cap (see .brand .name below): 1.23, inside the 1.1–1.3
     a lockup wants. Measure the ink, not the box, if this is ever retuned.
     2026-09-04: the whole lockup went 26 → 30 at Neo's request ("Innex 可以搞大
     一点"). Both numbers move together on purpose — the ratio above is what
     makes the pair read as one object, so growing only the wordmark would undo
     the fix this comment describes. At 30 the mark's ink is 25px against a
     20.3px cap: still 1.23. */
  .logo-mark { width: 30px; height: 30px; display: block; flex: 0 0 auto; }
  /* The wordmark is LIVE TEXT in the display serif, not an outlined asset — same
     treatment as the app's sidebar (AppSidebar.tsx) and the agent turn's identity
     label, so the brand reads identically on both surfaces and follows the theme.
     The page used to ship assets/innex-wordmark.svg here, which had it outlined in
     a *sans* face, lowercase, with the fill hardcoded to #232067 — three ways off
     from the app and from this page's own bundled _ds/readme.md ("the wordmark
     sets Innex in the display serif"). 26px, up from 23px, is half of the fix
     for the mark/wordmark size mismatch described on .logo-mark above — the
     mark came down 30→26 and the wordmark went up 23→26, so the lockup keeps
     its overall visual weight in a 72px bar (a wordmark large enough to fix the
     ratio on its own would need 31px and would outweigh the 14px nav links)
     while the ink ratio lands at 1.23. The app still runs 22px in a denser
     sidebar.
     Weight 500, not the app sidebar's 400, also at Neo's request ("字体粗一点").
     This is a deliberate divergence from AppSidebar.tsx and from the rule the
     1180px block below records — the marketing bar is a 73px header on a wide
     off-white page where 400 reads thin, whereas the app's 22px wordmark sits in
     a dense dark sidebar. 500 is the next cut Newsreader actually ships (see
     tokens/fonts.css: 400;500;600) — 600 turns the serif into a different, much
     harder voice. If the app ever needs to match, move the app, not this. */
  .brand .name { font-family: var(--font-serif); font-weight: 500; font-size: 30px; letter-spacing: -0.02em; color: var(--text-primary); }
  /* Optical centring. .brand is align-items:center, which lines up the BOXES;
     the ink inside them does not agree. Newsreader reserves descender room that
     "Innex" (ink descent 0.37px at 30px) never uses, so box-centring floats the
     glyphs above the mark's ink centre and the wordmark has to come back down.
     Measured 2026-09-08 with the real webfont at all three sizes the nav uses:
     the wordmark's ink centre sits 3.03px high at 30px, 3.43px at 34px, 3.84px
     at 38px — i.e. 0.101em flat, which is why the correction is written in em
     and needs no per-breakpoint value. Transform, not margin, so the flex
     layout and the gap are untouched.
     ⚠️ MEASURE ONLY WITH THE WEBFONT ACTUALLY LOADED. This value was briefly
     removed earlier that same day on measurements that said the opposite (ink
     sitting 0.109em LOW, so the nudge looked like it was creating the error it
     was there to fix). Those numbers were real but the font wasn't: server.js's
     CSP was blocking fonts.googleapis.com, so the page was rendering in macOS
     "Iowan Old Style", whose vertical metrics (fontBoundingBox 31/10 at 30px,
     against Newsreader's 25/9) flip the sign of the whole calculation. Before
     trusting any number here, confirm the face: CDP
     CSS.getPlatformFontsForNode on .brand .name must report
     "Newsreader 16pt" with isCustomFont true, NOT a system serif.
     Method: append a zero-size inline probe to .name to read the baseline, take
     actualBoundingBoxAscent / Descent from canvas measureText in the same
     computed font, and compare that ink centre against the mark's box centre —
     the mark's ink is centred in its box (viewBox 0 0 12 12, glyph 1→11), so
     its box centre IS its ink centre. */
  .brand .name { transform: translateY(0.1em); }
  .nav-links { display: flex; align-items: center; gap: 28px; flex: 0 0 auto; }
  .nav-links a { font-size: 14px; font-weight: 500; color: var(--text-secondary); transition: color var(--duration-fast) var(--ease-standard); }
  .nav-links a:hover { color: var(--text-primary); }
  .nav-right { display: flex; align-items: center; gap: 14px; justify-content: flex-end; }

  /* ---- Nav dropdowns --------------------------------------------- */
  .nav-links .nav-item { position: relative; }
  .nav-links .nav-trigger {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 14px; font-weight: 500; color: var(--text-secondary);
    background: transparent; border: 0; cursor: pointer; padding: 0;
    font-family: var(--font-sans);
    transition: color var(--duration-fast) var(--ease-standard);
  }
  .nav-links .nav-trigger:hover,
  .nav-item.open .nav-trigger { color: var(--text-primary); }
  .nav-links .nav-trigger .chev { width: 13px; height: 13px; color: var(--text-tertiary);
    transition: transform var(--duration-base) var(--ease-standard); }
  .nav-item.open .nav-trigger .chev { transform: rotate(180deg); }
  .nav-menu {
    position: absolute; top: calc(100% + 10px); left: 0;
    min-width: 220px; margin: 0; padding: 8px; list-style: none;
    background: var(--surface-card); border-radius: var(--radius-md);
    box-shadow: var(--shadow-dropdown);
    opacity: 0; transform: translateY(6px) scale(0.98); transform-origin: top left;
    pointer-events: none; z-index: 40;
    transition: opacity var(--duration-fast) var(--ease-standard),
                transform var(--duration-base) var(--ease-out);
  }
  .nav-item.open .nav-menu { opacity: 1; transform: none; pointer-events: auto; }
  .nav-menu a {
    display: block; padding: 9px 11px; border-radius: var(--radius-sm);
    font-size: 14px; color: var(--text-secondary);
    transition: background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
  }
  .nav-menu a:hover { background: var(--surface-hover); color: var(--text-primary); }

  /* ---- Mobile hamburger + menu sheet (hidden until ≤860px) ------- */
  .nav-burger {
    display: none; /* revealed in the ≤860px query */
    width: 42px; height: 42px; flex: 0 0 auto;
    align-items: center; justify-content: center;
    border: 0; border-radius: var(--radius-pill); background: transparent;
    color: var(--text-primary); cursor: pointer;
    transition: background var(--duration-fast) var(--ease-standard);
  }
  .nav-burger:hover { background: var(--surface-hover); }
  .nav-burger:active { transform: scale(0.94); }
  .nav-burger .bars { position: relative; width: 18px; height: 12px; }
  .nav-burger .bars span {
    position: absolute; left: 0; width: 100%; height: 1.6px; border-radius: 2px;
    background: currentColor;
    transition: transform var(--duration-base) var(--ease-standard),
                opacity var(--duration-fast) var(--ease-standard),
                top var(--duration-base) var(--ease-standard);
  }
  .nav-burger .bars span:nth-child(1) { top: 0; }
  .nav-burger .bars span:nth-child(2) { top: 5px; }
  .nav-burger .bars span:nth-child(3) { top: 10px; }
  .nav-burger[aria-expanded="true"] .bars span:nth-child(1) { top: 5px; transform: rotate(45deg); }
  .nav-burger[aria-expanded="true"] .bars span:nth-child(2) { opacity: 0; }
  .nav-burger[aria-expanded="true"] .bars span:nth-child(3) { top: 5px; transform: rotate(-45deg); }

  .mobile-menu {
    display: none; /* set to block only inside the ≤860px query */
    position: fixed; left: 0; right: 0; top: 72px; bottom: 0; z-index: 25;
    background: var(--surface-canvas);
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    opacity: 0; visibility: hidden; transform: translateY(-6px);
    transition: opacity var(--duration-base) var(--ease-standard),
                transform var(--duration-base) var(--ease-out),
                visibility var(--duration-base) var(--ease-standard);
  }
  .mobile-menu.open { opacity: 1; visibility: visible; transform: none; }
  .mobile-menu-in { display: flex; flex-direction: column; padding: 14px 0 40px; }
  .m-nav { display: flex; flex-direction: column; }
  /* Top-level rows: plain links (Pricing) and accordion triggers share one look,
     mirroring the desktop nav where Pricing is plain and Resources/About open. */
  .m-link,
  .m-group-trigger {
    display: flex; align-items: center; width: 100%; padding: 16px 6px;
    font-size: 19px; font-weight: 500; color: var(--text-primary);
    border-bottom: 1px solid var(--border-subtle);
    font-family: var(--font-sans);
    transition: color var(--duration-fast) var(--ease-standard);
  }
  .m-link:hover, .m-link:active,
  .m-group-trigger:hover { color: var(--text-accent); }
  .m-group-trigger {
    justify-content: space-between; gap: 12px; text-align: left;
    background: transparent; border-top: 0; border-left: 0; border-right: 0;
    cursor: pointer;
  }
  .m-group-trigger .chev {
    width: 16px; height: 16px; flex: 0 0 auto; color: var(--text-tertiary);
    transition: transform var(--duration-base) var(--ease-standard);
  }
  .m-group.open .m-group-trigger .chev { transform: rotate(180deg); }
  /* Collapsible panel — the 0fr→1fr grid-rows trick animates height with no
     magic pixel value; the inner wrapper's overflow:hidden clips during collapse. */
  .m-group-panel {
    display: grid; grid-template-rows: 0fr;
    transition: grid-template-rows var(--duration-base) var(--ease-out);
  }
  .m-group.open .m-group-panel { grid-template-rows: 1fr; }
  .m-group-panel-in { overflow: hidden; }
  .m-sublink {
    display: block; padding: 13px 6px 13px 18px;
    font-size: 16px; color: var(--text-secondary);
    border-bottom: 1px solid var(--border-subtle);
    transition: color var(--duration-fast) var(--ease-standard);
  }
  .m-sublink:hover, .m-sublink:active { color: var(--text-accent); }
  .m-cta { display: flex; flex-direction: column; gap: 12px; margin-top: 28px; }
  body.menu-open { overflow: hidden; }

  /* ---- Hero (fills the first screen) ----------------------------- */
  .hero { min-height: calc(100vh - var(--nav-h)); min-height: calc(100svh - var(--nav-h)); display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 56px 0; }
  /* The flex column centers via align-items, which would shrink-wrap .wrap to
     the widest nowrap headline and let it overflow. Pin it to full width so the
     column tracks the viewport and fitHeadings() can measure real available space. */
  .hero .wrap { width: 100%; }
  .hero h1 {
    margin: 24px auto 0;
    font-size: calc(var(--ts) * 76px);   /* desktop max; JS fitHeadings() scales down to fit */
    line-height: calc(0.99em + 3px);     /* additive leading: tight when big, looser when small */
    letter-spacing: -0.014em;
  }
  .hero p.sub { margin: 28px auto 0; max-width: 60ch; font-size: 20px; line-height: 1.6; color: var(--text-secondary); }
  .hero .cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 36px; }
  .hero .note { margin-top: 18px; font-size: 13px; color: var(--text-tertiary); }
  /* Split hero — copy left, globe right (China to the world, single-hue iris) */
  .hero-grid { display: grid; grid-template-columns: 1.04fr 0.96fr; align-items: center; gap: clamp(28px, 4vw, 72px); text-align: left; }
  .hero-copy { min-width: 0; }
  .hero-grid h1 { margin: 0; }
  .hero-grid p.sub { margin: 24px 0 0; max-width: 44ch; }
  .hero-grid .cta { justify-content: flex-start; }
  .hero-globe { width: 100%; max-width: 540px; margin: 0; justify-self: center; aspect-ratio: 1 / 1; }
  .hero-globe canvas { display: block; width: 100%; height: 100%; touch-action: pan-y; }

  /* Product showcase — the visual, just below the fold */
  .showcase { padding: 4px 0 var(--section-sm); }
  image-slot { display: block; width: 100%; }

  /* ---- Trust strip ----------------------------------------------- */
  .trust { padding: 8px 0 var(--section-sm); text-align: center; }
  .trust .trust-label { font-size: 13px; letter-spacing: 0.04em; color: var(--text-tertiary); }
  .trust .logos { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 18px 40px; margin-top: 26px; }
  .trust .logo-ghost { width: 116px; height: 30px; border-radius: var(--radius-sm); background: var(--surface-sunken); }

  /* ---- Creator intelligence -------------------------------------- */
  /* A flat --surface-sunken plinth, not a border — the system's own way of
     drawing a boundary without a rule line. Gives the section a floor to
     stand on so it stops reading as hero's composition continuing past the
     fold; the white cards float on it with no extra shadow/border needed. */
  .coverage { padding: var(--section-lg) 0; background: var(--surface-sunken); overflow: clip; }
  .creator-showcase { display: grid; grid-template-columns: minmax(0, .9fr) minmax(540px, 1.1fr); gap: clamp(28px, 6vw, 104px); align-items: center; }
  .creator-copy { position: relative; z-index: 2; }
  .coverage h2 { margin: 0; max-width: 8.6em; font-size: clamp(48px, 5vw, 76px); line-height: 1.03; }
  .coverage p.cov-sub { margin: 24px 0 0; max-width: 29ch; font-size: 17px; line-height: 1.65; color: var(--text-secondary); }
  .creator-deck { position: relative; height: 588px; min-width: 0; isolation: isolate; }
  .creator-card { position: absolute; overflow: hidden; width: 284px; border: 1px solid rgba(22, 20, 43, .1); border-radius: 18px; background: var(--surface-card); box-shadow: 0 22px 40px rgba(22, 20, 43, .13); transform-origin: center; transition: transform .55s var(--ease-standard), box-shadow .55s var(--ease-standard); }
  .creator-card--main { z-index: 3; top: 26px; left: 50%; width: 338px; transform: translateX(-50%); }
  .creator-card--instagram { z-index: 1; top: 106px; left: 3%; transform: rotate(-4deg); }
  .creator-card--tiktok { z-index: 2; top: 122px; right: 1%; transform: rotate(4deg); }
  .creator-card-media { height: 250px; overflow: hidden; background: var(--surface-sunken); }
  .creator-card--main .creator-card-media { height: 298px; }
  .creator-card-media img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .65s var(--ease-standard); }
  /* The source photos crop tight at the top (head almost touches frame edge),
     so no object-position value alone can pull the head's center down to the
     2/5 line the way Neo asked — cover only chooses which slice of the source
     to show, it can't invent pixels above it. Each jpg has a blurred strip
     added above the real photo, sized so that at 0% (no top crop) the head's
     center lands on that 2/5 line. */
  .creator-card--main .creator-card-media img { object-position: 50% 0%; }
  .creator-card--instagram .creator-card-media img { object-position: 50% 0%; }
  .creator-card--tiktok .creator-card-media img { object-position: 50% 0%; }
  .creator-card-platform { position: absolute; top: 15px; left: 15px; display: inline-flex; align-items: center; gap: 6px; padding: 7px 10px; border: 1px solid rgba(255,255,255,.72); border-radius: 999px; background: rgba(255,255,255,.92); color: var(--text-primary); font-size: 11px; font-weight: 600; line-height: 1; box-shadow: 0 3px 12px rgba(22, 20, 43, .08); }
  .creator-card-platform img { display: block; width: 13px; height: 13px; }
  .creator-card-body { padding: 17px 18px 18px; }
  .creator-name { margin: 0; color: var(--text-primary); font-family: var(--font-serif); font-size: 25px; font-weight: 500; letter-spacing: -.025em; line-height: 1.1; }
  .creator-card--back .creator-name { font-size: 20px; }
  .creator-niche { margin: 7px 0 0; color: var(--text-secondary); font-size: 12px; }
  .creator-mini-stats, .creator-main-stats { display: grid; grid-template-columns: 1fr 1fr; margin-top: 17px; padding-top: 14px; border-top: 1px solid var(--border-subtle); }
  .creator-mini-stats span + span, .creator-main-stats span + span { padding-left: 14px; border-left: 1px solid var(--border-subtle); }
  .creator-mini-stats strong, .creator-main-stats strong { display: block; color: var(--text-primary); font-family: var(--font-mono); font-size: 19px; font-weight: 600; letter-spacing: -.035em; line-height: 1; }
  .creator-main-stats strong { font-size: 24px; }
  .creator-mini-stats small, .creator-main-stats small { display: block; margin-top: 6px; color: var(--text-tertiary); font-size: 10px; line-height: 1.15; }
  .creator-insight { position: absolute; z-index: 4; min-width: 132px; padding: 15px 17px; border: 1px solid rgba(103, 88, 224, .12); border-radius: 14px; background: rgba(247, 245, 255, .96); box-shadow: 0 16px 28px rgba(49, 41, 108, .12); color: var(--text-primary); transition: transform .55s var(--ease-standard); }
  .creator-insight span { display: block; color: var(--text-secondary); font-size: 11px; font-weight: 500; }
  .creator-insight strong { display: block; margin-top: 5px; font-family: var(--font-mono); font-size: 30px; font-weight: 600; letter-spacing: -.06em; line-height: 1; }
  .creator-insight--fit { top: 80px; right: -1%; }
  .creator-insight--reach { bottom: 55px; left: 6%; }
  .creator-deck:hover .creator-card--main { transform: translateX(-50%) translateY(-10px); box-shadow: 0 31px 52px rgba(22, 20, 43, .18); }
  .creator-deck:hover .creator-card--instagram { transform: translate(-15px, 9px) rotate(-6deg); }
  .creator-deck:hover .creator-card--tiktok { transform: translate(15px, 9px) rotate(6deg); }
  .creator-deck:hover .creator-card--main img { transform: scale(1.035); }
  .creator-deck:hover .creator-insight--fit { transform: translate(8px, -7px); }
  .creator-deck:hover .creator-insight--reach { transform: translate(-7px, 7px); }
  /* Back cards are inspectable, not decorative: hover brings the selected
     creator to the reading plane without moving the rest of the composition. */
  .creator-deck .creator-card--instagram:hover { z-index: 6; transform: translate(-20px, -14px) rotate(-1.5deg) scale(1.035); box-shadow: 0 31px 52px rgba(22, 20, 43, .2); }
  .creator-deck .creator-card--tiktok:hover { z-index: 6; transform: translate(20px, -14px) rotate(1.5deg) scale(1.035); box-shadow: 0 31px 52px rgba(22, 20, 43, .2); }
  .creator-card--back:hover .creator-card-media img { transform: scale(1.035); }
  .creator-disclaimer { margin: 0; padding-right: 4px; color: var(--text-tertiary); font-size: 11px; text-align: right; }
  @media (prefers-reduced-motion: reduce) { .creator-card, .creator-card-media img, .creator-insight { transition: none; } .creator-deck:hover .creator-card, .creator-deck:hover .creator-insight { transform: none; } .creator-deck:hover .creator-card--main { transform: translateX(-50%); } }

  /* ---- Metrics band (dark) --------------------------------------- */
  .band { background: var(--surface-inverse); color: var(--text-inverse); padding: var(--section) 0; }
  .band h2 { text-align: center; margin: 16px auto 0; font-size: var(--display-lg); line-height: 1.12; color: var(--text-inverse); }
  .metrics { display: grid; grid-template-columns: repeat(5, 1fr); gap: 28px; margin-top: 76px; }
  .metric { text-align: center; padding: 0 8px; }
  .metric .num { font-family: var(--font-mono); font-weight: 500; font-size: 48px; line-height: 1; letter-spacing: -0.02em; color: var(--text-inverse); font-feature-settings: "tnum" 1, "lnum" 1; }
  .metric .num.accent { color: var(--iris-300); }
  .metric .cap { margin-top: 16px; font-size: 13px; line-height: 1.45; color: var(--slate-400); }

  /* ---- Features -------------------------------------------------- */
  .feat-head { text-align: center; padding: var(--section) 0 8px; }
  .feat-head h2 { margin: 16px auto 0; font-size: var(--display-lg); line-height: 1.1; }
  .feat-head p { margin: 16px auto 0; max-width: 54ch; font-size: 18px; line-height: 1.6; color: var(--text-secondary); }
  /* Intra-group rhythm, deliberately one step below the section scale. The four
     .feat blocks share one .feat-head, so they are a group, not four sections:
     --section on each would put 240px between features — the same gap as between
     two top-level sections — and the group would stop reading as one. --section-sm
     puts 160px between them, clearly looser than the old bare 64px (128px) but
     still tighter than a section boundary. */
  section.feat { padding: var(--section-sm) 0; }
  .feat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 80px; align-items: center; }
  /* A 1fr track's implicit min-width:auto grows to its content's min-content; a
     nowrap .ln heading can push that past the viewport and break the layout
     (and starve fitHeadings of a real column width). min-width:0 caps the track
     to its share so headings size and shrink against the actual column. */
  .feat-grid > * { min-width: 0; }
  .feat-grid.rev .copy { order: 2; }
  /* A demo box whose ratio differs from its source's makes object-fit eat a band
     of the clip, silently. All five scene videos render at 1600×1306 = 800/653;
     the box used to be 29/22, so `cover` scaled by width and cropped the bottom
     7% — 92 source px, the scene's bottom 69 CSS px. That band is not empty: it
     holds outreach's composer, scale's result toast, manage's reply box and
     plan's Back / Confirm & next, i.e. the controls those clips exist to show.
     (The two clips set to `contain` dodged the crop and paid in letterbox bars
     instead.) Giving the videos the source ratio makes cover and contain
     coincide, so nothing is cropped or letterboxed at any width, and the
     per-video object-fit split that used to matter no longer does. */
  video.feat-demo { height: auto !important; aspect-ratio: 800 / 653; }
  /* The demo shot wraps the clip and its end card. It carries no size of its
     own: the video's aspect-ratio above still sets the height, and the card is
     absolutely positioned inside, so adding the wrapper moved no layout. */
  .demo-shot { position: relative; display: block; }
  .demo-endcard {
    position: absolute; inset: 0; display: grid; place-items: center;
    border-radius: 20px; overflow: hidden;
    opacity: 0; transition: opacity var(--duration-slow, .32s) var(--ease-standard);
  }
  .demo-endcard.is-on { opacity: 1; }
  /* The whole still replays, not just the button — the button is the affordance,
     the card is the target. */
  .demo-endcard { cursor: pointer; }
  /* The still is the clip's own poster frame, so the swap from the last video
     frame to this image changes the playback state, not the picture. */
  .demo-endcard-still { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
  /* A translucent play button over the still: a square in smoked glass, on the
     design system's own corner radius, with a solid white triangle.
     Deliberately NOT the shape everyone's muscle memory reads as YouTube —
     that mark is a wide rounded rectangle in solid red, so this one is square,
     unsaturated and see-through on all three counts. It was briefly 78×50,
     which was close enough to be worth changing. */
  .demo-replay {
    position: relative; display: grid; place-items: center;
    width: 64px; height: 64px; padding: 0;
    border: 0; border-radius: var(--radius-pill);
    background: rgba(22, 20, 43, .24);
    -webkit-backdrop-filter: blur(10px) saturate(1.2);
    backdrop-filter: blur(10px) saturate(1.2);
    color: #fff; cursor: pointer;
    box-shadow: 0 4px 18px rgba(22, 20, 43, .12);
    transition: background var(--duration-fast) var(--ease-standard),
                transform var(--duration-fast) var(--ease-standard);
  }
  .demo-endcard:hover .demo-replay { background: rgba(22, 20, 43, .38); }
  .demo-replay:active { transform: scale(0.96); }
  /* Keyboard focus needs a ring the browser default can't give it here: the
     UA outline is dark, and this button sits on smoked glass. */
  .demo-replay:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
  /* An inline SVG with only a viewBox resolves to zero width in this button, so
     the icon has to be sized here or it silently doesn't render. No optical
     nudge: the glyph is drawn centred in its viewBox (see the path) and sits
     dead centre in the square. The shadow is what carries it now that the plate
     behind it is only 24% opaque — most of these stills are pale product
     screens. */
  .demo-replay svg {
    width: 34px; height: 34px;
    filter: drop-shadow(0 1px 4px rgba(22, 20, 43, .55));
  }
  .visually-hidden {
    position: absolute; width: 1px; height: 1px; margin: -1px;
    padding: 0; border: 0; overflow: hidden; white-space: nowrap;
    clip-path: inset(50%);
  }
  .feat .copy h3 { margin: 16px 0 0; font-size: var(--display-md); line-height: 1.1; }
  .feat .copy p.lead { margin: 22px 0 0; font-size: 18px; line-height: 1.62; color: var(--text-secondary); max-width: 46ch; }
  .feat .copy .bullets { list-style: none; margin: 24px 0 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 10px 20px; }
  .feat .copy .bullets li { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--text-primary); }
  .feat .copy .bullets li::before { content: ""; width: 5px; height: 5px; border-radius: 999px; background: var(--interactive); flex: 0 0 auto; }

  /* AI chat demo card (feature 3) */
  .ai-chat {
    background: var(--surface-card); border-radius: var(--radius-2xl);
    padding: 28px; box-shadow: var(--shadow-ai-panel);
    display: flex; flex-direction: column; gap: 18px;
  }
  .ai-chat .msg-user {
    align-self: flex-end; max-width: 82%;
    background: var(--surface-active); padding: 12px 16px;
    border-radius: 18px 18px 4px 18px; font-size: 15px; line-height: 1.5;
  }
  .ai-chat .msg-agent { display: flex; gap: 12px; }
  .ai-chat .ava {
    flex: 0 0 auto; width: 30px; height: 30px; border-radius: 999px;
    background: var(--surface-inverse); color: var(--iris-300);
    display: inline-flex; align-items: center; justify-content: center;
    font-family: var(--font-serif); font-size: 16px;
  }
  .ai-chat .msg-agent .body { font-size: 15px; line-height: 1.62; color: var(--text-primary); }
  .ai-chat .msg-agent .body b { font-weight: 600; }

  /* ---- Solutions / use-cases ------------------------------------- */
  .solutions { padding: var(--section) 0; }
  .sol-head { text-align: center; }
  .sol-head h2 { margin: 14px auto 0; font-size: var(--display-lg); line-height: 1.12; }
  .sol-head p { margin: 16px auto 0; max-width: 54ch; font-size: 18px; line-height: 1.6; color: var(--text-secondary); }
  .sol-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 56px; }
  /* Text card, not media — --radius-xl (16px), not --radius-2xl (20px). */
  .sol-card { background: var(--surface-card); border-radius: var(--radius-xl); padding: 30px 28px; box-shadow: var(--shadow-card); }
  .sol-card .sol-name { font-family: var(--font-serif); font-size: 22px; letter-spacing: -0.018em; }
  .sol-card p { margin: 12px 0 0; font-size: 16px; line-height: 1.62; color: var(--text-secondary); }

  /* ---- Pricing --------------------------------------------------- */
  .pricing { padding: var(--section) 0; }
  .pricing-head { text-align: center; }
  .pricing-head h1, .pricing-head h2 { margin: 16px auto 0; font-size: var(--display-lg); line-height: 1.1; }
  .pricing-head h1 { margin-top: 0; }
  .pricing-head p { margin: 18px auto 0; max-width: 44ch; font-size: 18px; line-height: 1.6; color: var(--text-secondary); }

  .bill-toggle {
    display: inline-flex; align-items: center; gap: 4px;
    margin: 36px auto 0; padding: 4px; border-radius: var(--radius-pill);
    background: var(--surface-sunken); position: relative;
  }
  .bill-toggle button {
    border: 0; background: transparent; cursor: pointer;
    padding: 9px 20px; border-radius: 12px;
    font-size: 14px; font-weight: 500; color: var(--text-secondary);
    transition: background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
  }
  .bill-toggle button[aria-pressed="true"] { background: var(--surface-card); color: var(--text-primary); box-shadow: var(--shadow-card); }
  /* Promo flag — now lives inside the entry plan card, not the toggle. */
  .save-badge {
    position: absolute; top: 20px; right: 20px;
    padding: 5px 12px; border-radius: 999px;
    background: var(--interactive-subtle); color: var(--iris-700);
    font-size: 12px; font-weight: 600; letter-spacing: 0.01em;
  }

  /* stretch, not start: the cards only line up on their own while all three
     hold the same number of rows at the same wrap. One extra line under any
     tier — a longer localised label, a note — used to leave the bottom edges
     ragged, which reads as a layout bug rather than a difference in content. */
  .plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 56px; align-items: stretch; }
  .plan {
    /* --radius-2xl (20px) is the *media* radius; a text card is --radius-xl. */
    background: var(--surface-card); border-radius: var(--radius-xl);
    padding: 34px 26px; display: flex; flex-direction: column;
    box-shadow: var(--shadow-card); position: relative;
  }
  .plan.featured { box-shadow: var(--shadow-card-hover); outline: 1.5px solid var(--iris-200); }
  .plan .pop-badge {
    position: absolute; top: 20px; right: 20px;
    padding: 5px 12px; border-radius: 999px;
    background: var(--action-primary); color: var(--text-inverse);
    font-size: 12px; font-weight: 600;
  }
  /* 32/36/40 across the breakpoints, up from 28/30/32 — the tier name is what
     a buyer scans the column by and it was sitting barely above the 15px body
     copy. Holds ~0.62 of the price size at every step, and the two ends land
     on the display scale (…24/32/40…). */
  .plan .plan-name { font-family: var(--font-serif); font-size: 32px; letter-spacing: -0.018em; }
  .plan .plan-for { margin-top: 8px; font-size: 14px; line-height: 1.5; color: var(--text-secondary); min-height: 42px; }
  .plan .price { margin-top: 26px; display: flex; align-items: baseline; gap: 8px; }
  .plan .price-was { font-family: var(--font-mono); font-size: 18px; color: var(--text-tertiary); text-decoration: line-through; }
  .plan .price-amount { font-family: var(--font-mono); font-weight: 500; font-size: 52px; line-height: 1; letter-spacing: -0.02em; color: var(--text-primary); }
  /* The blurred "price to be announced" treatment that used to live here —
     real figures moved into CSS `content` under a specular sheen — is gone as
     of 2026-09-02 (Neo): all three tiers now publish a real price, so there is
     nothing left to withhold. It took `.price-amount.masked` (+ ::before /
     ::after and the per-tier `content` overrides keyed off
     `.plans[data-billing]`) with it. Restoring the effect means restoring all
     four pieces together — a bare `.masked` class does nothing on its own. */
  .plan .price-period { font-size: 15px; color: var(--text-secondary); }
  .plan .price-billed { margin-top: 10px; font-size: 13px; color: var(--text-tertiary); min-height: 18px; }
  .plan .plan-cta { margin-top: 26px; }
  .plan .feat-list { list-style: none; margin: 30px 0 0; padding: 26px 0 0; border-top: 1px solid var(--border-subtle); display: flex; flex-direction: column; gap: 15px; }
  .plan .feat-list li { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 14px; color: var(--text-primary); }
  /* One step under the 14px label it sits opposite — keep that contrast. */
  .plan .feat-list .val { font-family: var(--font-mono); font-size: 13px; color: var(--text-secondary); }
  /* Every row is now a plain label/number pair, so the tick, the dash, the ∞
     and the struck-through promo value are all gone (2026-09-02, Neo re-pitched
     the table with concrete figures in all three columns). The only row that
     carries more than a number is the outreach one, whose mailbox qualifier
     drops to a second line rather than crowding the value column. */
  .plan .feat-list li.has-note { flex-wrap: wrap; row-gap: 3px; }
  .plan .feat-list .pf-note {
    flex-basis: 100%;
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--text-tertiary);
  }
  /* Swipe dots live under the plans; only the mobile carousel shows them. */
  .plans-dots { display: none; }

  /* ---- Closing CTA + demo-request form (dark) -------------------- */
  .feat-head, .pricing, .faq { scroll-margin-top: calc(var(--nav-h) + 16px); }
  .demo { background: var(--surface-inverse); color: var(--text-inverse); padding: var(--section) 0; scroll-margin-top: calc(var(--nav-h) + 16px); }
  .demo-grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 72px; align-items: center; }
  .demo-copy h2 { margin: 16px 0 0; max-width: 14ch; font-size: calc(var(--ts) * 52px); line-height: 1.07; color: var(--text-inverse); }
  /* cta.title is authored with curated .ln lines in BOTH languages, so the 14ch
     cap above is measuring a wrap that never happens — and clamping a nowrap
     line to 14ch just makes it overflow the box instead of wrapping inside it.
     Chinese survived on luck (8 han glyphs land just under 14ch); English
     ("without growing your team?") ran 605px out of a 423px box at every width,
     long before this file grew any wide-screen steps. The generic
     `h2:has(.ln) { max-width: none }` near the top of the file was meant to
     cover exactly this, but it's declared earlier at equal specificity and
     loses to the line above — hence the repeat here, and hence .demo-copy h2
     joining fitHeadings()'s selector list in landing.js so the line is sized to
     its real column like every other curated heading. */
  .demo-copy h2:has(.ln) { max-width: none; }
  .demo-copy p.csub { margin: 22px 0 0; max-width: 42ch; font-size: 18px; line-height: 1.6; color: var(--slate-400); }
  .demo-copy .alt { margin: 26px 0 0; font-size: 15px; color: var(--slate-400); }
  /* On the dark band the link goes LIGHTER on hover, which is the same rule as
     everywhere else — hover moves toward more contrast against the surface, and
     on near-black that direction is up. --iris-300/-200 stay as ramps: no role
     in the pinned build carries a light accent for dark surfaces. */
  .demo-copy .alt a { color: var(--iris-300); font-weight: 500; }
  .demo-copy .alt a:hover { color: var(--iris-200); }

  .demo-card { background: var(--surface-card); color: var(--text-primary); border-radius: var(--radius-2xl); padding: 34px; box-shadow: var(--shadow-ai-panel); }
  .field { display: flex; flex-direction: column; gap: 7px; margin-bottom: 16px; }
  .field label { font-size: 13px; font-weight: 500; color: var(--text-secondary); }
  /* Inputs are --radius-sm (6px) system-wide, so the booking form feels the same
     as the app's forms a visitor lands in right after. */
  .field input { height: 46px; border-radius: var(--radius-sm); border: 1px solid var(--border-default); padding: 0 14px; font-family: var(--font-sans); font-size: 15px; color: var(--text-primary); background: var(--surface-card); transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); }
  .field input::placeholder { color: var(--text-tertiary); }
  .field input:focus { outline: none; border-color: var(--interactive); box-shadow: 0 0 0 3px rgba(113,113,178,0.32); }
  .field.invalid input { border-color: var(--error); }
  .field.invalid input:focus { box-shadow: 0 0 0 3px rgba(158,76,90,0.26); }
  .field .err { font-size: 13px; color: var(--error); }
  .demo-card .submit { margin-top: 22px; }
  .submit[aria-busy="true"] { opacity: 0.72; pointer-events: none; }
  .form-error { margin-top: 14px; font-size: 13px; line-height: 1.5; color: var(--error); text-align: center; }

  /* ---- Date + time picker (Calendly-style popover) ---------------- */
  .datepick { position: relative; }
  .datepick-trigger {
    width: 100%; height: 46px; border-radius: var(--radius-sm); border: 1px solid var(--border-default);
    padding: 0 14px; background: var(--surface-card); font-family: var(--font-sans);
    font-size: 15px; color: var(--text-primary); cursor: pointer;
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
  }
  .datepick-trigger.placeholder .dp-label { color: var(--text-tertiary); }
  .datepick-trigger .cal-ico { width: 16px; height: 16px; color: var(--text-tertiary); flex: 0 0 auto; }
  .datepick-trigger:hover { border-color: var(--iris-300); }
  .datepick.open .datepick-trigger { outline: none; border-color: var(--interactive); box-shadow: 0 0 0 3px rgba(113,113,178,0.32); }

  .datepick-pop {
    position: absolute; top: calc(100% + 8px); left: 0; z-index: 50;
    width: 340px; max-width: 100%;
    background: var(--surface-card); border-radius: var(--radius-md); box-shadow: var(--shadow-dropdown);
    padding: 14px;
    opacity: 0; visibility: hidden; transform: translateY(6px) scale(0.99); transform-origin: top left; pointer-events: none;
    transition: opacity var(--duration-fast) var(--ease-standard), transform var(--duration-base) var(--ease-out), visibility var(--duration-base) var(--ease-out);
  }
  .datepick.open .datepick-pop { opacity: 1; visibility: visible; transform: none; pointer-events: auto; }

  .dp-body { display: flex; gap: 12px; }
  .dp-cal { flex: 0 0 188px; }

  .dp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
  .dp-title { font-size: 13px; font-weight: 600; color: var(--text-primary); }
  .dp-nav { display: inline-flex; gap: 2px; }
  .dp-nav button { width: 24px; height: 24px; border-radius: 6px; border: 0; background: transparent; color: var(--text-secondary); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
  .dp-nav button:hover:not(:disabled) { background: var(--surface-hover); color: var(--text-primary); }
  .dp-nav button:disabled { opacity: 0.35; cursor: default; }
  .dp-nav svg { width: 14px; height: 14px; }

  .dp-dow, .dp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; }
  .dp-dow span { text-align: center; font-size: 10px; color: var(--text-tertiary); padding: 2px 0; }
  .dp-day { height: 25px; border: 0; background: transparent; border-radius: 6px; font-family: var(--font-mono); font-size: 12px; color: var(--text-primary); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
  .dp-day.blank { pointer-events: none; }
  .dp-day:hover:not(:disabled):not(.blank) { background: var(--surface-hover); }
  .dp-day:disabled { color: var(--text-disabled); cursor: default; }
  .dp-day.today:not(.sel) { box-shadow: inset 0 0 0 1px var(--iris-200); }
  .dp-day.sel { background: var(--action-primary); color: var(--text-inverse); }

  .dp-times { flex: 1; min-width: 0; display: flex; flex-direction: column; border-left: 1px solid var(--border-subtle); padding-left: 12px; }
  .dp-times-label { font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-tertiary); margin-bottom: 6px; }
  .dp-slots { display: flex; flex-direction: column; gap: 6px; max-height: 176px; overflow: auto; padding-right: 2px; }
  .dp-slot { flex: 0 0 auto; border: 1px solid var(--border-default); background: var(--surface-card); border-radius: 8px; padding: 7px 0; font-family: var(--font-mono); font-size: 13px; color: var(--text-primary); cursor: pointer; transition: border-color var(--duration-fast) var(--ease-standard), background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
  .dp-slot:hover:not(:disabled) { border-color: var(--interactive); }
  .dp-slot:disabled { color: var(--text-disabled); cursor: default; }
  .dp-slot.booked { text-decoration: line-through; background: var(--surface-canvas); border-style: dashed; }
  .dp-slot.sel { background: var(--action-primary); color: var(--text-inverse); border-color: var(--action-primary); }
  .dp-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border-subtle); }
  .dp-tz { display: inline-flex; align-items: center; gap: 6px; min-width: 0; overflow: hidden; color: var(--text-secondary); }
  .dp-tz svg { width: 14px; height: 14px; color: var(--text-tertiary); flex: 0 0 auto; }
  .dp-tz-select { border: 0; background: transparent; font-family: var(--font-sans); font-size: 13px; color: var(--text-secondary); cursor: pointer; min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .dp-tz-select:focus-visible { outline: none; color: var(--text-primary); }
  .dp-clear { flex: 0 0 auto; background: transparent; border: 0; color: var(--text-tertiary); font-size: 13px; cursor: pointer; padding: 4px; }
  .dp-clear:hover { color: var(--text-secondary); }
  .dp-actions { display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto; }
  .dp-done { background: var(--action-primary); color: var(--text-inverse); border: 0; border-radius: 8px; font-family: var(--font-sans); font-size: 13px; font-weight: 600; padding: 7px 16px; cursor: pointer; transition: opacity var(--duration-fast) var(--ease-standard); }
  .dp-done:hover:not(:disabled) { opacity: 0.9; }
  .dp-done:disabled { background: var(--surface-hover); color: var(--text-disabled); cursor: default; }
  .demo-success { text-align: center; padding: 28px 8px 20px; }
  .demo-success .mark { width: 56px; height: 56px; border-radius: 999px; background: var(--interactive-subtle); color: var(--iris-700); display: inline-flex; align-items: center; justify-content: center; margin: 0 auto 20px; }
  .demo-success .mark svg { width: 26px; height: 26px; }
  .demo-success h3 { font-family: var(--font-serif); font-weight: 400; letter-spacing: -0.018em; font-size: 28px; }
  .demo-success p { margin-top: 12px; font-size: 15px; line-height: 1.6; color: var(--text-secondary); }

  /* ---- FAQ (compact accordion) ----------------------------------- */
  .faq { padding: var(--section) 0; scroll-margin-top: calc(var(--nav-h) + 16px); }
  .faq-inner { max-width: 760px; margin: 0 auto; }
  .faq-head { text-align: center; margin-bottom: 36px; }
  .faq-head h2 { margin: 14px auto 0; font-size: calc(var(--ts) * 34px); line-height: 1.12; }
  .faq-list { border-top: 1px solid var(--border-subtle); }
  .faq-item { border-bottom: 1px solid var(--border-subtle); }
  .faq-item summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 22px 4px; font-size: 17px; font-weight: 500; color: var(--text-primary); transition: color var(--duration-fast) var(--ease-standard); }
  .faq-item summary::-webkit-details-marker { display: none; }
  .faq-item summary:hover { color: var(--text-accent); }
  .faq-item .chev { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; color: var(--text-tertiary); transition: transform 220ms var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
  .faq-item .chev svg { width: 20px; height: 20px; }
  .faq-item[open] summary .chev { transform: rotate(180deg); color: var(--text-accent); }
  .faq-answer { padding: 0 4px 24px; font-size: 16px; line-height: 1.65; color: var(--text-secondary); max-width: 66ch; }
  .faq-foot-cta { margin: 32px 0 0; text-align: center; font-size: 16px; color: var(--text-secondary); }
  .faq-foot-cta a { color: var(--text-accent); font-weight: 500; text-decoration: none; transition: color var(--duration-fast) var(--ease-standard); }
  .faq-foot-cta a:hover { color: var(--interactive-active); text-decoration: underline; }

  /* ---- Footer ---------------------------------------------------- */
  footer { border-top: 1px solid var(--border-subtle); padding: var(--section-sm) 0 44px; }
  .foot-grid { display: grid; grid-template-columns: 2.2fr 1fr 1fr 1fr; gap: 48px; align-items: start; }
  .foot-statement { font-family: var(--font-serif); font-weight: 400; letter-spacing: var(--tk, -0.018em); font-size: 24px; line-height: 1.2; color: var(--text-primary); max-width: 16ch; margin: 20px 0 0; }
  /* `ch` is the width of "0", so a Latin-tuned cap of 16ch is ~7 CJK glyphs and
     the zh statement wrapped mid-word ("…红人营销增 / 长专家"). CJK has no word
     boundaries for the browser to respect, so the fix is to give the line room:
     14em ≈ 336px holds the whole sentence, and the footer's first column
     (2.2fr ≈ 464px) is wide enough for it. */
  html[lang^="zh"] .foot-statement { max-width: 14em; }
  .foot-tag { font-size: 14px; color: var(--text-tertiary); max-width: 34ch; line-height: 1.6; margin: 14px 0 0; }
  .socials { display: flex; gap: 10px; margin-top: 22px; }
  .socials a { width: 38px; height: 38px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; color: var(--text-tertiary); background: var(--surface-sunken); transition: background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), transform var(--duration-fast) var(--ease-standard); }
  .socials a:hover { background: var(--action-primary); color: var(--text-on-accent); }
  .socials a:active { transform: scale(0.94); }
  .socials svg { width: 17px; height: 17px; }
  .foot-col h4 { margin: 0 0 16px; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-tertiary); font-weight: 500; }
  .foot-col a { display: block; font-size: 14px; color: var(--text-secondary); margin-bottom: 12px; }
  .foot-col a:hover { color: var(--text-primary); }
  .foot-bottom { display: flex; justify-content: space-between; align-items: center; gap: 24px; margin-top: 64px; padding-top: 24px; border-top: 1px solid var(--border-subtle); font-size: 13px; color: var(--text-tertiary); }

  /* ---- Content renders statically and always visible. The design
     system favors calm; no from-hidden entrances that a paused or
     backgrounded render context could trap at opacity 0. The
     .reveal hooks are kept inert for an optional future entrance. - */
  .reveal { opacity: 1; transform: none; }

  /* ---- Responsive ------------------------------------------------ */
  /* The wide-screen (min-width) steps live at the very END of this file, after
     the multi-page section — .page-head and friends are declared down there at
     the same specificity, so a wide-screen override placed here would lose to
     them and those pages would never scale up. */
  @media (max-width: 1040px) {
    .metrics { grid-template-columns: repeat(3, 1fr); gap: 44px 24px; }
    .plans { grid-template-columns: repeat(2, 1fr); max-width: 680px; margin-left: auto; margin-right: auto; }
  }
  /* ---- Feature grid stacks at ≤1180, not ≤860 --------------------
     The two-column feature grid used to hold until 860px, which put the
     demo frames in a 351–510px column across the whole 861–1180 band (iPad
     landscape, un-maximised desktop windows): the videos were cover-cropped
     to a 440px-tall sliver and the live manage demo, which scales its 1176px
     canvas to the column, rendered 13px UI text at 3.9–5.6px. Stacking here
     gives every demo the full column (capped so four of them don't become
     four 1100×900 slabs; the cap matches the copy's own ~46ch measure, both
     left-aligned). The demo videos are near-square app frames shown at a
     fixed 440px with object-fit:cover — fine in the two-column grid, but
     once single-column the box ratio no longer matches and cover crops away
     the real content (results table), leaving a grey void. Drop the fixed
     height so each video shows its full frame at its natural ratio. */
  @media (max-width: 1180px) {
    .feat-grid { grid-template-columns: 1fr; gap: 36px; }
    .feat-grid.rev .copy { order: 0; }
    .feat-demo { height: auto !important; object-fit: contain; width: 100%; max-width: 880px; }
    /* The cap has to move to the wrapper as well, or the end card — which is
       inset:0 on the wrapper — would sit wider than the video it covers. */
    .demo-shot { width: 100%; max-width: 880px; }
  }
  @media (max-width: 860px) {
    .wrap { padding: 0 22px; }
    /* Collapse desktop nav into the hamburger sheet; auth lives in the sheet. */
    .nav-links { display: none; }
    .nav-right .btn-signin, .nav-right .btn-ink { display: none; }
    .nav-burger { display: inline-flex; }
    .mobile-menu { display: block; }
    /* Trim the marketing vertical rhythm so phones don't feel empty. */
    .band { padding: 72px 0; }
    .metrics { margin-top: 48px; }
    .feat-head { padding: 80px 0 4px; }
    section.feat { padding: 44px 0; }
    .solutions, .pricing, .demo, .coverage, .faq { padding: var(--section-sm) 0; }
    .hero { padding: 64px 0 40px; min-height: auto; }
    .hero p.sub { font-size: 17px; }
    /* Stack the split: copy first (centered), whole globe below the fold-free */
    .hero-grid { grid-template-columns: 1fr; text-align: center; gap: 8px; }
    .hero-grid h1 { margin: 0 auto; }
    .hero-grid p.sub { margin: 22px auto 0; max-width: 17em; }
    .hero-grid .cta { justify-content: center; }
    .hero-globe { margin: 30px auto 0; max-width: 400px; }
    /* (feature grid already single-column from the ≤1180 block above) */
    .feat .copy .bullets { grid-template-columns: 1fr; }
    .metrics { grid-template-columns: repeat(2, 1fr); }
    /* The mono metric numbers stay 48px while their captions and everything
       around them shrink on mobile — oversized and jarring once stacked. Scale
       them down with the layout. */
    .metric .num { font-size: 40px; }
    .demo-grid { grid-template-columns: 1fr; gap: 40px; }
    .demo-copy h2 { font-size: calc(var(--ts) * 36px); }
    .showcase image-slot { height: 340px !important; }
    .creator-showcase { grid-template-columns: 1fr; gap: 10px; }
    .creator-copy { text-align: center; }
    .coverage h2 { max-width: none; margin-left: auto; margin-right: auto; font-size: clamp(46px, 11vw, 66px); }
    .coverage p.cov-sub { margin-left: auto; margin-right: auto; }
    .creator-deck { width: min(620px, 100%); height: 530px; margin: 12px auto 0; }
    .creator-disclaimer { width: min(620px, 100%); margin: 0 auto; }
    /* Below this width the deck narrows to roughly the main card's own 338px,
       so there's no side gap left for a bottom-anchored badge to sit in — it
       lands on the card's text instead. Float it over the image corner like
       --fit does, rather than trying to preserve the desktop bottom offset. */
    .creator-insight--reach { top: 228px; bottom: auto; }
    .sol-grid { grid-template-columns: 1fr; }
    .foot-grid { grid-template-columns: 1fr 1fr; gap: 36px 24px; }
    .foot-statement { font-size: 21px; }
  }
  @media (max-width: 680px) {
    /* Three stacked full-height cards make for a long, monotonous scroll — and
       two of the tiers aren't even buyable yet. Turn the grid into a horizontal
       swipe carousel: one card tall, snap per card, with the next card peeking
       to signal there's more. Full-bleed via negative margin, re-inset by the
       same padding so the first card lines up with the rest of the page. */
    .plans {
      display: flex; grid-template-columns: none; max-width: none;
      margin: 48px -22px 0; padding: 4px 22px 6px; gap: 14px;
      align-items: stretch;
      overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-left: 22px;
      -webkit-overflow-scrolling: touch; scrollbar-width: none;
    }
    .plans::-webkit-scrollbar { display: none; }
    .plan { flex: 0 0 84%; scroll-snap-align: start; }
    .plans-dots { display: flex; justify-content: center; gap: 8px; margin-top: 22px; }
    .plans-dots .pd {
      width: 7px; height: 7px; border-radius: 999px;
      background: var(--border-strong, #cbd5e1);
      transition: width 0.25s ease, background 0.25s ease;
    }
    .plans-dots .pd[aria-current="true"] { width: 22px; background: var(--iris-600); }
    .creator-deck { height: 470px; transform: scale(.88); transform-origin: top center; margin-bottom: -57px; }
    .creator-disclaimer { text-align: center; }
  }
  @media (max-width: 460px) {
    .metrics { grid-template-columns: 1fr; gap: 36px; }
    .metric .num { font-size: 34px; }
    .nav-right .btn-demo { display: none; }
  }

  /* ---- Phone-only refinements (≤600px) --------------------------- */
  @media (max-width: 600px) {
    /* Chinese hero is dense full-width CJK glyphs (and falls back to a heavier
       CJK serif — Newsreader is Latin-only). fitHeadings() only shrinks a line
       until it *fills* the column, so on a phone the zh hero ends up edge-to-edge
       with no breathing room, while proportional Latin reads airier at the same
       fit. Cap the zh hero smaller here; fitHeadings honors it as the ceiling. */
    html[lang^="zh"] .hero h1 { font-size: clamp(32px, 10.5vw, 52px); }
    /* Per-feature serif titles are nowrap curated lines capped at 15ch on desktop;
       on a phone that cap lets the long zh lines spill past the column and clip.
       Drop it here so fitHeadings() sizes them against the real column width. */
    .feat .copy h3 { max-width: none; }
    /* solutions/pricing titles wrap naturally (no .ln), so fitHeadings leaves them
       flush; cap the zh ones on phones for the same side breathing room. */
    html[lang^="zh"] :is(.sol-head h2, .pricing-head h1, .pricing-head h2) {
      font-size: clamp(28px, 8.5vw, 36px);
    }

    .demo-card { padding: 24px 20px; }
    /* The date+time picker can't hold two columns on a phone — stack it,
       let it fill the card width, and lay the slots out as a grid. */
    .datepick-pop { width: 100%; left: 0; right: 0; padding: 16px; }
    .dp-body { flex-direction: column; gap: 16px; }
    .dp-cal { flex: 1 1 auto; }
    .dp-day { height: 34px; font-size: 13px; }
    .dp-times {
      border-left: 0; padding-left: 0;
      border-top: 1px solid var(--border-subtle); padding-top: 14px;
    }
    .dp-slots {
      flex-direction: row; flex-wrap: wrap; gap: 8px;
      max-height: 200px; padding-right: 0;
    }
    .dp-slot { flex: 1 0 calc(33.333% - 6px); padding: 9px 0; }
  }

  /* ============================================================
     Multi-page additions — plain nav link + secondary pages
     ============================================================ */

  /* Sign-in: quiet text link on the right of the nav */
  .nav-right .btn-signin { background: transparent; color: var(--text-secondary); padding: 0 8px; height: auto; }
  .nav-right .btn-signin:hover { color: var(--text-primary); background: transparent; }

  /* Plain (non-dropdown) nav item, styled to match .nav-trigger */
  .nav-links a.nav-link-plain {
    display: inline-flex; align-items: center;
    /* Reserve the same trailing width the dropdown items spend on their
       chevron (13px icon + 5px gap), so the three nav labels space evenly. */
    padding-right: 18px;
    font-size: 14px; font-weight: 500; color: var(--text-secondary);
    transition: color var(--duration-fast) var(--ease-standard);
  }
  .nav-links a.nav-link-plain:hover { color: var(--text-primary); }
  .nav-links a.nav-link-plain[aria-current="page"] { color: var(--text-primary); }

  /* Sign-up (auth) page — centered brand form. Reuses .demo-card / .field /
     .demo-success so it stays on the design system; only layout is added here. */
  .auth-main { display: flex; align-items: center; }
  .auth { width: 100%; padding: 80px 0 96px; }
  .auth-head { text-align: center; max-width: 30rem; margin: 0 auto 28px; padding: 0 20px; }
  .auth-head h1 { font-size: calc(var(--ts) * 38px); line-height: 1.1; letter-spacing: -0.02em; }
  .auth-head .auth-sub { margin: 14px auto 0; max-width: 38ch; font-size: 16px; line-height: 1.6; color: var(--text-secondary); }
  .auth-card { width: 100%; max-width: 440px; margin: 0 auto; }
  .auth-alt { margin: 20px 0 0; text-align: center; font-size: 14px; color: var(--text-secondary); }
  /* /signup after 2026-09-02: one sentence and one button, no form. The card
     keeps .demo-card's surface so the page still matches the booking form it
     sits beside, but nothing inside it needs the field rhythm any more. */
  .auth-handoff-body {
    margin: 0 0 22px;
    text-align: center;
    font-size: 15px;
    line-height: 1.65;
    color: var(--text-secondary);
  }
  .auth-alt a { color: var(--text-accent); font-weight: 500; }
  .auth-alt a:hover { color: var(--interactive-active); }
  .signup-success { padding-top: 8px; }

  /* Generic page header for secondary pages */
  #contact { scroll-margin-top: 96px; }
  .page-head { padding: 88px 0 8px; text-align: center; }
  .page-head h1 { margin: 0 auto; max-width: 18ch; font-size: calc(var(--ts) * 56px); line-height: 1.06; }
  .page-head p.page-sub { margin: 20px auto 0; max-width: 54ch; font-size: 18px; line-height: 1.62; color: var(--text-secondary); }

  /* Help Center category grid */
  .help { padding: 40px 0 var(--section); }
  .help-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 56px; }
  .help-card { display: block; background: var(--surface-card); border-radius: var(--radius-2xl); padding: 28px 26px; box-shadow: var(--shadow-card);
    transition: box-shadow var(--duration-base) var(--ease-standard), transform var(--duration-fast) var(--ease-standard); }
  .help-card:hover { box-shadow: var(--shadow-card-hover); transform: translateY(-2px); }
  .help-card:active { transform: translateY(0); }
  .help-card .help-ico { width: 42px; height: 42px; border-radius: 12px; background: var(--surface-sunken); color: var(--text-accent); display: inline-flex; align-items: center; justify-content: center; }
  .help-card .help-ico svg { width: 20px; height: 20px; }
  .help-card h3 { margin: 18px 0 0; font-family: var(--font-serif); font-weight: 400; letter-spacing: -0.018em; font-size: 21px; }
  .help-card p { margin: 10px 0 0; font-size: 14px; line-height: 1.6; color: var(--text-secondary); }

  /* About prose + Contact card */
  .about-prose { max-width: 720px; margin: 0 auto; padding: 36px 0 var(--section-sm); }
  .about-prose p { font-size: 18px; line-height: 1.72; color: var(--text-secondary); margin: 0 0 20px; }
  .about-prose h2 { font-family: var(--font-serif); font-weight: 400; letter-spacing: -0.018em; font-size: 30px; margin: 48px 0 16px; color: var(--text-primary); }
  .contact-card { max-width: 720px; margin: 0 auto var(--section); background: var(--surface-card); border-radius: var(--radius-2xl); padding: 44px 40px; box-shadow: var(--shadow-card); text-align: center; }
  .contact-card h2 { font-family: var(--font-serif); font-weight: 400; letter-spacing: -0.018em; font-size: 28px; }
  .contact-card p { margin: 14px auto 0; max-width: 46ch; font-size: 16px; line-height: 1.62; color: var(--text-secondary); }
  .contact-card a.contact-mail { display: inline-block; margin-top: 24px; font-family: var(--font-mono); font-size: 16px; color: var(--text-accent); }
  .contact-card a.contact-mail:hover { color: var(--interactive-active); }

  /* Legal prose (privacy / terms) */
  .legal { max-width: 720px; margin: 0 auto; padding: 28px 0 var(--section); }
  .legal .legal-meta { font-size: 14px; color: var(--text-tertiary); margin-bottom: 28px; }
  .legal h2 { font-family: var(--font-serif); font-weight: 400; letter-spacing: -0.018em; font-size: 26px; margin: 40px 0 12px; }
  .legal h3 { font-size: 17px; font-weight: 600; margin: 24px 0 8px; color: var(--text-primary); }
  .legal p, .legal li { font-size: 16px; line-height: 1.72; color: var(--text-secondary); }
  .legal ul { margin: 12px 0; padding-left: 22px; }
  .legal li { margin: 6px 0; }
  .legal strong { color: var(--text-primary); font-weight: 600; }
  .legal a { color: var(--text-accent); text-decoration: underline; text-underline-offset: 2px; }
  .legal a:hover { color: var(--interactive-active); }
  /* In-page table of contents for the long legal pages. */
  .legal .legal-toc { margin: 8px 0 8px; padding: 18px 22px; background: var(--surface-sunken); border-radius: var(--radius-md); }
  .legal .legal-toc h2 { font-family: var(--font-sans); font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-tertiary); margin: 0 0 10px; }
  .legal .legal-toc ul { margin: 0; padding-left: 0; list-style: none; columns: 2; column-gap: 28px; }
  .legal .legal-toc li { margin: 4px 0; font-size: 14px; break-inside: avoid; }
  .legal .legal-toc a { color: var(--text-secondary); text-decoration: none; }
  .legal .legal-toc a:hover { color: var(--text-accent); text-decoration: underline; }
  .legal h2[id] { scroll-margin-top: 92px; }

  /* Blog placeholder list */
  .blog { padding: 40px 0 var(--section); }
  .blog-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 56px; }
  .blog-card { background: var(--surface-card); border-radius: var(--radius-2xl); overflow: hidden; box-shadow: var(--shadow-card); display: flex; flex-direction: column; }
  .blog-card .blog-thumb { display: block; width: 100%; }
  .blog-card .blog-body { padding: 22px 24px 26px; }
  .blog-card .blog-tag { font-size: 12px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-accent); }
  .blog-card h3 { margin: 12px 0 0; font-family: var(--font-serif); font-weight: 400; letter-spacing: -0.018em; font-size: 20px; line-height: 1.22; }
  .blog-card p { margin: 10px 0 0; font-size: 14px; line-height: 1.6; color: var(--text-secondary); }
  .blog-empty { text-align: center; max-width: 48ch; margin: 36px auto 0; font-size: 16px; line-height: 1.62; color: var(--text-tertiary); }

  @media (max-width: 860px) {
    .help-grid, .blog-grid { grid-template-columns: 1fr; }
    .legal .legal-toc ul { columns: 1; }
    .page-head { padding: 64px 0 8px; }
    .page-head h1 { font-size: calc(var(--ts) * 40px); }
    .auth { padding: 48px 0 64px; }
    .auth-head h1 { font-size: calc(var(--ts) * 32px); }
  }

  /* ============================================================
     Wide screens (≥1400px)

     Above 1320px the page used to freeze. .wrap caps at --content-wide and
     every size in this file is fixed px, so the largest breakpoint the file
     had was `max-width: 1040px` — nothing at all above the band's own width.
     On a 27" 2560px display that left 620px of dead margin per side (48% of
     the screen) and, because nothing scaled up, made the whole design read
     SMALLER rather than bigger.

     These two steps raise the band, the display tier, the vertical rhythm and
     the hero art together, so a wide screen shows the same design enlarged
     instead of a 1320px page floating in the middle of a lot of nothing.
     Below 1400px nothing here applies and the page renders exactly as before.

     WHY 1400/1800 AND NOT 1600/2000, which is where these started: those were
     picked while testing at 2560 and they turned out to clear every common
     laptop — a 1440 MacBook Air, a 1512 MacBook Pro 14", a 27" running at
     half-width — so in day-to-day use none of this was ever reached. Measure at
     the width the page is actually read at, not at the width you happen to be
     testing in.

     WHY THIS SITS AT THE END OF THE FILE, not up in the Responsive section
     where the max-width steps are: the multi-page rules above declare
     .page-head h1 / .page-head p.page-sub at the same specificity these
     overrides use. Placed earlier, the later declaration wins and /about,
     /help, /blog and the legal pages keep their 1320px headline on a 2560px
     screen. Anything added here has to stay after every rule it overrides.

     Deliberately NOT scaled: the prose measures (.about-prose, .legal,
     .contact-card) and every ch-based max-width. Those cap line length for
     readability — widening them on a big screen makes reading worse, not
     better, which is the entire reason they exist. .faq-inner is the one
     exception and does grow: it wraps an accordion of short question rows, not
     a text column, and the answers inside carry their own 66ch cap — so the
     measure that actually matters stays protected either way.

     Cards get their interior scaled too, not just their outer box. A .plan or
     .sol-card that goes from 400px to 480px wide while its padding, its label
     type and its 13px values all stay put doesn't read as bigger, it reads as
     emptier — the space-between rows in particular stretch into two lonely
     ends with a gulf in the middle.

     On the type steps: the 1800px tier lands on the real display scale one rung
     up (60/48/40 — see landing-pinned.css); 1400px is the transition band and
     interpolates (52/44/36), because the tier's 8–12px steps are far too coarse
     to express the ~8% nudge that width deserves.
     ============================================================ */
  @media (min-width: 1400px) {
    :root {
      /* min(), not a bare 1520px: a fixed band equal to (or wider than) the
         breakpoint itself leaves zero outer margin right at the breakpoint and
         the page reads as bleeding off both edges. Capping against the viewport
         guarantees 40px a side at every width — plus .wrap's own 40px padding,
         so content never sits closer than 80px to the screen edge — while still
         opening up to the full 1520 as soon as there's room. 80px is also
         comfortably above any classic scrollbar, so 100vw including the
         scrollbar can't push this into a horizontal overflow. */
      --content-wide: min(1520px, calc(100vw - 80px));
      --display-lg: 52px;
      --display-md: 44px;
      --display-sm: 36px;
      --section:    140px;
      --section-sm: 96px;
      --nav-h:      80px;
    }
    /* The bar was 72px tall with 14px links at every width, so on a wide screen
       it reads as a thin strip of small type over a much larger page. It grows
       with everything else here — and because --nav-h drives the hero offset and
       the anchor scroll-margins too, those stay correct without being touched. */
    .nav-links { gap: 32px; }
    .nav-links a, .nav-links .nav-trigger { font-size: 15px; }
    .nav-links .nav-trigger .chev { width: 14px; height: 14px; }
    .nav-right { gap: 16px; }
    .nav-right .btn { height: 48px; font-size: 16px; padding: 0 24px; }
    /* Brand grows with the bar. Two levers, and only two: size, and the weight
       500 set on the base rule. The design system's imagery rule still keeps
       gradients off type — the hero globe is the single sanctioned exception and
       only because it sits beside the headline, not behind it — so no gradient
       fill, and no cut heavier than 500.
       Mark and wordmark stay on the same number so the 1.23 ink ratio holds.
       The gap scales with them (10px at the base 30px, so 34/30 × 10 ≈ 11) —
       it used to CLOSE as they grew, 10 → 9 → 8, which this comment defended as
       making the pair read as one object. It doesn't: at 34px and 38px the
       wordmark's opening serif ran into the mark's upper-right dart. Kerning is
       proportional, so the gap has to be too. */
    .brand { gap: 11px; }
    .brand .logo-mark { width: 34px; height: 34px; }
    .brand .name { font-size: 34px; }
    /* fitHeadings() only ever shrinks a heading to fit its column, never grows
       it — so raising the CSS ceiling is the whole change; the JS follows. */
    .hero h1 { font-size: calc(var(--ts) * 92px); }
    .hero p.sub { font-size: 21px; max-width: 50ch; }
    /* Copy column takes the extra width (the headline grew); the globe gets a
       smaller share, since a bigger sphere adds less than a bigger headline. */
    .hero-grid { grid-template-columns: 1.06fr 0.94fr; gap: 88px; }
    .hero-globe { max-width: 620px; }
    .feat-grid { gap: 96px; }
    /* No .feat-demo ratio override here on purpose. This block used to pin
       29/22, the ratio the 1320px layout was tuned at, and it survived the
       switch to scene videos only because .manage-demo — the live GSAP
       reconstruction that stood in for feature 3 — was authored at exactly that
       ratio on a 1176×892 stage. That demo is now manage.mp4 like the other
       four, so every .feat-demo is a 1600×1306 video and takes 800/653 from the
       base .feat block. Derive a demo's ratio from its own source, never from
       the container width: a box pinned to the column crops a different band at
       every breakpoint. */
    .feat-head p, .sol-head p, .pricing-head p, .feat .copy p.lead { font-size: 19px; }
    /* The ch caps are what actually make a wide screen feel empty: headings are
       nowrap and fill their column, while body copy stays locked at 44–54ch, so
       the two sit at wildly different widths and the column shows through
       between them. Widening the caps in step with the column closes that gap —
       these are still well inside a readable measure (~33 CJK glyphs / ~55
       Latin characters per line at this tier), which is why the prose pages
       below, set for long-form reading, keep their original caps. */
    .coverage p.cov-sub { font-size: 18px; }
    /* Only the column-bound, left-aligned body copy gets a wider cap. The
       centred section sub-heads (.feat-head p, .sol-head p, .pricing-head p,
       .cov-sub) deliberately float in the middle of a wide band — widening them
       doesn't fill anything, it just re-breaks a two-line sentence into one and
       a half and leaves an orphan on the last line. Balance their wrap instead. */
    .feat .copy p.lead { max-width: 52ch; }
    .feat-head p, .sol-head p, .pricing-head p, .coverage p.cov-sub { text-wrap: balance; }
    .metric .num { font-size: 54px; }
    .metric .cap { font-size: 14px; }
    .ai-chat { padding: 32px; }
    .ai-chat .msg-user, .ai-chat .msg-agent .body { font-size: 16px; }
    .demo-copy h2 { font-size: calc(var(--ts) * 58px); }
    .demo-copy p.csub { font-size: 19px; max-width: 48ch; }
    .plans, .sol-grid { gap: 24px; }
    .sol-card { padding: 34px 32px; }
    .sol-card .sol-name { font-size: 24px; }
    .sol-card p { font-size: 17px; }
    .plan { padding: 38px 30px; }
    .plan .plan-name { font-size: 36px; }
    .plan .price-amount { font-size: 58px; }
    .plan .plan-for, .plan .feat-list li { font-size: 15px; }
    .plan .feat-list .val { font-size: 14px; }
    .demo-card { padding: 38px; }
    .field label { font-size: 14px; }
    .field input, .datepick-trigger { height: 50px; font-size: 16px; }
    .faq-inner { max-width: 880px; }
    .faq-item summary { font-size: 18px; padding: 24px 4px; }
    .faq-answer { font-size: 17px; }
    .foot-grid { gap: 64px; }
    .foot-statement { font-size: 26px; }
    .foot-col a, .foot-tag { font-size: 15px; }
    .page-head h1 { font-size: calc(var(--ts) * 62px); }
    .page-head p.page-sub { font-size: 19px; }
  }
  @media (min-width: 1800px) {
    :root {
      --content-wide: min(1760px, calc(100vw - 80px));
      --display-lg: 60px;
      --display-md: 48px;
      --display-sm: 40px;
      --section:    160px;
      --section-sm: 108px;
      --nav-h:      88px;
    }
    .nav-links { gap: 36px; }
    .nav-links a, .nav-links .nav-trigger { font-size: 16px; }
    .nav-links .nav-trigger .chev { width: 15px; height: 15px; }
    .nav-right { gap: 18px; }
    .nav-right .btn { height: 50px; font-size: 17px; padding: 0 26px; }
    /* Mark and wordmark scale together so the 1.23 ink ratio set on .logo-mark
       holds, and translateY(0.1em) keeps compensating the right amount — the
       ink offset is 0.101em at every size the nav uses, so it needs no value of
       its own here. The gap scales with them for the reason given in the 1400px
       block: 38/30 × 10 ≈ 13. */
    .brand { gap: 13px; }
    .brand .logo-mark { width: 38px; height: 38px; }
    .brand .name { font-size: 38px; }
    .hero h1 { font-size: calc(var(--ts) * 102px); }
    .hero p.sub { font-size: 22px; max-width: 54ch; }
    .hero-grid { gap: 112px; }
    .hero-globe { max-width: 720px; }
    .feat-grid { gap: 112px; }
    .feat-head p, .sol-head p, .pricing-head p, .feat .copy p.lead { font-size: 20px; }
    .coverage p.cov-sub { font-size: 19px; }
    .feat .copy p.lead { max-width: 56ch; }
    .metric .num { font-size: 60px; }
    .metric .cap { font-size: 15px; }
    .ai-chat { padding: 36px; }
    .ai-chat .msg-user, .ai-chat .msg-agent .body { font-size: 17px; }
    .demo-copy h2 { font-size: calc(var(--ts) * 64px); }
    .demo-copy p.csub { font-size: 20px; max-width: 52ch; }
    .plans, .sol-grid { gap: 28px; }
    .sol-card { padding: 38px 36px; }
    .sol-card .sol-name { font-size: 26px; }
    .sol-card p { font-size: 18px; }
    .plan { padding: 42px 34px; }
    .plan .plan-name { font-size: 40px; }
    .plan .price-amount { font-size: 64px; }
    .plan .plan-for, .plan .feat-list li { font-size: 16px; }
    .plan .feat-list .val { font-size: 15px; }
    .demo-card { padding: 42px; }
    .field input, .datepick-trigger { height: 52px; }
    .faq-inner { max-width: 940px; }
    .faq-item summary { font-size: 19px; }
    .faq-answer { font-size: 18px; }
    .foot-grid { gap: 72px; }
    .foot-statement { font-size: 28px; }
    .foot-col a, .foot-tag { font-size: 16px; }
    .page-head h1 { font-size: calc(var(--ts) * 68px); }
    .page-head p.page-sub { font-size: 20px; }
  }

  /* ---- Tall viewports: stop the hero padding itself out ------------
     `.hero` is `min-height: calc(100vh - 72px)` with the content centred, so
     every pixel the viewport has beyond the content becomes dead space split
     above and below. That was tuned on a ~800px-tall laptop, where it leaves a
     comfortable 76px; the slack grows linearly with viewport height and hits
     616px (308 a side) on a 1440px-tall 27". Phones already hit this and the
     ≤860px block fixed it there by dropping min-height entirely — this is the
     same fix for the other end.

     Keyed on HEIGHT, not width, because height is what actually drives the bug
     and the two don't track each other: a 1024×1366 tablet in portrait is far
     below any width step yet carries the most slack on the page, while a
     2560×800 ultrawide clears every width step and has almost none. Pairing
     this with the width steps would fix the second and miss the first. Above
     940px tall the hero is sized
     by its content with explicit padding for breathing room, exactly like the
     phone layout; at or below that the original full-screen behaviour stands
     (a 1440×900 laptop keeps its 88px-a-side, which reads as intentional).
     The 900px width floor keeps this off phones in portrait, so the ≤860px
     block's own padding is not overridden from down here. */
  @media (min-width: 900px) and (min-height: 940px) {
    .hero { min-height: 0; padding: 96px 0 120px; }
  }

  /* ---- 2K / 4K desktops: scale the 1800px layout, don't add a fourth tier --
     The two tiers above stop at 1760px of content. That is 92% of a 1920
     viewport, 69% of a 27" 2K at 100% (2560) and 46% of a 32" 4K at 100%
     (3840) — on the 4K the page sat as a phone-sized column between two
     1040px gutters, and on the 2K every control read a size too small.

     A third explicit tier was the obvious move and the wrong one. The tiers
     above bump ~55 declarations each and still leave the fixed 13–15px
     leftovers alone (feature bullets, plan rows, footer fine print, form
     labels, the coverage logo strip); at ×1.2 that mismatch is visible, at
     ×1.5 it is a different page. What these widths need is the 1920 layout
     rendered at the same PHYSICAL size the 24" 1080p user sees — 16px on a
     92ppi 24" is 4.4mm; a 109ppi 27" 2K wants ×1.2 and a 138ppi 32" 4K wants
     ×1.5 for the same 4.4mm — and that is exactly what CSS zoom on the root
     does: every px in the page scales together, ratios intact, and the layout
     below keeps running as if the viewport were ~2100–2560px, i.e. the ≥1800
     tier. 1760px × 1.5 = 2640 of a 3840 viewport, the same 69% the 2K has.

     Steps are keyed to the CSS viewport the OS actually hands the browser:
     2400–2999 catches 2560 (27" 2K @100%); 3000–3399 catches 3072 (32" 4K
     @125%); 3400+ catches 3840 (32" 4K @100%). A 4K at 150% scaling arrives
     as 2560 and lands in the first step, which is what its owner expects.

     Media queries evaluate against the unzoomed viewport, so the tiers above
     still match on their real widths; vw/svh inside the page are scaled by
     zoom in Chromium and left unscaled in WebKit — the only two places this
     page uses them (--content-wide's min() and the hero's min-height) are
     both capped or, on these viewports, already switched off by the tall-
     viewport rule above, so neither reading changes the layout. The globe
     canvas needs no help (hero-globe.js resize() explains why).
     `zoom` has been standard since Chrome 128 / Firefox 126 / Safari 4.

     These three steps are the no-JS fallback. With JS, landing.js overrides
     them with a CONTINUOUS factor clamp(1, viewport/2133, 1.5) set inline —
     the same curve, without the 20% / 17% / 7% size jumps at 2400 / 3000 /
     3400 — and it refuses to recompute when the viewport changed because the
     user pressed Ctrl-plus, so browser zoom is not eaten by the page shrinking
     its own factor. Details on that block. Keep the two in step if retuning. */
  @media (min-width: 2400px) {
    html { zoom: 1.2; }
    /* "Fill the first screen" is meaningless once the page is zoomed and the
       screen is this tall; size the hero by content, same as the tall rule. */
    .hero { min-height: 0; padding: 96px 0 120px; }
  }
  @media (min-width: 3000px) { html { zoom: 1.4; } }
  @media (min-width: 3400px) { html { zoom: 1.5; } }
