
    * { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
    :root {
      --bg-primary: #0a0a0a;
      --bg-secondary: #121212;
      --bg-tertiary: #1f1f1f;
      --bg-hover: #2a2a2a;
      --text-primary: #ffffff;
      --text-secondary: #888888;
      --text-muted: #555555;
      --border-color: #2a2a2a;
      --accent: #ffffff;
      --accent-dim: rgba(255,255,255,0.1);
      --shadow: 0 4px 24px rgba(0,0,0,0.4);
      --radius: 16px;
      --radius-sm: 10px;
      --radius-xs: 6px;
      /* Wide desktop product stage. Visuals, grids and simulators can use the
         available canvas; prose keeps its own readable measure below. */
      --stage-max: 1680px;
      /* ===== Apple polish tokens: motion =====
         Four decelerating curves and one press curve. Nothing overshoots by
         more than 4%: the old --ease-settle (1.56) and --ease-glide (1.35)
         put a 56% / 35% rubber-band on every hover lift and sliding
         highlight on the page, which is what made the whole thing read
         springy and templated. Real surfaces decelerate; they do not bounce. */
      --ease-settle: cubic-bezier(0.32, 1.04, 0.5, 1);    /* pop / badge-in: a hair of settle */
      --ease-glide: cubic-bezier(0.25, 1, 0.35, 1);       /* sliding highlights: pure decel */
      --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);   /* modal FLIP / pane slides */
      --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);     /* scroll reveals */
      --ease-pill: cubic-bezier(0.32, 0.72, 0, 1);        /* iOS segmented pill */
      --ease-press: cubic-bezier(0.4, 0, 0.6, 1);         /* press-down */
      --dur-press: 0.08s;
      --dur-fast: 0.25s;
      --dur-move: 0.45s;
      --dur-reveal: 0.7s;
      /* ===== Apple polish tokens: surfaces ===== */
      --hairline: rgba(255,255,255,0.08);
      --hairline-hover: rgba(255,255,255,0.18);
      --hairline-strong: rgba(255,255,255,0.35);
      --glass-bg: rgba(20,20,20,0.55);
      --glass-blur: blur(28px);
      --edge-top: inset 0 0.5px 0 rgba(255,255,255,0.06);
      --elev-1: 0 1px 2px rgba(0,0,0,0.25), 0 4px 14px rgba(0,0,0,0.22);
      --elev-2: 0 2px 6px rgba(0,0,0,0.3), 0 14px 36px rgba(0,0,0,0.42);
      --elev-3: 0 30px 80px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04);
      /* One typographic voice throughout the landing page. `system-ui`
         resolves to the variable SF Pro family on Apple platforms, including
         its automatic optical sizing. Other platforms receive their native
         UI sans rather than a visually unrelated bundled webfont. */
      --font-sf: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro', 'Helvetica Neue', 'Segoe UI', sans-serif;

      /* Apple-style semantic marketing scale: body remains stable while
         display roles scale fluidly with the viewport. */
      --type-hero: clamp(48px, 5.8vw, 80px);
      --type-section: clamp(40px, 4.4vw, 64px);
      --type-feature: clamp(32px, 3.2vw, 48px);
      --type-title: 19px;
      --type-body: 17px;
      --type-callout: 16px;
      --type-subhead: 15px;
      --type-footnote: 13px;
      --type-caption: 12px;
      --track-hero: -0.04em;
      --track-section: -0.03em;
      --track-feature: -0.02em;
      --track-title: -0.01em;
    }
    html { scroll-behavior: smooth; }
    body {
      font-family: var(--font-sf);
      font-optical-sizing: auto;
      font-kerning: normal;
      font-synthesis: none;
      background: var(--bg-primary);
      color: var(--text-primary);
      line-height: 1.5;
      min-height: 100vh;
      -webkit-font-smoothing: antialiased;
      overflow-x: hidden;
    }
    a { color: inherit; text-decoration: none; }
    img { display: block; max-width: 100%; }

    /* ===== NAV ===== */
    /* Floating island nav: seamless full-width bar at the top of the page,
       detaches into a rounded frosted-glass island once you scroll. */
    .nav {
      position: sticky;
      top: 0;
      z-index: 100;
      background: transparent;
      padding: 0 12px;
      transition: padding-top 0.45s var(--ease-out-quint);
    }
    .nav-inner {
      max-width: 1280px;
      margin: 0 auto;
      padding: 14px 12px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      position: relative;
      border: 1px solid transparent;
      border-radius: 20px;
      background: rgba(12, 12, 12, 0);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      transition: margin 0.45s var(--ease-out-quint), max-width 0.45s var(--ease-out-quint),
                  padding 0.45s var(--ease-out-quint), background 0.45s ease,
                  border-color 0.45s ease, box-shadow 0.45s ease;
    }
    .nav.scrolled {
      padding-top: 10px;
    }
    .nav.scrolled .nav-inner {
      margin: 0 auto;
      max-width: 1080px;
      padding: 8px 14px;
      background: rgba(14, 14, 14, 0.6);
      border-color: var(--hairline);
      box-shadow: var(--elev-2);
    }
    @media (max-width: 768px) {
      .nav { padding: 0 8px; }
      .nav.scrolled { padding-top: 8px; }
    }
    @media (min-width: 769px) {
      .nav-inner > .svc-switch {
        margin-left: auto;
        margin-right: auto;
      }
    }
    .nav-logo {
      display: flex;
      align-items: center;
      gap: 10px;
      font-size: 18px;
      font-weight: 800;
      letter-spacing: -0.3px;
    }
    .nav-logo .k {
      font-family: var(--font-sf);
      font-optical-sizing: auto;
      font-size: 32px;
      font-weight: 700;
      letter-spacing: -0.04em;
      color: var(--text-primary);
      padding: 0 2px;
      line-height: 1;
    }
    .nav-links {
      display: flex;
      align-items: center;
      gap: 28px;
    }
    .nav-links a {
      font-size: 14px;
      font-weight: 500;
      color: var(--text-secondary);
      transition: color 0.2s ease;
    }
    .nav-links a:hover { color: var(--text-primary); }
    /* The chip material, not a white fill (The No Pure White Rule,
       DESIGN.md:190). It still outranks the plain nav links, which are text
       only, and it keeps its weight through the label and the padding. */
    .nav-cta {
      padding: 9px 18px;
      background: var(--bg-hover);
      color: var(--text-primary);
      border-radius: 11px;
      font-size: 13px;
      font-weight: 700;
      transition: transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1)), box-shadow 0.25s ease, border-color 0.25s ease;
      border: 1px solid var(--hairline-hover);
    }
    .nav-cta:hover { border-color: var(--hairline-strong); transform: translateY(-1px); box-shadow: 0 2px 3px rgba(0,0,0,0.5), 0 8px 20px rgba(0,0,0,0.5), inset 0 -1px 0 rgba(0,0,0,0.16); }
    .nav-cta:active { transform: scale(0.94); transition: transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
    /* .nav-links a is 0-1-1 and .nav-cta is 0-1-0, so neither the colour nor
       the weight above ever reached this button: it was measured at
       rgb(136,136,136) weight 400. Scoped to the same 0-2-1 the link rule
       needs, so the CTA actually reads as the CTA. */
    .nav-links a.nav-cta { color: var(--text-primary); font-weight: 700; }

    /* iOS-style idle breathing on primary CTAs — barely perceptible
       scale pulse signaling "alive". Disabled on hover/active states
       since explicit interaction takes priority. */
    .cta-primary:hover,
    .cta-primary:active,
    .nav-cta:hover,
    .nav-cta:active,
    .price.featured .price-cta:hover,
    .price.featured .price-cta:active {
      animation: none;
    }
    @media (prefers-reduced-motion: reduce) {
      .nav-logo .k { animation: none; background-position: 50% 0; }
      .cta-primary,
      .nav-cta,
      .price.featured .price-cta { animation: none; }
    }
    @media (max-width: 768px) {
      .nav-links a:not(.nav-cta) { display: none; }
      /* Slimmer bar on phones. The island shape and its scroll morph are
         unchanged - it just takes less vertical room, so more of the page
         shows under it. */
      .nav-inner { padding: 8px 12px; border-radius: 16px; }
      .nav.scrolled .nav-inner { padding: 6px 12px; }
      .nav-logo .k { font-size: 26px; }
      .nav-cta { padding: 7px 14px; font-size: 12px; border-radius: 10px; }
      .svc-switch { padding: 3px; gap: 2px; }
      .svc-btn { height: 34px; padding: 0 8px; }
    }

    /* ===== CONTAINER ===== */
    .wrap { max-width: 1280px; margin: 0 auto; padding: 0 24px; }
    @media (min-width: 1280px) {
      /* Apple-style presentation width and reading width are separate jobs.
         Let product UI, card collections and media breathe on a desktop while
         .sec-head, .hero-sub and .faq-list retain their narrower text caps. */
      .wrap { max-width: var(--stage-max); }

      /* Files is a guided product walkthrough rather than a full-width product
         stage. Keep its interface close to the original desktop measure while
         giving only the editorial copy a little more breathing room. */
      #filesContent > section > .wrap,
      #filesContent > footer > .wrap { max-width: 1344px; }
      #filesContent .files-hero-inner { max-width: 896px; }
      #filesContent .files-hero-sub { max-width: 704px; }
      #filesContent .sec-head { max-width: 760px; }

      /* AutoGen should feel expansive without spanning the entire Gen stage.
         Pull it in one small step; the hero and other Gen sections stay wide. */
      #autogen > .wrap { max-width: 1568px; }
    }
    @media (max-width: 640px) { .wrap { padding: 0 18px; } }

    /* ===== HERO ===== */
    .hero {
      padding: 80px 0 60px;
      position: relative;
    }
    @media (max-width: 768px) { .hero { padding: 50px 0 40px; } }
    .hero-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 60px;
      align-items: center;
    }
    @media (min-width: 1024px) {
      .hero > .wrap { max-width: var(--stage-max); }
      .hero-grid {
        grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr);
        gap: clamp(48px, 5vw, 72px);
      }
      /* The Image Gen hero is product-led: give the live result stage more
         room than the copy column instead of making both halves compete. */
      #genContent .hero > .wrap { max-width: var(--stage-max); }
      #genContent .hero-grid {
        grid-template-columns: minmax(0, 0.76fr) minmax(0, 1.24fr);
        gap: clamp(40px, 4vw, 64px);
      }
      /* Like the API introduction, the Gen hero is one complete desktop
         chapter. Center the copy and result stage in the usable viewport so
         the stats strip begins below the fold instead of peeking into it. */
      #genContent > .hero {
        min-height: calc(100svh - 72px);
        display: flex;
        align-items: center;
        padding-block: clamp(48px, 6vh, 72px);
      }
      #genContent > .hero > .wrap { width: 100%; }
    }
    /* "Currently running" indicator. Opacity only, and a shallow range:
       the old version also scaled the dot to 1.2x, which made every status
       dot on the page throb like a notification badge. Reserved for steps
       that are genuinely in progress right now, never for static labels. */
    @keyframes pulseDot {
      0%, 100% { opacity: 1; }
      50%      { opacity: 0.62; }
    }
    .hero h1 {
      font-size: clamp(42px, 6.5vw, 80px);
      font-weight: 800;
      line-height: 1.02;
      letter-spacing: -0.032em;
      margin-bottom: 22px;
    }
    /* Accent phrase in the headline. Solid accent, not a travelling gradient:
       the old version rested at the dark end of its ramp, leaving "at the"
       around 2.4:1 on the near-black background (below the 3:1 large-text
       minimum). Weight and colour carry the emphasis instead. */
    .hero h1 .shimmer-word {
      color: var(--text-primary);
      padding: 0 4px;
    }
    .hero-sub {
      font-size: 17px;
      color: var(--text-secondary);
      line-height: 1.6;
      margin-bottom: 32px;
      max-width: 540px;
    }
    .hero-ctas {
      display: flex;
      flex-direction: column;
      gap: 14px;
      max-width: 380px;
    }
    @media (min-width: 480px) { .hero-ctas { flex-direction: row; max-width: none; } }
    /* The chip material, not a white fill (The No Pure White Rule,
       DESIGN.md:190). .cta-secondary sits on --bg-secondary at weight 600 with
       the faint edge, so the primary is one surface step lighter, one hairline
       step brighter and one weight step heavier: the ranking survives without
       the fill. */
    .cta-primary {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 8px;
      padding: 16px 26px;
      background: var(--bg-hover);
      color: var(--text-primary);
      border-radius: 14px;
      font-size: 15px;
      font-weight: 700;
      transition: transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1)), box-shadow 0.25s ease, border-color 0.25s ease;
      border: 1px solid var(--hairline-hover);
      box-shadow: 0 1px 1px rgba(0,0,0,0.45), 0 5px 14px rgba(0,0,0,0.38), inset 0 -1px 0 rgba(0,0,0,0.16);
    }
    .cta-primary:hover { border-color: var(--hairline-strong); transform: translateY(-2px); box-shadow: 0 3px 5px rgba(0,0,0,0.5), 0 14px 34px rgba(0,0,0,0.55), inset 0 -1px 0 rgba(0,0,0,0.16); }
    .cta-primary:active { transform: scale(0.94); transition: transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
    .cta-primary svg { width: 16px; height: 16px; }
    .cta-secondary {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 8px;
      padding: 16px 26px;
      background: var(--bg-secondary);
      color: var(--text-primary);
      border: 1px solid var(--border-color);
      border-radius: 14px;
      font-size: 15px;
      font-weight: 600;
      transition: transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1)), border-color 0.25s ease;
    }
    .cta-secondary:hover { border-color: rgba(255, 255, 255, 0.35); transform: translateY(-2px); }
    .cta-secondary:active { transform: scale(0.94); transition: transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
    .hero-trust {
      margin-top: 40px;
      display: flex;
      flex-wrap: wrap;
      gap: 28px;
      font-size: 13px;
      color: var(--text-muted);
    }
    .hero-trust div { display: flex; align-items: center; gap: 6px; }
    .hero-trust svg { width: 16px; height: 16px; color: #30d158; }

    /* ===== HERO MOCKUP ===== */
    .hero-mock {
      position: relative;
      animation: floatY 8s ease-in-out infinite;
    }
    @keyframes floatY {
      0%, 100% { transform: translateY(0); }
      50% { transform: translateY(-8px); }
    }
    .mock-frame {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 18px;
      padding: 18px;
      box-shadow: 0 30px 80px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.04);
      position: relative;
    }
    #genContent .hero-mock .mock-frame,
    #genContent .hero-cycle {
      transform-style: preserve-3d;
    }
    #genContent .hero-cycle {
      transition: opacity 0.56s var(--ease-out-quint), filter 0.56s ease;
    }
    #genContent .mock-frame.is-resetting .hero-cycle {
      opacity: 0;
      filter: blur(10px);
    }
    .mock-titlebar {
      display: flex;
      align-items: center;
      gap: 8px;
      padding-bottom: 14px;
      border-bottom: 1px solid var(--border-color);
      margin-bottom: 14px;
    }
    .mock-titlebar .dots { display: flex; gap: 6px; }
    .mock-titlebar .dots span {
      width: 10px; height: 10px; border-radius: 50%;
      background: #2a2a2a;
    }
    .mock-titlebar .url {
      flex: 1;
      text-align: center;
      font-size: 11px;
      color: var(--text-muted);
      font-family: var(--font-sf);
    }
    .mock-prompt {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      padding: 12px 14px;
      font-size: 11px;
      font-family: var(--font-sf);
      color: var(--text-secondary);
      line-height: 1.6;
      margin-bottom: 12px;
      /* The box is sized to the whole prompt before the first character
         streams in (runHeroCycle measures and commits it), so nothing ever
         clips or scrolls mid-type and every prompt gets exactly the height
         its own wrapped text needs. */
      transition: height 0.45s var(--ease-out-quint), box-shadow 0.3s ease;
      overflow: hidden;
      position: relative;
      word-break: break-word;
    }
    .mock-prompt .typed-text { color: var(--text-primary); }
    /* no blinking text carets anywhere on the page: the typing itself reads */
    .mock-prompt .cursor { display: none; }
    @keyframes caret { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
    .mock-status {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 11px;
      color: var(--text-muted);
      margin-bottom: 14px;
      font-family: var(--font-sf);
      height: 16px;
      flex-shrink: 0;
    }
    .mock-status.gen-active .label {
      color: #ffbd2e;
    }
    .mock-status.complete .label { color: #30d158; }
    /* The word swap between PROMPTING, GENERATING and COMPLETE: the old word
       softens out of focus, the new one condenses into place — the Apple
       Intelligence text reveal, not a hard string swap. */
    .mock-status .label { display: inline-block; }
    .mock-status .label.swap-out { animation: heroWordOut 0.22s var(--ease-out-quint) forwards; }
    .mock-status .label.swap-in { animation: heroWordIn 0.5s var(--ease-out-quint); }
    /* Pure crossfade: the old word fades out through blur, the new one fades
       in from blur. No travel, no tracking shift - opacity and focus only. */
    @keyframes heroWordOut {
      to { opacity: 0; filter: blur(6px); }
    }
    @keyframes heroWordIn {
      from { opacity: 0; filter: blur(7px); }
      to   { opacity: 1; filter: blur(0); }
    }
    @media (prefers-reduced-motion: reduce) {
      .mock-status .label.swap-out, .mock-status .label.swap-in,
      .ag-batch-stage.swap-out, .ag-batch-stage.swap-in { animation: none; }
      .mock-prompt { transition: none; }
    }
    .mock-grid {
      display: grid;
      grid-template-columns: repeat(4, minmax(0, 1fr));
      gap: 4px;
    }
    @media (min-width: 769px) {
      .mock-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 8px;
      }
      .mock-grid .mock-tile:nth-child(n + 4) { display: none; }
    }
    .mock-tile {
      aspect-ratio: 3/4;
      border-radius: 8px;
      background: var(--bg-tertiary);
      overflow: hidden;
      position: relative;
      transition: box-shadow 0.3s ease;
    }
    #genContent .hero-mock.tilt-active .mock-prompt {
      box-shadow: 0 14px 32px rgba(0,0,0,0.34), 0 0 0 1px rgba(255,255,255,0.04);
    }
    #genContent .hero-mock.tilt-active .mock-tile {
      box-shadow: 0 16px 34px rgba(0,0,0,0.38);
    }
    .mock-tile.empty {
      background: linear-gradient(110deg, var(--bg-tertiary) 30%, var(--bg-hover) 50%, var(--bg-tertiary) 70%);
      background-size: 200% 100%;
      animation: tileShimmer 1.6s ease-in-out infinite;
    }
    @keyframes tileShimmer {
      0% { background-position: 200% 0; }
      100% { background-position: -200% 0; }
    }
    .mock-tile img {
      width: 100%; height: 100%;
      object-fit: cover;
      animation: tileFade 0.7s var(--ease-out-expo);
    }
    @keyframes tileFade {
      from { opacity: 0; transform: scale(0.95); filter: blur(6px); }
      to { opacity: 1; transform: scale(1); filter: blur(0); }
    }

    /* Image Gen result stage: the generated work is the hierarchy. The
       prompt becomes a quiet rail, chrome contracts to the 4px spacing
       system, and the wider desktop column flows directly into larger
       portrait tiles. The existing three-on-desktop/four-on-phone contract
       and content-sized prompt measurement stay unchanged. */
    #genContent .hero-mock {
      width: 100%;
      justify-self: end;
    }
    #genContent .hero-mock .mock-frame {
      padding: 14px;
      border-radius: 16px;
      background: #111111;
      border-color: rgba(255,255,255,0.11);
      box-shadow: inset 0 1px 0 rgba(255,255,255,0.035);
    }
    #genContent .hero-mock .mock-prompt {
      margin-bottom: 4px;
      padding: 4px 4px 12px;
      border: 0;
      border-radius: 0;
      background: transparent;
      color: var(--text-secondary);
      font-size: 13px;
      line-height: 1.45;
    }
    #genContent .hero-mock .mock-status {
      height: 20px;
      margin: 0 4px 12px;
      gap: 7px;
      color: #f4bd45;
      font-size: 12px;
      font-weight: 600;
      letter-spacing: 0.02em;
    }
    #genContent .hero-mock .mock-status.gen-active .label {
      background: none;
      -webkit-text-fill-color: currentColor;
      color: inherit;
      animation: none;
    }
    #genContent .hero-mock .mock-status.complete {
      color: #30d158;
    }
    #genContent .hero-mock .mock-grid {
      gap: 6px;
    }
    #genContent .hero-mock .mock-tile {
      border-radius: 10px;
    }
    #genContent .hero-mock.tilt-active .mock-prompt {
      box-shadow: none;
    }
    #genContent .hero-mock.tilt-active .mock-tile {
      box-shadow: 0 4px 8px rgba(0,0,0,0.38);
    }
    @media (max-width: 768px) {
      #genContent .hero-mock .mock-frame { padding: 12px; }
      #genContent .hero-mock .mock-prompt {
        padding: 2px 2px 10px;
        font-size: 12px;
      }
      #genContent .hero-mock .mock-status {
        margin: 0 2px 10px;
        font-size: 11px;
      }
      #genContent .hero-mock .mock-grid { gap: 4px; }
      #genContent .hero-mock .mock-tile { border-radius: 8px; }
    }
    /* ===== STATS STRIP ===== */
    .stats-strip {
      padding: 30px 0;
      border-top: 1px solid var(--border-color);
      border-bottom: 1px solid var(--border-color);
      margin-top: 40px;
    }
    /* The live band stands on its own; no separating hairlines. */
    #apiLiveStrip { border-top: 0; border-bottom: 0; }
    .stats-row {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 24px;
      text-align: center;
    }
    @media (min-width: 640px) {
      .stats-row { grid-template-columns: repeat(4, 1fr); }
      #apiContent .stats-row { grid-template-columns: repeat(3, 1fr); }
    }
    .stat .num {
      font-size: clamp(24px, 4vw, 36px);
      font-weight: 800;
      letter-spacing: -1px;
      color: var(--text-primary);
      line-height: 1;
      margin-bottom: 6px;
      font-variant-numeric: tabular-nums;
      display: inline-block;
      transform-origin: center;
    }
    .stat .lbl {
      font-size: 12px;
      color: var(--text-muted);
      text-transform: uppercase;
      letter-spacing: 0.5px;
      font-weight: 600;
    }

    /* ===== API LIVE STRIP =====
       Served-request odometer + anonymized live feed. The number rolls the
       way iOS numerals do: each digit is a vertical reel inside a masked
       one-line window, travelling on the page's settle curve. */
    .live-band {
      display: grid;
      grid-template-columns: 1fr 1.1fr;
      gap: 48px;
      align-items: center;
    }
    /* Rows carry unbreakable nowrap lines; without this the grid track
       inflates to their min-content and the card overflows the phone. */
    .live-band > * { min-width: 0; }
    @media (max-width: 860px) {
      .live-band { grid-template-columns: 1fr; gap: 28px; }
    }
    .live-lbl {
      font-size: 12px;
      color: var(--text-muted);
      text-transform: uppercase;
      letter-spacing: 0.5px;
      font-weight: 600;
      margin-bottom: 10px;
    }
    .odo {
      display: inline-flex;
      font-size: clamp(38px, 5.5vw, 58px);
      font-weight: 800;
      letter-spacing: -1px;
      line-height: 1;
      color: var(--text-primary);
      font-variant-numeric: tabular-nums;
    }
    .odo .odo-d {
      height: 1em;
      overflow: hidden;
      /* soft edges so digits condense into place instead of guillotining */
      -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 18%, #000 82%, transparent 100%);
      mask-image: linear-gradient(180deg, transparent 0, #000 18%, #000 82%, transparent 100%);
    }
    .odo .odo-reel {
      display: flex;
      flex-direction: column;
      transition: transform 0.62s var(--ease-out-quint);
    }
    .odo .odo-reel > span { height: 1em; line-height: 1; }
    .live-sub {
      margin-top: 12px;
      font-size: 13px;
      color: var(--text-muted);
    }
    .live-sub b { color: var(--text-secondary); font-weight: 600; }
    .live-feed {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 14px;
      padding: 14px 16px;
    }
    .live-feed-head {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 12px;
      color: var(--text-muted);
      margin-bottom: 10px;
    }
    .live-rows { height: calc(5 * var(--lrow, 52px) + 32px); overflow: hidden; }
    .live-note {
      margin-top: 12px;
      font-size: 11px;
      color: var(--text-muted);
    }
    /* Calm between-requests state: no fake rows, just a listening line. */
    .live-quiet {
      height: 52px;
      display: flex; align-items: center;
      padding: 0 12px;
      font-size: 13px; color: var(--text-muted);
    }
    /* Each request is its own card, the way the real feed draws them:
       status dot, model over requester, live progress on the right that
       resolves into ttft / total / tokens once the stream finishes. */
    .live-row {
      display: flex;
      align-items: center;
      gap: 10px;
      height: var(--lrow, 52px);
      margin-bottom: 8px;
      padding: 0 12px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      overflow: hidden;
      white-space: nowrap;
    }
    .live-row.is-enter { height: 0; margin-bottom: 0; opacity: 0; border-width: 0; }
    .live-row.is-live {
      transition: height 0.5s var(--ease-out-quint), margin-bottom 0.5s var(--ease-out-quint), opacity 0.4s ease;
      height: var(--lrow, 52px); margin-bottom: 8px; opacity: 1;
    }
    .live-row.is-exit {
      transition: height 0.5s var(--ease-out-quint), margin-bottom 0.5s var(--ease-out-quint), opacity 0.3s ease;
      height: 0; margin-bottom: 0; opacity: 0;
    }
    .lr-main { min-width: 0; }
    .lr-model {
      font-size: 13px; font-weight: 650; color: var(--text-primary);
      overflow: hidden; text-overflow: ellipsis;
    }
    .lr-sub {
      font-size: 12px; color: var(--text-muted);
      overflow: hidden; text-overflow: ellipsis;
    }
    .lr-sub b { color: var(--text-secondary); font-weight: 500; }
    .lr-right {
      margin-left: auto;
      display: flex; align-items: center; gap: 10px;
      flex-shrink: 0;
    }
    .lr-spin {
      width: 12px; height: 12px; border-radius: 50%;
      border: 1.5px solid rgba(255,255,255,0.22);
      border-top-color: rgba(255,255,255,0.75);
      animation: lrSpin 0.9s linear infinite;
      flex-shrink: 0;
    }
    @keyframes lrSpin { to { transform: rotate(360deg); } }
    .lr-status {
      font-size: 12px; line-height: 1.3; color: var(--text-secondary);
      font-variant-numeric: tabular-nums;
    }
    /* Finished requests read as one quiet line: number then muted label,
       no stacked columns, no dots. */
    .lr-done {
      font-size: 12px; line-height: 1.3; color: var(--text-muted);
      font-variant-numeric: tabular-nums; white-space: nowrap;
    }
    .lr-done b {
      font-size: 13px; font-weight: 650; color: var(--text-primary);
    }
    /* Inline rolling numerals for live counters, the same reel mechanic as
       the big odometer: each digit is a masked window over a 0-9 strip. */
    .rn { display: inline-flex; vertical-align: bottom; }
    .rn .rn-d {
      height: 1.3em; overflow: hidden;
      -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%);
      mask-image: linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%);
    }
    .rn .rn-reel {
      display: flex; flex-direction: column;
      transition: transform 0.5s var(--ease-out-quint);
    }
    .rn .rn-reel > span { height: 1.3em; line-height: 1.3; }
    .lr-age {
      font-size: 11px; color: var(--text-muted);
      width: 52px; text-align: right; flex-shrink: 0;
      font-variant-numeric: tabular-nums;
    }
    .lr-model.swap-in, .lr-right.swap-in { animation: heroWordIn 0.5s var(--ease-out-quint); }

    /* Desktop live proof: treat the traffic as its own full-viewport product
       chapter. The real counter and requests gain scale and breathing room;
       adjacent chapters stay outside the frame when this section is centered.
       Compact layouts intentionally retain the denser five-row presentation. */
    @media (min-width: 1100px) {
      #apiLiveStrip {
        min-height: 100svh;
        display: flex;
        align-items: center;
        padding: clamp(64px, 8vh, 96px) 0;
      }
      #apiLiveStrip > .wrap {
        width: 100%;
        max-width: var(--stage-max);
        padding-inline: 40px;
      }
      #apiLiveStrip .live-band {
        grid-template-columns: minmax(340px, 0.76fr) minmax(0, 1.24fr);
        gap: clamp(72px, 6vw, 112px);
      }
      #apiLiveStrip .live-lbl {
        margin-bottom: 16px;
        font-size: 14px;
      }
      #apiLiveStrip .odo {
        font-size: clamp(72px, 5.2vw, 96px);
        letter-spacing: -0.04em;
      }
      #apiLiveStrip .live-sub {
        margin-top: 20px;
        font-size: 15px;
      }
      #apiLiveStrip .live-feed {
        padding: 20px;
        border-radius: 18px;
      }
      #apiLiveStrip .live-feed-head {
        margin-bottom: 16px;
        font-size: 14px;
      }
      #apiLiveStrip .live-rows {
        --lrow: 60px;
        height: calc(7 * var(--lrow) + 48px);
      }
      #apiLiveStrip .live-row {
        padding-inline: 16px;
        border-radius: 12px;
      }
      #apiLiveStrip .lr-model { font-size: 15px; }
      #apiLiveStrip .lr-sub,
      #apiLiveStrip .lr-status,
      #apiLiveStrip .lr-done { font-size: 13px; }
      #apiLiveStrip .lr-done b { font-size: 14px; }
      #apiLiveStrip .lr-age {
        width: 60px;
        font-size: 12px;
      }
      #apiLiveStrip .live-note {
        margin-top: 16px;
        font-size: 12px;
      }
    }

    /* Phone: each request becomes a three-line card. Model and age on
       top, requester and platform on their own full line, then the full
       status / stats line with room for every number and label. */
    @media (max-width: 560px) {
      .live-feed { padding: 12px; --lrow: 76px; }
      .live-row {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas: 'model age' 'sub sub' 'right right';
        align-content: center;
        column-gap: 10px;
        row-gap: 4px;
      }
      .lr-main { display: contents; }
      .lr-model, .lr-sub { min-width: 0; }
      .lr-model { grid-area: model; font-size: 14px; }
      .lr-sub { grid-area: sub; }
      .lr-age { grid-area: age; width: auto; justify-self: end; }
      .lr-right { grid-area: right; justify-self: start; margin-left: 0; gap: 8px; }
      .lr-done { font-size: 13px; }
    }
    @media (max-width: 374px) {
      .lr-vb { display: none; }
      .lr-seg.lr-total { display: none; }
    }
    @media (prefers-reduced-motion: reduce) {
      .odo .odo-reel { transition: none; }
      .rn .rn-reel { transition: none; }
      .lr-spin { animation: none; }
      .live-row.is-enter, .live-row.is-live, .live-row.is-exit { transition: none; height: var(--lrow, 52px); margin-bottom: 8px; opacity: 1; }
      .live-row.is-exit { display: none; }
      .lr-model.swap-in, .lr-right.swap-in { animation: none; }
    }

    /* ===== SECTIONS ===== */
    section.sec {
      padding: 100px 0;
      position: relative;
    }
    @media (max-width: 768px) { section.sec { padding: 70px 0; } }
    .sec-head {
      text-align: center;
      max-width: 720px;
      margin: 0 auto 50px;
    }
    .sec h2 {
      font-size: clamp(32px, 5vw, 54px);
      font-weight: 800;
      letter-spacing: -0.03em;
      line-height: 1.06;
      margin-bottom: 14px;
    }
    .sec-sub {
      font-size: 16px;
      color: var(--text-secondary);
      line-height: 1.6;
    }

    /* ===== HOW IT WORKS ===== */
    .steps {
      display: grid;
      grid-template-columns: 1fr;
      gap: 18px;
    }
    @media (min-width: 768px) { .steps { grid-template-columns: repeat(3, 1fr); gap: 22px; } }
    .step {
      background: var(--glass-bg);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      border: 1px solid var(--hairline);
      border-radius: 18px;
      padding: 28px;
      position: relative;
      overflow: hidden;
      transition: border-color 0.3s ease;
    }
    .step:hover { border-color: var(--hairline-hover); }
    /* Step ordinal. Was a 56px/900 numeral in --bg-tertiary sitting on the
       card corner: 1.2:1 against its own background, so it was not text, it
       was a watermark. Giant ghosted 01/02/03 corner numerals are the single
       most recognisable ornament on a generated landing page. The cards read
       left to right; the number was saying nothing the order did not. */
    .step-icon {
      width: 44px; height: 44px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 11px;
      display: flex; align-items: center; justify-content: center;
      margin-bottom: 18px;
    }
    .step-icon svg { width: 24px; height: 24px; color: var(--text-primary); }

    /* ===== ICON WEIGHT =====
       One set, one weight. Every glyph on this page comes from
       shared/kg-icons.js and carries the estate stroke, KG_ICON_STROKE = 1.5,
       applied by kgIcon() once for every caller. The old optical ladder that
       stood here set stroke-width 1.7 / 1.9 / 2.15 / 2.5 per slot, and a CSS
       stroke-width beats the attribute, so no slot may name one again:
       weight never varies to show size, state or emphasis. Caps and joins
       below are the set's own and only restate what the glyphs already say. */
    svg { stroke-linecap: round; stroke-linejoin: round; }
    .step h3 {
      font-size: 18px;
      font-weight: 700;
      margin-bottom: 8px;
    }
    .step p {
      font-size: 14px;
      color: var(--text-secondary);
      line-height: 1.6;
    }

    /* ===== AUTOGEN SHOWCASE ===== */
    .ag-show {
      display: grid;
      grid-template-columns: 1fr;
      gap: 40px;
      align-items: start;
    }
    @media (min-width: 1024px) { .ag-show { grid-template-columns: 1fr 1.1fr; gap: 60px; align-items: center; } }
    .ag-show-text h2 { font-size: clamp(28px, 4.5vw, 42px); font-weight: 800; letter-spacing: -1px; line-height: 1.1; margin-bottom: 16px; }
    .ag-show-text p { font-size: 16px; color: var(--text-secondary); line-height: 1.65; margin-bottom: 22px; }
    /* Eyebrow removal shortens these centered desktop columns without moving
       their row center. Reclaim exactly half of each removed tag's measured
       outer height so the remaining copy occupies that space evenly. */
    @media (min-width: 1024px) {
      #genContent .hero-grid > .reveal:first-child,
      #apiContent .hero-grid > .reveal:first-child {
        position: relative;
        top: -26.5px;
      }
      #autogen .ag-show-text,
      #imports .ag-show-text,
      #api-speed .ag-show-text,
      #api-privacy .ag-show-text {
        position: relative;
        top: -19.5px;
      }
    }
    .ag-feat-list { list-style: none; }
    .ag-feat-list li {
      display: flex;
      align-items: flex-start;
      gap: 12px;
      padding: 10px 0;
      font-size: 14px;
      color: var(--text-primary);
    }
    .ag-feat-list li svg {
      width: 20px; height: 20px;
      color: #30d158;
      flex-shrink: 0;
      margin-top: 1px;
    }
    .ag-feat-list li b { color: var(--text-primary); font-weight: 700; }
    .ag-feat-list li span { color: var(--text-secondary); }

    /* AutoGen mock */
    .ag-mock {
      background: transparent;
      border: none;
      padding: 0;
      box-shadow: none;
      position: relative;
      z-index: 1;
      isolation: isolate;
    }
    /* Hero mock stage  the rotating layer that holds frame + float cards */
    .hero-mock-stage {
      position: relative;
      width: 100%;
    }
    /* AutoGen mock floats with its own rhythm so side-by-side mocks don't
       bob in lockstep with the hero. */
    .ag-mock.tilt-host {
      animation: floatPanelAlt 9s ease-in-out infinite;
    }
    @keyframes floatPanelAlt {
      0%, 100% { transform: translate3d(0, 0, 0); }
      50%      { transform: translate3d(0, -6px, 0); }
    }
    .ag-mock-inner {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 18px;
      padding: 18px;
      box-shadow: 0 30px 80px rgba(0,0,0,0.5);
    }
    .ag-batch {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      padding: 12px;
      margin-bottom: 10px;
    }
    .ag-batch:last-child { margin-bottom: 0; }
    /* Active batch (#agB2) reserves full height even before content fills */
    #agB2 {
      min-height: 240px;
    }
    @media (max-width: 768px) {
      #agB2 { min-height: 220px; }
    }
    .ag-batch-head {
      display: flex; align-items: center;
      margin-bottom: 8px;
    }
    .ag-batch-label {
      font-size: 11px;
      font-weight: 700;
      color: var(--text-primary);
    }
    .ag-batch-time {
      margin-left: auto;
      font-size: 10px;
      color: var(--text-muted);
      font-variant-numeric: tabular-nums;
    }
    .ag-batch-stage {
      font-size: 10px;
      font-weight: 700;
      letter-spacing: 0.5px;
      color: var(--text-muted);
      margin-bottom: 4px;
    }
    .ag-batch-stage.shimmer {
      color: #ffbd2e;
    }
    /* Stage-word changes use the same blur crossfade as the hero status.
       Defined after .shimmer so the morph wins the animation slot mid-swap. */
    .ag-batch-stage.swap-out { animation: heroWordOut 0.22s var(--ease-out-quint) forwards; }
    .ag-batch-stage.swap-in { animation: heroWordIn 0.5s var(--ease-out-quint); }
    .ag-batch-prompt {
      font-size: 11px;
      font-family: var(--font-sf);
      color: var(--text-secondary);
      line-height: 1.5;
      height: auto;
      min-height: 1.5em;
      overflow: hidden;
      margin-bottom: 8px;
      word-break: break-word;
      transition: height 0.35s var(--ease-out-quint);
    }
    .ag-batch-prompt .cursor { display: none; }
    .ag-batch-imgs {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 4px;
    }
    .ag-batch-img {
      aspect-ratio: 3/4;
      border-radius: 5px;
      background: var(--bg-secondary);
      overflow: hidden;
    }
    .ag-batch-img img { width: 100%; height: 100%; object-fit: cover; animation: tileFade 0.7s var(--ease-out-expo); }
    .ag-batch-img.skel {
      background: linear-gradient(110deg, var(--bg-secondary) 30%, var(--bg-hover) 50%, var(--bg-secondary) 70%);
      background-size: 200% 100%;
      animation: tileShimmer 1.6s ease-in-out infinite;
    }

    /* ===== MODELS MARQUEE ===== */
    .marquee-wrap {
      position: relative;
      overflow: hidden;
      mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
      -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    }
    .marquee {
      display: flex;
      gap: 14px;
      width: max-content;
      animation: marqueeScroll 60s linear infinite;
    }
    /* Marquee runs continuously — no pause on hover */
    .marquee-row + .marquee-row { margin-top: 14px; }
    .marquee.reverse { animation-direction: reverse; animation-duration: 75s; }
    @keyframes marqueeScroll {
      from { transform: translateX(0); }
      to { transform: translateX(-50%); }
    }
    .mcard {
      flex-shrink: 0;
      width: 150px;
      cursor: default;
    }
    .mcard-img {
      width: 100%;
      aspect-ratio: 3/4;
      border-radius: var(--radius-sm);
      background: var(--bg-tertiary);
      overflow: hidden;
      border: 2px solid transparent;
      transition: box-shadow 0.3s ease, border-color 0.3s ease;
      margin-bottom: 8px;
      position: relative;
    }
    .mcard-img img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 0.5s var(--ease-out-expo), filter 0.3s ease;
    }
    .mcard:hover .mcard-img {
      border-color: rgba(255, 255, 255, 0.18);
      box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 8px 28px rgba(255, 255, 255, 0.12), 0 0 40px rgba(255, 255, 255, 0.05);
    }
    .mcard:hover .mcard-img img {
      transform: scale(1.06);
      filter: brightness(1.08) saturate(1.1);
    }
    .mcard-name {
      transition: color 0.25s ease;
    }
    .mcard:hover .mcard-name {
      color: #ffffff;
      text-shadow: 0 0 12px rgba(255, 255, 255, 0.25);
    }
    .mcard-name {
      font-size: 11px;
      font-weight: 600;
      color: var(--text-primary);
      text-align: center;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
/* DETAILER MODEL PILLS (flat clean style) */
.det-model-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.det-model-pill {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px 8px;
  background: var(--bg-tertiary);
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-align: center;
  transition: background 0.2s ease, border-color 0.2s ease;
  user-select: none;
}
.det-model-pill:hover {
  background: var(--bg-hover);
}
.det-model-pill.selected {
  border-color: var(--accent);
  background: var(--accent-dim);
}
.det-model-pill span {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: 0.2px;
}
.det-model-check {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 18px;
  height: 18px;
  background: var(--accent);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 0.25s var(--ease-settle), transform 0.25s var(--ease-settle);
  pointer-events: none;
}
.det-model-check svg {
  width: 11px;
  height: 11px;
  color: var(--bg-primary);
}
.det-model-pill.selected .det-model-check {
  opacity: 1;
  transform: scale(1);
}

/* MERGE DETAILERS row (flat clean style) */
.det-merge-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
  user-select: none;
}
.det-merge-row:hover {
  background: var(--bg-hover);
}
.det-merge-row.selected {
  border-color: var(--accent);
  background: var(--accent-dim);
}
.det-merge-box {
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--border-color);
  border-radius: 4px;
  background: var(--bg-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.det-merge-box svg {
  width: 12px;
  height: 12px;
  color: var(--bg-primary);
  opacity: 0;
  transition: opacity 0.15s ease;
}
.det-merge-row.selected .det-merge-box {
  background: var(--accent);
  border-color: var(--accent);
}
.det-merge-row.selected .det-merge-box svg {
  opacity: 1;
}
    /* ===== FEATURES GRID ===== */
    .feat-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 18px;
    }
    @media (min-width: 640px) { .feat-grid { grid-template-columns: repeat(2, 1fr); } }
    @media (min-width: 1024px) { .feat-grid { grid-template-columns: repeat(3, 1fr); } }
    .feat {
      background: var(--glass-bg);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      border: 1px solid var(--hairline);
      border-radius: 18px;
      padding: 26px;
      transition: border-color 0.3s ease;
      position: relative;
      overflow: hidden;
    }
    .feat:hover { border-color: var(--hairline-hover); }
    .feat-icon {
      width: 42px; height: 42px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 11px;
      display: flex; align-items: center; justify-content: center;
      margin-bottom: 18px;
      color: var(--text-primary);
    }
    .feat-icon svg { width: 20px; height: 20px; }
    .feat.accent-gold .feat-icon,
    .feat.accent-green .feat-icon,
    .feat.accent-blue .feat-icon,
    .feat.accent-amber .feat-icon,
    .feat.accent-purple .feat-icon {
      background: var(--bg-tertiary);
      border-color: var(--border-color);
      color: var(--text-primary);
    }
    .feat h3 { font-size: 17px; font-weight: 700; margin-bottom: 8px; }
    .feat p { font-size: 14px; color: var(--text-secondary); line-height: 1.6; }
    .feat-tag {
      position: absolute;
      top: 20px; right: 20px;
      font-size: 10px;
      font-weight: 800;
      letter-spacing: 0.6px;
      padding: 3px 7px;
      border-radius: 4px;
      background: var(--bg-tertiary);
      color: var(--text-secondary);
      border: 1px solid var(--border-color);
    }
    .feat-tag.new { color: #30d158; border-color: rgba(74,222,128,0.3); background: rgba(74,222,128,0.08); }

    /* ===== FEATURES GRID, figure-led variant (Image Gen features) =====
       No card, no icon tile: the real number out of the copy is the graphic,
       and the rule under it does all the containing that is needed. */
    .featnum-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 36px;
    }
    @media (min-width: 640px) { .featnum-grid { grid-template-columns: repeat(2, 1fr); gap: 44px 40px; } }
    @media (min-width: 1024px) { .featnum-grid { grid-template-columns: repeat(3, 1fr); gap: 48px 56px; } }
    .featnum { min-width: 0; }
    .featnum-fig {
      display: flex;
      align-items: flex-start;
      justify-content: space-between;
      gap: 16px;
      margin-bottom: 16px;
      padding-bottom: 12px;
      border-bottom: 1px solid var(--hairline);
      transition: border-color 0.3s ease;
    }
    .featnum:hover .featnum-fig { border-color: var(--hairline-hover); }
    .featnum-n {
      display: block;
      font-size: 46px;
      font-weight: 250;
      line-height: 1;
      letter-spacing: -0.045em;
      color: var(--text-primary);
      font-variant-numeric: tabular-nums;
      margin-bottom: 8px;
    }
    .featnum-u {
      display: block;
      font-size: 12px;
      line-height: 1.3;
      color: var(--text-muted);
    }
    .featnum h3 { font-size: 17px; font-weight: 700; margin-bottom: 8px; }
    .featnum p { font-size: 14px; color: var(--text-secondary); line-height: 1.6; }

    /* ===== PRICING ===== */
    .price-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 16px;
    }
    @media (min-width: 640px) { .price-grid { grid-template-columns: repeat(2, 1fr); } }
    @media (min-width: 1024px) { .price-grid { grid-template-columns: repeat(4, 1fr); } }
    .price {
      background: var(--glass-bg);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      border: 1px solid var(--hairline);
      border-radius: 18px;
      padding: 24px;
      position: relative;
      transition: border-color 0.3s ease;
    }
    .price:hover { border-color: var(--hairline-hover); }
    .price.featured {
      border-color: rgba(255,215,0,0.35);
      background: linear-gradient(180deg, rgba(255,215,0,0.04), var(--bg-secondary));
    }
    /* This pseudo-element is the badge, not a sheen layer - the specular
       hover block below deliberately skips .featured so its inset:0 and
       opacity:0 can't stretch this into a full-card slab. The explicit
       resets keep it safe even if that selector list changes again. */
    .price.featured::before {
      content: 'Most Popular';
      position: absolute;
      inset: auto;
      top: -10px; left: 50%; transform: translateX(-50%);
      background: #FFD700;
      color: #000;
      font-size: 10px; font-weight: 800;
      padding: 4px 12px;
      border-radius: 20px;
      letter-spacing: 0.5px;
      white-space: nowrap;
      opacity: 1;
      z-index: 2;
    }
    .price-name {
      font-size: 13px;
      font-weight: 700;
      color: var(--text-secondary);
      text-transform: uppercase;
      letter-spacing: 0.6px;
      margin-bottom: 12px;
    }
    .price.featured .price-name { color: #FFD700; }
    .price-cost {
      display: flex;
      align-items: baseline;
      gap: 4px;
      margin-bottom: 16px;
    }
    .price-cost .amount {
      font-size: 32px;
      font-weight: 800;
      letter-spacing: -1px;
    }
    .price-cost .per {
      font-size: 12px;
      color: var(--text-muted);
    }
    .price-gens {
      font-size: 14px;
      color: var(--text-primary);
      font-weight: 600;
      margin-bottom: 4px;
    }
    .price-gens b {
      color: #30d158;
      font-size: 16px;
    }
    /* what the credits actually buy, right where the wallet opens */
    .price-worth {
      font-size: 12px;
      color: var(--text-muted);
      margin-bottom: 14px;
    }
    .price ul {
      list-style: none;
      margin-bottom: 18px;
    }
    .price ul li {
      font-size: 13px;
      color: var(--text-secondary);
      padding: 4px 0;
      display: block;
    }
    .price-cta {
      display: block;
      text-align: center;
      padding: 11px;
      border-radius: 9px;
      font-size: 13px;
      font-weight: 700;
      transition: background-color var(--dur-fast) ease, border-color var(--dur-fast) ease, color var(--dur-fast) ease;
      background: var(--bg-tertiary);
      color: var(--text-primary);
      border: 1px solid var(--border-color);
    }
    .price-cta:hover { border-color: rgba(255, 255, 255, 0.35); }
    /* The chip material, not a white fill (The No Pure White Rule,
       DESIGN.md:190). The other tiers sit on --bg-tertiary with the faint
       edge, so one surface step and one hairline step still name the featured
       tier as the recommended one. */
    .price.featured .price-cta { background: var(--bg-hover); color: var(--text-primary); border-color: var(--hairline-hover); font-weight: 700; }
    /* KING (plan perks, 2026-10-04). The top plan spans the whole row under the
       four cards rather than squeezing a fifth into it: the same card, laid
       across, its name led by the crown glyph and its perks in two columns.
       No gold and no glow; it is told apart by its width and its contents. */
    .price.price-king { grid-column: 1 / -1; display: grid; grid-template-columns: 1fr; gap: 8px 32px; }
    .price-king .price-name { display: inline-flex; align-items: center; gap: 8px; color: var(--text-primary); }
    .price-king .price-name svg { width: 18px; height: 18px; }
    .price-king ul { columns: 1; column-gap: 32px; margin-bottom: 0; }
    .price-king .price-cta { align-self: end; }
    @media (min-width: 1024px) {
      .price.price-king { grid-template-columns: minmax(220px, 1fr) 2fr minmax(180px, 0.8fr); align-items: center; padding: 28px 32px; }
      .price-king ul { columns: 2; }
      .price-king ul li { break-inside: avoid; }
      .price-king .price-cta { align-self: center; }
    }
    .price.featured .price-cta:hover { border-color: var(--hairline-strong); transform: translateY(-1px); box-shadow: 0 2px 3px rgba(0,0,0,0.5), 0 8px 20px rgba(0,0,0,0.5), inset 0 -1px 0 rgba(0,0,0,0.16); }

    /* the villain price, one line, right above the tiers */
    .pricing-anchor {
      margin-top: 12px;
      font-size: 14px;
      color: var(--text-muted);
    }
    .pricing-anchor b { color: var(--text-secondary); }

    /* how buying works: the purchase mechanics sold up front, not discovered
       at the last button */
    .buy-how {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 28px;
      max-width: 980px;
      margin: 34px auto 0;
    }
    .buy-step { display: flex; gap: 12px; align-items: flex-start; }
    .buy-n {
      font-family: var(--font-sf);
      font-size: 12px;
      color: var(--text-muted);
      line-height: 1.7;
      flex-shrink: 0;
    }
    .buy-step p {
      font-size: 13px;
      line-height: 1.6;
      color: var(--text-secondary);
      margin: 0;
    }
    .buy-step p b { color: var(--text-primary); display: block; margin-bottom: 2px; }
    .buy-step a { color: var(--text-secondary); text-decoration: underline; }
    @media (max-width: 800px) {
      .buy-how { grid-template-columns: 1fr; gap: 16px; }
    }

    .pricing-note {
      text-align: center;
      margin-top: 30px;
      font-size: 13px;
      color: var(--text-muted);
    }
    .pricing-note a { color: var(--text-secondary); text-decoration: underline; }

    /* ===== FAQ ===== */
    .faq-list { max-width: 760px; margin: 0 auto; }
    .faq-item {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 12px;
      margin-bottom: 10px;
      overflow: hidden;
      transition: border-color 0.2s ease;
    }
    .faq-item.open { border-color: rgba(255,255,255,0.2); }
    .faq-q {
      width: 100%;
      text-align: left;
      padding: 18px 22px;
      background: none;
      border: none;
      color: var(--text-primary);
      font-size: 15px;
      font-weight: 600;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      font-family: inherit;
    }
    .faq-q svg {
      width: 18px; height: 18px;
      color: var(--text-muted);
      transition: transform 0.5s var(--ease-settle), color 0.25s ease;
      flex-shrink: 0;
    }
    .faq-item.open .faq-q svg { transform: rotate(180deg); color: var(--text-primary); }
    /* 0fr -> 1fr grid expansion: true content-height animation, no max-height
       clipping cap. The inner wrapper is required (grid items need min-height:0). */
    .faq-a {
      display: grid;
      grid-template-rows: 0fr;
      transition: grid-template-rows 0.5s var(--ease-out-quint), padding 0.3s ease;
      padding: 0 22px;
      font-size: 14px;
      color: var(--text-secondary);
      line-height: 1.7;
    }
    .faq-a-inner {
      overflow: hidden;
      min-height: 0;
    }
    .faq-item.open .faq-a {
      grid-template-rows: 1fr;
      padding: 0 22px 18px 22px;
    }

    /* ===== FINAL CTA ===== */
    .final-cta {
      padding: 90px 0 100px;
      text-align: center;
    }
    .final-cta h2 {
      font-size: clamp(32px, 5vw, 52px);
      font-weight: 800;
      letter-spacing: -1.8px;
      line-height: 1.05;
      margin-bottom: 16px;
    }
    .final-cta p {
      font-size: 17px;
      color: var(--text-secondary);
      max-width: 560px;
      margin: 0 auto 36px;
      line-height: 1.6;
    }
    .final-buttons {
      display: flex;
      flex-direction: column;
      gap: 14px;
      max-width: 380px;
      margin: 0 auto;
    }
    .img-btn {
      display: flex; align-items: center; justify-content: center;
      width: 100%;
      height: 76px;
      background: var(--bg-secondary);
      border: 2px solid var(--border-color);
      border-radius: 14px;
      transition: background-color var(--dur-fast) ease, border-color var(--dur-fast) ease;
      position: relative;
    }
    .img-btn:hover { border-color: rgba(255, 255, 255, 0.35); transform: translateY(-2px); background: var(--bg-tertiary); }
    .img-btn img { height: 36px; width: auto; }
    .boosty-wrap { position: relative; }
    .help-badge {
      position: absolute;
      top: -10px; right: -10px;
      width: 28px; height: 28px;
      /* The chip material, not a white fill (The No Pure White Rule,
         DESIGN.md:190). */
      background: var(--bg-hover); color: var(--text-primary);
      border-radius: 50%;
      font-weight: bold;
      display: flex; align-items: center; justify-content: center;
      border: 3px solid var(--bg-primary);
      box-shadow: 0 4px 10px rgba(0,0,0,0.5);
      transition: transform 0.2s;
      font-size: 14px;
      z-index: 5;
    }
    .help-badge:hover { transform: scale(1.15); }

    /* ===== FOOTER ===== */
    footer {
      border-top: 1px solid var(--border-color);
      padding: 36px 0;
      font-size: 13px;
      color: var(--text-muted);
    }
    .foot-row {
      display: flex;
      flex-direction: column;
      gap: 16px;
      align-items: center;
      text-align: center;
    }
    @media (min-width: 768px) {
      .foot-row { flex-direction: row; justify-content: space-between; text-align: left; }
    }
    .foot-row a { color: var(--text-secondary); transition: color 0.2s; }
    .foot-row a:hover { color: var(--text-primary); }
    .foot-links { display: flex; gap: 20px; flex-wrap: wrap; justify-content: center; }

    /* ===== SCROLL REVEAL ===== */
    .reveal {
      opacity: 0;
      transform: translateY(24px) scale(0.98);
      transition: opacity var(--dur-reveal) var(--ease-out-expo),
                  transform var(--dur-reveal) var(--ease-out-expo),
                  filter var(--dur-reveal) var(--ease-out-expo);
    }
    /* Blur-materialize on section headings only: pure text, one per section.
       Do NOT extend blur to cards (breaks their backdrop-filter sampling on
       every replay) or tilt hosts (filter flattens the 3D subtree). */
    .sec-head.reveal { filter: blur(8px); }
    .reveal.visible {
      opacity: 1;
      transform: none;
      filter: none;
    }
    .reveal.delay-1 { transition-delay: 0.08s; }
    .reveal.delay-2 { transition-delay: 0.16s; }
    .reveal.delay-3 { transition-delay: 0.24s; }
    .reveal.delay-4 { transition-delay: 0.32s; }

    /* Tier locked badge style (gold dot) */
    .tier-mini {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      padding: 4px 10px;
      background: rgba(255,215,0,0.08);
      border: 1px solid rgba(255,215,0,0.25);
      border-radius: 20px;
      font-size: 11px;
      font-weight: 600;
      color: #FFD700;
    }
    .tier-mini::before {
      content: '';
      width: 5px; height: 5px;
      border-radius: 50%;
      background: #FFD700;
    }

    /* Hide scrollbars on horizontal scrollers */
    .marquee-wrap { scrollbar-width: none; }
    .marquee-wrap::-webkit-scrollbar { display: none; }

    /* =========================================
       SERVICE SWITCH (Generate / API / Files in the nav)
       ========================================= */
    /* THE NAME SPRINGS OPEN (2026-09-23, the owner's pick landing.services
       "open" on kammii-demos/review/picker). One glass capsule of glyphs:
       the product on show wears the frosted material and its name springs
       open beside its glyph while the others close to the glyph alone. The
       width is a spring in the script below (stiffness 300, damping 26), so
       a swipe between products can hold two names part open. The sliding
       pill is retired; the element stays hidden so older script finds it. */
    .svc-switch {
      position: relative;
      display: inline-flex;
      align-items: center;
      gap: 4px;
      padding: 4px;
      border-radius: 999px;
      background: rgba(237, 237, 237, 0.05);
      box-shadow: inset -1px 1px 0 rgba(255, 255, 255, 0.10), inset 1px -1px 0 rgba(255, 255, 255, 0.10), 0 4px 19px rgba(0, 0, 0, 0.4);
      flex-shrink: 0;
    }
    .svc-pill { display: none; }
    .svc-btn {
      position: relative;
      display: inline-flex;
      align-items: center;
      height: 36px;
      padding: 0 9px;
      background: transparent;
      border: none;
      border-radius: 999px;
      color: var(--text-secondary);
      font-family: inherit;
      cursor: pointer;
      white-space: nowrap;
      -webkit-tap-highlight-color: transparent;
      transition: background-color 0.3s ease, box-shadow 0.3s ease, color 0.3s ease, transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1));
    }
    .svc-btn svg { width: 18px; height: 18px; flex: none; }
    .svc-btn.active {
      background: rgba(255, 255, 255, 0.12);
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), inset 0 -1px 0 rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.4);
      color: var(--text-primary);
    }
    /* The press is the estate's: .94 on the shared press curves. */
    .svc-btn:active {
      transform: scale(0.94);
      transition: background-color 0.3s ease, box-shadow 0.3s ease, color 0.3s ease, transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1));
    }
    .svc-btn:focus-visible { outline: 1px solid rgba(237, 237, 237, 0.6); outline-offset: 2px; }
    /* The name, clipped to the width the spring gives it. Before the script
       runs, the product on show is open and the others are closed. */
    .svc-w { display: inline-block; overflow: hidden; width: 0; }
    .svc-btn.active .svc-w { width: auto; }
    .svc-l { display: inline-block; padding-left: 7px; padding-right: 3px; font-size: 14px; font-weight: 650; }
    /* =========================================
       CAROUSEL VIEWPORT  iOS-style page swipe
       =========================================
       The viewport wraps all three .svc-content tabs and clips
       horizontal overflow so the neighbor tab is invisible when
       it's positioned at +/-100vw offscreen. */
    .svc-viewport {
      position: relative;
      overflow-x: clip;
      width: 100%;
    }

    /* Default state  only the active tab takes up space.
       Inactive tabs are hidden so they don't render or affect layout. */
    .svc-content {
      display: none;
    }
    .svc-content.active {
      display: block;
    }

    /* During a transition (drag or commit), the viewport gets a flag
       and both the active tab AND its neighbor become positioned.
       Neighbor is absolutely positioned beside the active one. */
    .svc-viewport.svc-transitioning .svc-content.active {
      position: relative;
      z-index: 2;
      will-change: transform;
    }
    .svc-viewport.svc-transitioning .svc-content.svc-neighbor {
      display: block;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      z-index: 1;
      will-change: transform;
      pointer-events: none;
    }
    .svc-content.svc-neighbor-right {
      transform: translate3d(100%, 0, 0);
    }
    .svc-content.svc-neighbor-left {
      transform: translate3d(-100%, 0, 0);
    }
    /* When the carousel commits, both tabs glide together using a CSS
       transition (set inline by JS so we can vary duration). */
    .svc-content.svc-sliding {
      transition: transform 0.32s var(--ease-out-quint);
    }

    /* During-slide cascade: while the neighbor is sliding into view,
       each cascade-item INSIDE it animates from its own offset
       back to 0  staggered. The animation runs concurrently with
       the carousel slide so you see elements settling as the page arrives.
       Direction-aware: left swipe = elements offset to the right,
       right swipe = elements offset to the left. */
    .svc-content.svc-settling-left .cascade-item {
      animation: svcSwipeInFromRight 0.55s var(--ease-out-quint) both;
      animation-delay: calc(var(--cascade-i, 0) * 30ms);
    }
    .svc-content.svc-settling-right .cascade-item {
      animation: svcSwipeInFromLeft 0.55s var(--ease-out-quint) both;
      animation-delay: calc(var(--cascade-i, 0) * 30ms);
    }
    @keyframes svcSwipeInFromRight {
      from { transform: translate3d(120px, 0, 0); }
      to   { transform: translate3d(0, 0, 0); }
    }
    @keyframes svcSwipeInFromLeft {
      from { transform: translate3d(-120px, 0, 0); }
      to   { transform: translate3d(0, 0, 0); }
    }











    /* =========================================
       API HERO MOCK
       ========================================= */
    .api-hero { padding-top: 70px; }
    @media (min-width: 1024px) {
      /* The API introduction is a complete desktop chapter. Center the
         headline, actions, trust row and live answer together in the usable
         viewport below the 72px navigation instead of centering them inside
         a short content-height section. */
      .api-hero {
        min-height: calc(100svh - 72px);
        display: flex;
        align-items: center;
        padding-block: clamp(48px, 6vh, 72px);
      }
      .api-hero > .wrap { width: 100%; }
    }

    /* Small status badge. Born in the old hero mock, still worn by the
       model-swap card further down the page, which recolors it inline. */
    .ttfb-tag {
      display: inline-block;
      background: rgba(74, 222, 128, 0.12);
      color: #30d158;
      font-size: 10px;
      padding: 2px 7px;
      border-radius: 8px;
      border: 1px solid rgba(74, 222, 128, 0.25);
    }

    /* The streaming card used to sit squarely on top of the window's toolbar,
       hiding the traffic lights -- the one cue that reads "macOS window" at a
       glance. Lifting it clear keeps the floating-object depth and gives the
       chrome back. API hero only; the other services' float cards are unchanged. */
    /* =========================================
       API HERO ANSWER
       No frame, no card, no chrome. The reply the model actually returned is
       the whole image; the prompt sits above it in mono at reading size and
       the model that wrote it sits below. Everything else is space.
       ========================================= */
    .apiq {
      margin: 0;
      /* ~40 characters at the display size: a proper measure for type this
         large. `ch` would resolve against the inherited 16px, not the 29px the
         quote is actually set in, so the cap is stated outright. */
      max-width: 470px;
      padding-left: 26px;
      position: relative;
    }
    /* one hairline standing in for a quotation rule -- the only mark on the
       whole column, and it is doing structural work, not decoration */
    .apiq::before {
      content: "";
      position: absolute;
      left: 0;
      top: 6px;
      bottom: 6px;
      width: 1px;
      background: linear-gradient(180deg,
        rgba(255,255,255,0) 0%,
        rgba(255,255,255,0.22) 16%,
        rgba(255,255,255,0.22) 84%,
        rgba(255,255,255,0) 100%);
    }
    .apiq-ask {
      font-family: var(--font-sf);
      font-size: 13px;
      letter-spacing: 0.01em;
      color: var(--text-muted);
      margin-bottom: 20px;
    }
    .apiq-say {
      margin: 0;
      font-size: clamp(21px, 2.05vw, 29px);
      line-height: 1.36;
      letter-spacing: -0.024em;
      font-weight: 400;
      color: var(--text-primary);
      /* the model writes narration in *asterisks*; rendered as italics it
         reads as prose instead of as markup */
      text-wrap: pretty;
    }
    .apiq-say i {
      font-style: italic;
      color: #b6b6bc;
    }
    .apiq-by {
      display: flex;
      align-items: center;
      gap: 9px;
      margin-top: 26px;
      font-family: var(--font-sf);
      font-size: 12px;
      color: var(--text-muted);
    }
    /* the model that wrote it is the interesting half of the caption, so it
       carries slightly more weight than the client it came through */
    .apiq-by > span:first-child { color: var(--text-secondary); }
    .apiq-dot {
      width: 2px; height: 2px; border-radius: 50%;
      background: currentColor;
      opacity: 0.7;
    }
    .apiq-via { color: var(--text-muted); }

    /* One quiet crossfade between examples. No typing, no caret, no counters --
       the column simply holds a different answer the next time you look at it. */
    .apiq.is-turning .apiq-ask,
    .apiq.is-turning .apiq-say,
    .apiq.is-turning .apiq-by { opacity: 0; }
    .apiq-ask, .apiq-say, .apiq-by {
      opacity: 1;
      transition: opacity 0.62s var(--ease-glide);
    }
    .apiq-say { transition-delay: 0.05s; }
    .apiq-by { transition-delay: 0.1s; }

    @media (max-width: 1023px) {
      .apiq { max-width: none; padding-left: 22px; }
      .apiq-say { font-size: clamp(20px, 4.6vw, 26px); }
      .apiq-ask { margin-bottom: 16px; }
      .apiq-by { margin-top: 20px; }
    }

    @media (prefers-reduced-motion: reduce) {
      .apiq-ask, .apiq-say, .apiq-by { transition: none; }
    }

    .api-mock-providers {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      padding: 8px 12px;
      margin-bottom: 10px;
      display: flex;
      flex-direction: column;
      gap: 6px;
    }
    .api-prov-step {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 11px;
      color: var(--text-secondary);
      font-family: var(--font-sf);
    }
    .api-prov-step .dot {
      width: 7px; height: 7px;
      border-radius: 50%;
      background: var(--text-muted);
      flex-shrink: 0;
    }
    .api-prov-step.active .dot { background: #ffbd2e; animation: pulseDot 1s ease-in-out infinite; }
    .api-prov-step.success .dot { background: #30d158; }
    .api-prov-step.failed .dot { background: #ff4444; }
    .api-prov-step .name { color: var(--text-primary); font-weight: 600; }
    .api-prov-step.success .name { color: #30d158; }
    .api-prov-step.failed .name { color: #ff4444; text-decoration: line-through; }
    .api-prov-step .status { margin-left: auto; font-size: 10px; color: var(--text-muted); }

    /* =========================================
       PROVIDER FALLBACK MOCK
       ========================================= */
    .api-providers-mock {
      padding: 22px;
    }
    .prov-flow-title {
      font-size: 11px;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.6px;
      color: var(--text-secondary);
      margin-bottom: 18px;
      text-align: center;
    }
    .prov-chain {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 12px;
    }
    .prov-node {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 14px 18px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 12px;
      width: 100%;
      max-width: 320px;
      box-sizing: border-box;
    }
    .prov-node.kammii {
      background: linear-gradient(135deg, rgba(74,222,128,0.06), rgba(168,85,247,0.06));
      border-color: rgba(255,255,255,0.18);
    }
    .prov-node-icon {
      width: 38px; height: 38px;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      display: flex; align-items: center; justify-content: center;
      flex-shrink: 0;
    }
    .prov-node-icon svg { width: 18px; height: 18px; }
    .prov-node-icon.user-icon { color: var(--text-secondary); }
    .prov-node-info { flex: 1; }
    .prov-node-name {
      font-size: 13px;
      font-weight: 700;
      color: var(--text-primary);
    }
    .prov-node-meta {
      font-size: 11px;
      color: var(--text-muted);
      font-family: var(--font-sf);
      margin-top: 2px;
    }
    .prov-arrow {
      font-size: 20px;
      color: var(--text-muted);
      line-height: 1;
    }
    .prov-providers {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
      gap: 8px;
      width: 100%;
    }
    .prov-card {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      padding: 10px 12px;
      transition: background-color 0.3s ease, border-color 0.3s ease;
      position: relative;
      overflow: hidden;
    }
    .prov-card.active {
      border-color: rgba(255, 189, 46, 0.5);
      background: rgba(255, 189, 46, 0.05);
      transform: translateY(-2px);
      box-shadow: 0 6px 16px rgba(255, 189, 46, 0.12);
    }
    .prov-card.success {
      border-color: rgba(74, 222, 128, 0.5);
      background: rgba(74, 222, 128, 0.05);
    }
    .prov-card.failed {
      opacity: 0.4;
      border-color: rgba(255, 68, 68, 0.4);
    }
    .prov-card.failed::after {
      content: '';
      position: absolute;
      top: 50%; left: 12px; right: 12px;
      height: 1px;
      background: rgba(255, 68, 68, 0.5);
    }
    .prov-card-head {
      display: flex;
      align-items: center;
      gap: 7px;
      margin-bottom: 4px;
    }
    .prov-card-dot {
      width: 7px; height: 7px;
      border-radius: 50%;
      flex-shrink: 0;
    }
    .prov-card-name {
      font-size: 12px;
      font-weight: 700;
      color: var(--text-primary);
    }
    .prov-card-status {
      font-size: 10px;
      color: var(--text-muted);
      font-family: var(--font-sf);
    }
    .prov-card.active .prov-card-status { color: #ffbd2e; }
    .prov-card.success .prov-card-status { color: #30d158; }
    .prov-card.failed .prov-card-status { color: #ff4444; }

    .prov-result {
      margin-top: 6px;
      padding: 12px 16px;
      background: rgba(74, 222, 128, 0.08);
      border: 1px solid rgba(74, 222, 128, 0.3);
      border-radius: 10px;
      display: flex;
      align-items: center;
      gap: 10px;
      width: 100%;
      max-width: 320px;
      box-sizing: border-box;
      opacity: 0;
      transform: translateY(8px);
      transition: opacity 0.4s ease, transform 0.4s ease;
    }
    .prov-result.visible {
      opacity: 1;
      transform: translateY(0);
    }
    .prov-result-icon {
      font-size: 18px;
      color: #30d158;
      font-weight: 800;
    }
    .prov-result-text {
      font-size: 12px;
      color: var(--text-primary);
    }
    .prov-result-text b { color: #30d158; font-variant-numeric: tabular-nums; }
    /* =========================================
       API HERO ENGINE PULSE
       ========================================= */
    .api-engine-pulse {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      padding: 12px 14px;
      margin-bottom: 10px;
    }
    .engine-row {
      display: flex;
      align-items: center;
      gap: 10px;
      font-size: 11px;
      color: var(--text-secondary);
      font-family: var(--font-sf);
      margin-bottom: 6px;
    }
    .engine-k {
      width: 22px; height: 22px;
      display: flex; align-items: center; justify-content: center;
      font-size: 18px; font-weight: 900; line-height: 1;
      color: var(--text-primary);
    }
    .engine-label {
      flex: 1;
      color: var(--text-primary);
    }
    .engine-label.active {
      color: #ffbd2e;
    }
    .engine-ttfb {
      background: rgba(74, 222, 128, 0.12);
      color: #30d158;
      font-size: 10px;
      padding: 2px 7px;
      border-radius: 8px;
      border: 1px solid rgba(74, 222, 128, 0.25);
      opacity: 0;
      transition: opacity 0.3s ease;
    }
    .engine-ttfb.visible { opacity: 1; }
    .engine-bar {
      height: 3px;
      background: rgba(255,255,255,0.06);
      border-radius: 2px;
      overflow: hidden;
    }
    .engine-bar-fill {
      height: 100%;
      width: 0%;
      background: linear-gradient(90deg, #30d158, #fff, #30d158);
      background-size: 200% 100%;
      animation: engineBarShimmer 1.4s linear infinite;
      transition: width 0.6s var(--ease-out-expo);
    }
    @keyframes engineBarShimmer {
      0% { background-position: 200% 0; }
      100% { background-position: -100% 0; }
    }

    /* =========================================
       SPEED MOCK
       ========================================= */
    .api-speed-mock { padding: 22px; }
    .speed-mock-title {
      font-size: 11px;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.6px;
      color: var(--text-secondary);
      margin-bottom: 18px;
      text-align: center;
    }
    .speed-tier { margin-bottom: 16px; }
    .speed-tier:last-child { margin-bottom: 0; }
    .speed-tier-head {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 6px;
    }
    .speed-tier-name {
      display: flex;
      align-items: center;
      gap: 7px;
      font-size: 13px;
      font-weight: 700;
      color: var(--text-primary);
    }
    .speed-tier-time {
      font-size: 14px;
      font-weight: 700;
      color: var(--text-primary);
      font-variant-numeric: tabular-nums;
    }
    .speed-tier-bar {
      height: 6px;
      background: var(--bg-tertiary);
      border-radius: 3px;
      overflow: hidden;
      margin-bottom: 6px;
    }
    .speed-tier-fill {
      height: 100%;
      width: 0%;
      border-radius: 3px;
      background: rgba(255,255,255,0.82);
      transition: width 1.6s var(--ease-out-expo);
    }
    .speed-tier-time { transform-origin: right center; }
    .speed-tier-time.landed { animation: numberLand 0.5s var(--ease-settle); }
    /* iOS-style number landing: pop up, settle back */
    @keyframes numberLand {
      0% { transform: scale(1); }
      35% { transform: scale(1.22); }
      70% { transform: scale(0.96); }
      100% { transform: scale(1); }
    }
    .speed-tier-models {
      font-size: 11px;
      color: var(--text-muted);
      font-family: var(--font-sf);
    }


    /* =========================================
       ROLEPLAY VS BASE
       ========================================= */
    .rp-vs-base {
      display: grid;
      grid-template-columns: 1fr;
      gap: 18px;
    }
    @media (min-width: 768px) {
      .rp-vs-base { grid-template-columns: 1fr 1fr; gap: 22px; }
    }
    .rp-card {
      background: var(--glass-bg);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      border: 1px solid var(--hairline);
      border-radius: 18px;
      padding: 28px;
      transition: border-color 0.3s ease;
    }
    .rp-card:hover { border-color: var(--hairline-hover); }
    .rp-card-head {
      display: flex;
      align-items: center;
      gap: 14px;
      margin-bottom: 20px;
      padding-bottom: 18px;
      border-bottom: 1px solid var(--border-color);
    }
    .rp-card-icon {
      width: 48px; height: 48px;
      border-radius: 12px;
      display: flex; align-items: center; justify-content: center;
      flex-shrink: 0;
      background: var(--bg-tertiary) !important;
      border: 1px solid var(--border-color);
      color: var(--text-primary);
    }
    .rp-card-icon svg { width: 24px; height: 24px; stroke: var(--text-primary) !important; }
    .rp-card-head h3 { font-size: 19px; font-weight: 800; margin-bottom: 3px; }
    .rp-card-sub {
      font-size: 12px;
      color: var(--text-muted);
      margin: 0;
    }
    .rp-card-list {
      list-style: none;
      margin-bottom: 18px;
    }
    .rp-card-list li {
      font-size: 13px;
      color: var(--text-secondary);
      padding: 7px 0;
      border-bottom: 1px solid var(--border-color);
      display: flex;
      align-items: center;
      gap: 8px;
    }
    .rp-card-list li:last-child { border-bottom: none; }
    .rp-card-list li {
      flex-wrap: wrap;
      min-width: 0;
    }
    .rp-card-list li b {
      color: var(--text-primary);
      font-weight: 700;
      min-width: 0;
      flex-shrink: 0;
    }
    @media (min-width: 480px) {
      .rp-card-list li b { min-width: 130px; }
    }
    .rp-card {
      min-width: 0;
      overflow: hidden;
    }
    .rp-card-tag {
      padding: 10px 14px;
      background: var(--bg-tertiary);
      border-radius: 10px;
      font-size: 12px;
      color: var(--text-muted);
      text-align: center;
    }
    .rp-toggle-note {
      margin-top: 26px;
      padding: 16px 20px;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 12px;
      display: flex;
      align-items: flex-start;
      gap: 12px;
      max-width: 760px;
      margin-left: auto;
      margin-right: auto;
    }
    .rp-toggle-note svg {
      width: 20px; height: 20px;
      color: #ffbd2e;
      flex-shrink: 0;
      margin-top: 1px;
    }
    .rp-toggle-note span {
      font-size: 13px;
      color: var(--text-secondary);
      line-height: 1.6;
    }
    .rp-toggle-note b { color: var(--text-primary); }

    /* =========================================
       WORKS WITH: LOGO CAPSULES
       ========================================= */
    /* 2026-09-23, the owner's pick landing.logos "caps". The four cards and
       their grey glyphs are one row of capsules, each carrying the app's OWN
       icon (api-worker/dashboard/apps.mjs, the same images the API dashboard
       uses, spliced into this head by worker-src.js) with a blurred copy of
       it orbiting inside (main-domain-worker/brand-marks.js .kb-glow). A tap
       swaps the one setup line under the row. The capsule is the button
       standard's Secondary surface at size L with the estate press. */
    .lc {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      gap: 10px;
    }
    .lc-i {
      display: inline-flex;
      align-items: center;
      gap: 10px;
      min-height: 44px;
      padding: 0 20px 0 12px;
      border: 0;
      border-radius: 999px;
      background: rgba(237, 237, 237, 0.05);
      box-shadow: inset -1px 1px 0 rgba(255, 255, 255, 0.10), inset 1px -1px 0 rgba(255, 255, 255, 0.10), 0 4px 19px rgba(0, 0, 0, 0.4);
      color: var(--text-primary);
      font-family: inherit;
      font-size: 15px;
      font-weight: 650;
      cursor: pointer;
      -webkit-tap-highlight-color: transparent;
      transition: transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1));
    }
    .lc-i:active { transform: scale(0.94); transition: transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
    .lc-i:focus-visible { outline: 1px solid rgba(237, 237, 237, 0.6); outline-offset: 2px; }
    .lc-i .kb-mark { width: 24px; height: 24px; border-radius: 6px; }
    .lc-i .lc-term { display: grid; place-items: center; background: none; color: var(--text-secondary); }
    .lc-i .lc-term svg { width: 16px; height: 16px; }
    .lc-p {
      margin: 20px auto 0;
      max-width: 460px;
      min-height: 3em;
      text-align: center;
      font-size: 15px;
      line-height: 1.5;
      color: var(--text-secondary);
      text-wrap: balance;
    }
    .lc-p b { color: var(--text-primary); font-weight: 600; }
    .lc-p.swap-out { animation: heroWordOut 0.22s var(--ease-out-quint) forwards; }
    .lc-p.swap-in { animation: heroWordIn 0.5s var(--ease-out-quint); }
    @media (prefers-reduced-motion: reduce) {
      .lc-p.swap-out, .lc-p.swap-in { animation: none; }
    }

    /* =========================================
       CODE MOCK
       ========================================= */
    .code-mock {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 14px;
      overflow: hidden;
      box-shadow: 0 24px 60px rgba(0,0,0,0.4);
    }
    .code-mock-head {
      display: flex;
      align-items: center;
      gap: 14px;
      padding: 12px 16px;
      background: var(--bg-tertiary);
      border-bottom: 1px solid var(--border-color);
    }
    .code-mock-head .dots { display: flex; gap: 6px; }
    .code-mock-head .dots span {
      width: 10px; height: 10px;
      border-radius: 50%;
      background: var(--bg-secondary);
    }
    .code-tabs {
      display: flex;
      gap: 4px;
      margin-left: auto;
    }
    .code-tab {
      padding: 6px 14px;
      background: transparent;
      border: 1px solid transparent;
      color: var(--text-muted);
      font-size: 12px;
      font-weight: 600;
      cursor: pointer;
      border-radius: 7px;
      transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
      font-family: inherit;
    }
    .code-tab:hover { color: var(--text-secondary); }
    .code-tab.active {
      background: var(--bg-secondary);
      border-color: var(--border-color);
      color: var(--text-primary);
    }
    .code-mock-body {
      padding: 22px 24px;
      overflow-x: auto;
    }
    .code-block {
      font-family: var(--font-sf);
      font-size: 13px;
      color: var(--text-secondary);
      line-height: 1.7;
      white-space: pre;
    }
    .code-block .code-keyword { color: #a855f7; font-weight: 600; }
    .code-block .code-string { color: #30d158; }
    .code-block .code-num { color: #ffbd2e; }

    @media (max-width: 640px) {
      .code-mock-body { padding: 16px; }
      .code-block { font-size: 11px; }
      .code-tabs { gap: 2px; }
      .code-tab { padding: 5px 9px; font-size: 11px; }
    }
          /* =========================================
       NEW: WORKFLOW (GEN)
       ========================================= */
    .workflow-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 16px;
      align-items: stretch;
      margin-bottom: 36px;
    }
    @media (min-width: 900px) {
      .workflow-grid {
        grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr;
        gap: 12px;
      }
    }
    .workflow-step {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius);
      padding: 22px;
      position: relative;
      transition: border-color 0.3s ease, transform 0.3s ease;
    }
    .workflow-step:hover { border-color: var(--hairline-hover); }
    .workflow-num {
      position: absolute;
      top: 14px; right: 16px;
      font-size: 32px;
      font-weight: 900;
      color: var(--bg-tertiary);
      line-height: 1;
    }
    .workflow-icon {
      width: 38px; height: 38px;
      border-radius: 10px;
      display: flex; align-items: center; justify-content: center;
      margin-bottom: 14px;
    }
    .workflow-icon svg { width: 18px; height: 18px; }
    .workflow-step h3 {
      font-size: 15px;
      font-weight: 700;
      margin-bottom: 6px;
    }
    .workflow-step p {
      font-size: 13px;
      color: var(--text-secondary);
      line-height: 1.5;
    }
    .workflow-arrow {
      display: none;
      align-items: center;
      justify-content: center;
      color: var(--text-muted);
    }
    @media (min-width: 900px) {
      .workflow-arrow { display: flex; }
    }
    .workflow-arrow svg { width: 18px; height: 18px; }
    .workflow-demo {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius);
      padding: 18px;
      box-shadow: 0 24px 60px rgba(0,0,0,0.4);
    }
    .workflow-demo-frame {
      background: var(--bg-tertiary);
      border-radius: 12px;
      padding: 14px 16px;
    }
    .workflow-demo-titlebar {
      display: flex;
      align-items: center;
      gap: 14px;
      margin-bottom: 10px;
    }
    .workflow-demo-step-label {
      font-size: 11px;
      font-weight: 700;
      color: var(--text-secondary);
      text-transform: uppercase;
      letter-spacing: 0.5px;
      flex-shrink: 0;
    }
    .workflow-demo-progress {
      flex: 1;
      height: 4px;
      background: var(--bg-secondary);
      border-radius: 2px;
      overflow: hidden;
    }
    .workflow-demo-progress-fill {
      height: 100%;
      width: 25%;
      background: linear-gradient(90deg, #30d158, #fff, #30d158);
      background-size: 200% 100%;
      animation: engineBarShimmer 1.4s linear infinite;
      transition: width 0.6s var(--ease-out-expo);
    }
    .workflow-demo-body { padding: 6px 2px; }
    .workflow-demo-prompt {
      font-size: 12px;
      font-family: var(--font-sf);
      color: var(--text-primary);
      line-height: 1.6;
      margin-bottom: 10px;
      min-height: 40px;
    }
    .workflow-demo-action {
      font-size: 11px;
      color: var(--text-muted);
      font-family: var(--font-sf);
    }

    /* Render timeline (replacement for old workflow-demo content) */
    .render-timeline-frame {
      background: var(--bg-tertiary);
      border-radius: 12px;
      padding: 22px 26px 20px 26px;
    }
    .render-timeline-head {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 28px;
    }
    .render-timeline-title {
      font-size: 11px;
      font-weight: 700;
      letter-spacing: 0.6px;
      text-transform: uppercase;
      color: var(--text-secondary);
    }
    .render-timeline-elapsed {
      font-size: 13px;
      font-weight: 800;
      color: var(--text-primary);
      font-variant-numeric: tabular-nums;
      font-family: var(--font-sf);
    }
    .render-timeline-track {
      position: relative;
      height: 4px;
      background: var(--bg-secondary);
      border-radius: 2px;
      margin: 0 8px 44px 8px;
    }
    .render-timeline-fill {
      position: absolute;
      top: 0; left: 0;
      height: 100%;
      width: 0%;
      background: rgba(255,255,255,0.9);
      border-radius: 2px;
      transition: width 1.4s var(--ease-out-expo);
    }
    .render-timeline-dot {
      position: absolute;
      top: 50%;
      left: 0%;
      width: 14px;
      height: 14px;
      border-radius: 50%;
      background: #ffffff;
      box-shadow: 0 0 0 4px rgba(255,255,255,0.12), 0 0 18px rgba(255,255,255,0.5);
      transform: translate(-50%, -50%);
      transition: left 1.4s cubic-bezier(0.22, 0.61, 0.36, 1);
    }
    .render-timeline-checkpoints {
      position: absolute;
      top: 0; left: 0; right: 0; bottom: 0;
      pointer-events: none;
    }
    .render-timeline-checkpoint {
      position: absolute;
      top: 50%;
      transform: translate(-50%, -50%);
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 18px;
    }
    .render-timeline-checkpoint[data-cp="prompt"] { left: 0%; }
    .render-timeline-checkpoint[data-cp="render"] { left: 50%; }
    .render-timeline-checkpoint[data-cp="save"]   { left: 100%; }
    .render-cp-pin {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: var(--bg-secondary);
      border: 2px solid var(--border-color);
      transition: background 0.3s ease, border-color 0.3s ease, transform 0.3s ease;
    }
    .render-timeline-checkpoint.reached .render-cp-pin {
      background: #ffffff;
      border-color: #ffffff;
      transform: scale(1.15);
    }
    .render-cp-label {
      position: absolute;
      top: 22px;
      font-size: 11px;
      font-weight: 700;
      color: var(--text-muted);
      letter-spacing: 0.4px;
      text-transform: uppercase;
      transition: color 0.3s ease;
      white-space: nowrap;
    }
    .render-timeline-checkpoint.reached .render-cp-label {
      color: var(--text-primary);
    }
    .render-timeline-stats {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 8px;
    }
    .render-stat-chip {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 8px;
      padding: 8px 12px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
      min-width: 0;
    }
    .render-stat-key {
      font-size: 10px;
      font-weight: 800;
      letter-spacing: 0.5px;
      text-transform: uppercase;
      color: var(--text-muted);
      flex-shrink: 0;
    }
    .render-stat-val {
      font-size: 12px;
      color: var(--text-primary);
      font-weight: 600;
      font-family: var(--font-sf);
      text-align: right;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    @media (max-width: 640px) {
      .render-timeline-frame { padding: 18px 18px 16px 18px; }
      .render-timeline-stats { grid-template-columns: 1fr; }
    }


    /* =========================================
       NEW: HQ MODE (GEN)
       ========================================= */
    .hq-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 18px;
      margin-bottom: 26px;
    }
    @media (min-width: 768px) { .hq-grid { grid-template-columns: 1fr 1fr; } }
    .hq-card {
      background: var(--glass-bg);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      border: 1px solid var(--hairline);
      border-radius: 18px;
      padding: 26px;
      transition: border-color 0.3s ease;
    }
    .hq-card:hover { border-color: var(--hairline-hover); }
    .hq-card-featured {
      background: linear-gradient(180deg, rgba(255,215,0,0.04), var(--bg-secondary));
      border-color: rgba(255,215,0,0.25);
    }
    .hq-card-head { margin-bottom: 18px; }
    .hq-tag {
      display: inline-block;
      padding: 4px 10px;
      background: var(--bg-tertiary);
      color: var(--text-secondary);
      font-size: 10px;
      font-weight: 800;
      letter-spacing: 0.6px;
      border-radius: 20px;
      margin-bottom: 10px;
    }
    .hq-tag-featured {
      background: rgba(255,215,0,0.12);
      color: #FFD700;
      border: 1px solid rgba(255,215,0,0.3);
    }
    .hq-card h3 { font-size: 18px; font-weight: 800; }
    .hq-card-list {
      list-style: none;
      margin-bottom: 18px;
    }
    .hq-card-list li {
      display: flex;
      align-items: flex-start;
      gap: 10px;
      padding: 8px 0;
      font-size: 13px;
      color: var(--text-secondary);
      border-bottom: 1px solid var(--border-color);
    }
    .hq-card-list li:last-child { border-bottom: none; }
    .hq-card-list li svg { width: 16px; height: 16px; color: #30d158; flex-shrink: 0; margin-top: 2px; }
    .hq-card-list li b { color: var(--text-primary); font-weight: 700; }
    .hq-card-cost {
      padding: 10px 14px;
      background: var(--bg-tertiary);
      border-radius: 10px;
      font-size: 13px;
      font-weight: 700;
      color: var(--text-primary);
      text-align: center;
    }
    .hq-card-featured .hq-card-cost {
      background: rgba(255,215,0,0.1);
      color: #FFD700;
    }
    .hq-tip {
      display: flex;
      align-items: flex-start;
      gap: 12px;
      padding: 14px 18px;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 12px;
      max-width: 760px;
      margin: 0 auto;
    }
    .hq-tip svg { width: 18px; height: 18px; color: #ffbd2e; flex-shrink: 0; margin-top: 2px; }
    .hq-tip span { font-size: 13px; color: var(--text-secondary); line-height: 1.6; }
    .hq-tip b { color: var(--text-primary); }

    /* =========================================
       NEW: USE CASES GRID (shared)
       ========================================= */
    .usecase-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 16px;
    }
    @media (min-width: 640px) { .usecase-grid { grid-template-columns: repeat(2, 1fr); } }
    @media (min-width: 1024px) { .usecase-grid { grid-template-columns: repeat(3, 1fr); } }
    .usecase-card {
      background: var(--glass-bg);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      border: 1px solid var(--hairline);
      border-radius: 18px;
      padding: 22px;
      transition: border-color 0.3s ease;
    }
    .usecase-card:hover { border-color: var(--hairline-hover); }
    .usecase-icon {
      width: 44px; height: 44px;
      border-radius: 12px;
      display: flex; align-items: center; justify-content: center;
      margin-bottom: 14px;
      background: var(--bg-tertiary) !important;
      border: 1px solid var(--border-color);
      color: var(--text-primary);
    }
    .usecase-icon svg { width: 24px; height: 24px; stroke: var(--text-primary) !important; }
    .usecase-card h3 { font-size: 16px; font-weight: 700; margin-bottom: 8px; }
    .usecase-card p {
      font-size: 13px;
      color: var(--text-secondary);
      line-height: 1.6;
      margin-bottom: 14px;
    }
    .usecase-meta {
      display: flex;
      flex-wrap: wrap;
      gap: 6px;
    }
    .usecase-tag {
      padding: 4px 9px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      /* Squared off with the other inline labels on the page (.ttfb-tag,
         .feat-tag). At 14px on a 26px tag these read as pills, which the
         page no longer uses. */
      border-radius: 6px;
      font-size: 11px;
      font-weight: 600;
      color: var(--text-secondary);
    }

    /* =========================================
       NEW: WHY-SWITCH (API)
       ========================================= */
    .why-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 18px;
    }
    @media (min-width: 1024px) { .why-grid { grid-template-columns: repeat(3, 1fr); } }
    .why-card {
      background: var(--glass-bg);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      border: 1px solid var(--hairline);
      border-radius: 18px;
      padding: 28px 24px 24px 24px;
      position: relative;
      transition: border-color 0.3s ease;
    }
    .why-card:hover { border-color: var(--hairline-hover); }
    .why-num {
      position: absolute;
      top: 18px; right: 22px;
      font-size: 38px;
      font-weight: 900;
      color: var(--bg-tertiary);
      line-height: 1;
      letter-spacing: -1.5px;
    }
    .why-icon {
      width: 44px; height: 44px;
      border-radius: 12px;
      display: flex; align-items: center; justify-content: center;
      margin-bottom: 18px;
      background: var(--bg-tertiary) !important;
      border: 1px solid var(--border-color);
      color: var(--text-primary);
    }
    .why-icon svg { width: 24px; height: 24px; stroke: var(--text-primary) !important; }
    .why-card h3 {
      font-size: 19px;
      font-weight: 800;
      margin-bottom: 10px;
    }
    .why-card-sub {
      font-size: 14px;
      color: var(--text-secondary);
      line-height: 1.65;
      margin-bottom: 18px;
    }
    .why-comparison {
      background: var(--bg-tertiary);
      border-radius: 10px;
      padding: 12px 14px;
    }
    .why-comparison-row {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 6px 0;
      font-size: 12px;
    }
    .why-comparison-row + .why-comparison-row {
      border-top: 1px solid var(--border-color);
    }
    .why-comparison-label { color: var(--text-secondary); }
    .why-comparison-value { color: var(--text-primary); font-weight: 700; }
    .why-comparison-bad { color: #f87171 !important; }
    .why-comparison-good { color: #30d158 !important; }
    .why-tip-list {
      display: flex;
      flex-direction: column;
      gap: 8px;
    }
    .why-tip-row {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 10px 12px;
      background: var(--bg-tertiary);
      border-radius: 8px;
      font-size: 13px;
      color: var(--text-secondary);
    }
    .why-tip-row svg { width: 16px; height: 16px; flex-shrink: 0; }
    .why-config-mock {
      background: var(--bg-tertiary);
      border-radius: 10px;
      padding: 12px 14px;
      font-family: var(--font-sf);
    }
    .why-config-line {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 5px 0;
      font-size: 12px;
    }
    .why-config-line + .why-config-line { border-top: 1px solid var(--border-color); margin-top: 5px; padding-top: 8px; }
    .why-config-label {
      font-size: 10px;
      font-weight: 800;
      letter-spacing: 0.5px;
      color: var(--text-muted);
      width: 42px;
      flex-shrink: 0;
    }
    .why-config-line code {
      color: var(--text-primary);
      background: transparent;
      font-size: 12px;
    }

    /* =========================================
       NEW: CONVERSATION DEMO (API)
       ========================================= */
    .conv-demo-wrap {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius);
      overflow: hidden;
      box-shadow: 0 24px 60px rgba(0,0,0,0.4);
    }
    .conv-demo-toolbar {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 16px;
      padding: 14px 18px;
      background: var(--bg-tertiary);
      border-bottom: 1px solid var(--border-color);
      flex-wrap: wrap;
    }
    .conv-demo-model-pills {
      display: flex;
      gap: 6px;
    }
    .conv-demo-pill {
      padding: 7px 14px;
      background: transparent;
      border: 1px solid var(--border-color);
      color: var(--text-muted);
      font-size: 12px;
      font-weight: 700;
      cursor: pointer;
      border-radius: 20px;
      font-family: inherit;
      transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
    }
    .conv-demo-pill:hover { color: var(--text-secondary); }
    .conv-demo-pill.active {
      background: var(--bg-secondary);
      border-color: rgba(255,255,255,0.2);
      color: var(--text-primary);
    }
    .conv-demo-thinking {
      display: flex;
      align-items: center;
      gap: 10px;
    }
    .conv-demo-thinking-label {
      font-size: 11px;
      font-weight: 700;
      color: var(--text-muted);
      text-transform: uppercase;
      letter-spacing: 0.5px;
    }
    .conv-demo-thinking-toggle {
      background: none;
      border: none;
      cursor: pointer;
      padding: 0;
    }
    .conv-demo-thinking-track {
      display: block;
      width: 36px;
      height: 20px;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 20px;
      position: relative;
      transition: background-color 0.25s ease, border-color 0.25s ease;
    }
    .conv-demo-thinking-knob {
      position: absolute;
      top: 2px; left: 2px;
      width: 14px; height: 14px;
      background: var(--text-muted);
      border-radius: 50%;
      transition: transform 0.25s var(--ease-pill), background-color 0.25s ease;
    }
    .conv-demo-thinking-toggle.active .conv-demo-thinking-track {
      background: rgba(74,222,128,0.15);
      border-color: rgba(74,222,128,0.4);
    }
    .conv-demo-thinking-toggle.active .conv-demo-thinking-knob {
      transform: translateX(16px);
      background: #30d158;
    }
    .conv-demo-stream {
      padding: 18px 20px;
      display: flex;
      flex-direction: column;
      gap: 12px;
      min-height: 260px;
    }
    .conv-demo-msg {
      padding: 12px 14px;
      border-radius: 10px;
    }
    .conv-demo-user {
      background: rgba(59, 130, 246, 0.06);
      border: 1px solid rgba(59, 130, 246, 0.18);
      align-self: flex-end;
      max-width: 80%;
    }
    .conv-demo-assistant {
      background: rgba(74, 222, 128, 0.06);
      border: 1px solid rgba(74, 222, 128, 0.18);
      align-self: flex-start;
      max-width: 90%;
    }
    .conv-demo-thinking-block {
      background: rgba(255, 189, 46, 0.05);
      border: 1px solid rgba(255, 189, 46, 0.18);
      align-self: stretch;
      max-width: 100%;
      display: none;
      animation: conv-fade-in 0.4s ease;
    }
    .conv-demo-thinking-block.visible { display: block; }
    @keyframes conv-fade-in {
      from { opacity: 0; transform: translateY(8px); }
      to { opacity: 1; transform: translateY(0); }
    }
    .conv-demo-role {
      font-size: 10px;
      font-weight: 800;
      letter-spacing: 0.5px;
      color: var(--text-muted);
      margin-bottom: 6px;
      display: flex;
      align-items: center;
      gap: 8px;
    }
    .conv-demo-text {
      font-size: 13px;
      color: var(--text-primary);
      line-height: 1.6;
      white-space: pre-wrap;
    }
    .conv-demo-think-text {
      color: var(--text-secondary);
      font-style: italic;
      font-size: 12px;
    }
    .conv-demo-think-time {
      background: rgba(255, 189, 46, 0.12);
      color: #ffbd2e;
      font-size: 10px;
      padding: 2px 7px;
      border-radius: 8px;
      border: 1px solid rgba(255, 189, 46, 0.25);
      font-weight: 700;
      margin-left: auto;
    }
    .conv-demo-ttfb {
      background: rgba(74, 222, 128, 0.12);
      color: #30d158;
      font-size: 10px;
      padding: 2px 7px;
      border-radius: 8px;
      border: 1px solid rgba(74, 222, 128, 0.25);
      font-weight: 700;
    }
    .conv-demo-footer {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 0;
      padding: 14px 0;
      background: var(--bg-tertiary);
      border-top: 1px solid var(--border-color);
    }
    .conv-demo-stat {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 4px;
      border-right: 1px solid var(--border-color);
      padding: 4px 0;
    }
    .conv-demo-stat:last-child { border-right: none; }
    .conv-demo-stat-label {
      font-size: 10px;
      font-weight: 700;
      letter-spacing: 0.5px;
      color: var(--text-muted);
      text-transform: uppercase;
    }
    .conv-demo-stat-value {
      font-size: 14px;
      font-weight: 800;
      color: var(--text-primary);
      font-variant-numeric: tabular-nums;
    }

    /* =========================================
       NEW: TOOLKIT (API)
       ========================================= */
    .toolkit-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 18px;
    }
    @media (min-width: 768px) { .toolkit-grid { grid-template-columns: 1fr 1fr; } }
    @media (max-width: 768px) {
      #api-toolkit { display: none !important; }
    }
    .toolkit-card {
      background: var(--glass-bg);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      border: 1px solid var(--hairline);
      border-radius: 18px;
      padding: 24px;
      transition: border-color 0.3s ease;
    }
    .toolkit-card:hover { border-color: var(--hairline-hover); }
    .toolkit-card-head {
      display: flex;
      align-items: center;
      gap: 14px;
      margin-bottom: 14px;
    }
    .toolkit-icon {
      width: 40px; height: 40px;
      border-radius: 11px;
      display: flex; align-items: center; justify-content: center;
      flex-shrink: 0;
      background: var(--bg-tertiary) !important;
      border: 1px solid var(--border-color);
      color: var(--text-primary);
    }
    .toolkit-icon svg { width: 20px; height: 20px; stroke: var(--text-primary) !important; }
    .toolkit-card h3 { font-size: 17px; font-weight: 700; }
    .toolkit-card-desc {
      font-size: 13px;
      color: var(--text-secondary);
      line-height: 1.6;
      margin-bottom: 16px;
    }
    .toolkit-card-desc code {
      background: var(--bg-tertiary);
      padding: 1px 5px;
      border-radius: 3px;
      font-size: 11px;
    }
    .toolkit-mock {
      background: var(--bg-tertiary);
      border-radius: 10px;
      padding: 14px;
    }
    .toolkit-slider-row {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 6px 0;
      font-size: 12px;
    }
    .toolkit-slider-label {
      width: 80px;
      color: var(--text-secondary);
      flex-shrink: 0;
      font-weight: 600;
    }
    .toolkit-slider-track {
      flex: 1;
      height: 4px;
      background: var(--bg-secondary);
      border-radius: 2px;
      position: relative;
    }
    .toolkit-slider-fill {
      height: 100%;
      background: linear-gradient(90deg, rgba(255,255,255,0.5), rgba(255,255,255,0.9));
      border-radius: 2px;
      position: relative;
      /* Spring: knob overshoots the new value and settles, like a real drag */
      transition: width 0.9s var(--ease-out-expo);
    }
    /* iOS-style slider thumb riding the end of the fill */
    .toolkit-slider-fill::after {
      content: '';
      position: absolute;
      right: -5px; top: 50%;
      width: 11px; height: 11px;
      transform: translateY(-50%);
      border-radius: 50%;
      background: #fff;
      box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5), 0 0 0 0.5px rgba(0, 0, 0, 0.15);
    }
    .toolkit-slider-value {
      width: 36px;
      text-align: right;
      color: var(--text-primary);
      font-weight: 700;
      font-family: var(--font-sf);
      flex-shrink: 0;
      transform-origin: right center;
    }
    .toolkit-slider-value.landed { animation: numberLand 0.45s var(--ease-settle); }
    .toolkit-preset-list {
      display: flex;
      flex-direction: column;
      gap: 6px;
    }
    .toolkit-preset-item {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 10px 12px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 8px;
      font-size: 13px;
      color: var(--text-secondary);
      transition: background 0.35s ease, border-color 0.35s ease, color 0.35s ease;
    }
    .toolkit-preset-item.active {
      background: rgba(255,255,255,0.04);
      border-color: rgba(255,255,255,0.25);
      color: var(--text-primary);
    }
    .toolkit-preset-item svg { width: 16px; height: 16px; flex-shrink: 0; }
    /* Check + dot swap with a spring pop when the active preset changes */
    .toolkit-preset-item .toolkit-preset-check { display: none; }
    .toolkit-preset-item.active .toolkit-preset-check { display: block; animation: checkPop 0.45s var(--ease-settle); }
    .toolkit-preset-item.active .toolkit-preset-dot { display: none; }
    @keyframes checkPop {
      0% { transform: scale(0.3); opacity: 0; }
      60% { transform: scale(1.15); }
      100% { transform: scale(1); opacity: 1; }
    }
    .toolkit-preset-dot {
      width: 7px; height: 7px;
      border-radius: 50%;
      background: var(--text-muted);
      margin-left: 3px;
      flex-shrink: 0;
    }
    .toolkit-preset-tokens {
      margin-left: auto;
      font-size: 10px;
      color: var(--text-muted);
      font-family: var(--font-sf);
    }
    .toolkit-stats-mock {
      background: var(--bg-tertiary);
      border-radius: 10px;
      padding: 14px;
      display: flex;
      flex-direction: column;
      gap: 10px;
    }
    .toolkit-stats-row {
      display: flex;
      align-items: center;
      gap: 12px;
      font-size: 12px;
    }
    .toolkit-stats-label {
      width: 70px;
      color: var(--text-secondary);
      flex-shrink: 0;
      font-weight: 600;
    }
    .toolkit-stats-bar {
      flex: 1;
      height: 6px;
      background: var(--bg-secondary);
      border-radius: 3px;
      overflow: hidden;
    }
    .toolkit-stats-bar-fill {
      height: 100%;
      border-radius: 3px;
      /* Spring: slight overshoot, then settle */
      transition: width 1.1s var(--ease-out-expo);
    }
    .toolkit-stats-num.landed { animation: numberLand 0.45s var(--ease-settle); }
    .toolkit-stats-num {
      width: 40px;
      text-align: right;
      color: var(--text-primary);
      font-weight: 800;
      transform-origin: right center;
      font-family: var(--font-sf);
      flex-shrink: 0;
    }
    .toolkit-swap-mock {
      background: var(--bg-tertiary);
      border-radius: 10px;
      padding: 16px 14px;
    }
    .toolkit-swap-row {
      display: flex;
      align-items: center;
      gap: 14px;
      justify-content: center;
      padding: 6px 0 12px 0;
      border-bottom: 1px solid var(--border-color);
      margin-bottom: 12px;
    }
    .toolkit-swap-from code,
    .toolkit-swap-to code {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      padding: 6px 12px;
      border-radius: 7px;
      font-size: 12px;
      color: var(--text-primary);
      font-family: var(--font-sf);
      font-weight: 600;
    }
    .toolkit-swap-to code {
      border-color: rgba(255,255,255,0.35);
      color: var(--text-primary);
    }
    .toolkit-swap-status {
      text-align: center;
    }

    /* =========================================
       NEW: PRIVACY MOCK
       ========================================= */
    .privacy-mock {
      padding: 28px 22px;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 22px;
    }
    .privacy-lock-anim {
      width: 120px; height: 120px;
      flex-shrink: 0;
    }
    .privacy-lock-svg {
      width: 100%; height: 100%;
      overflow: visible;
      transition: filter 0.6s ease;
    }
    /* ===== Physical lock animation =====
       The lock starts open. When "encrypted" fires, the shackle springs shut
       (overshoot + settle), the body absorbs the impact with a squash, a
       ripple radiates from the click and the keyhole gives a key-turn.
       Completion tints everything green with a confirm bounce; the next
       cycle springs the shackle back open. */
    .lock-group {
      animation: lockBreathe 6s ease-in-out infinite;
    }
    .lock-shackle {
      transform-box: view-box;
      transform-origin: 65px 45px;
      transform: translateY(-9px) rotate(-14deg);
      transition: transform 0.65s var(--ease-settle), stroke 0.6s ease;
    }
    #privacyLockAnim.locked .lock-shackle { transform: none; }
    .lock-body {
      transform-box: view-box;
      transform-origin: 50px 73px;
    }
    #privacyLockAnim.locked .lock-body { animation: lockImpact 0.5s 0.32s var(--ease-settle) both; }
    .lock-body rect { transition: stroke 0.6s ease, fill 0.6s ease; }
    .lock-keyhole {
      transform-box: view-box;
      transform-origin: 50px 58px;
    }
    #privacyLockAnim.locked .lock-keyhole { animation: lockKeyTurn 0.55s 0.52s var(--ease-settle) both; }
    .lock-keyhole circle { transition: fill 0.6s ease; }
    .lock-keyhole line { transition: stroke 0.6s ease; }
    .lock-ripple {
      transform-box: view-box;
      transform-origin: 50px 56px;
      opacity: 0;
    }
    #privacyLockAnim.locked .lock-ripple { animation: lockRipple 0.9s 0.36s var(--ease-out-quint) both; }
    #privacyLockAnim.complete .lock-shackle { stroke: var(--text-primary); }
    #privacyLockAnim.complete .lock-body rect { stroke: var(--text-primary); fill: rgba(255, 255, 255, 0.08); }
    #privacyLockAnim.complete .lock-keyhole circle { fill: var(--text-primary); }
    #privacyLockAnim.complete .lock-keyhole line { stroke: var(--text-primary); }
    #privacyLockAnim.complete #privacyLockRing { stroke: var(--text-primary); }
    #privacyLockAnim.complete .privacy-lock-svg {
      animation: lockConfirm 0.7s var(--ease-settle);
      filter: none;
    }
    @keyframes lockBreathe {
      0%, 100% { transform: translateY(0); }
      50% { transform: translateY(-2px); }
    }
    @keyframes lockImpact {
      0% { transform: scale(1, 1); }
      35% { transform: scale(1.06, 0.92); }
      65% { transform: scale(0.97, 1.03); }
      100% { transform: scale(1, 1); }
    }
    @keyframes lockKeyTurn {
      0% { transform: rotate(0); }
      40% { transform: rotate(-28deg); }
      75% { transform: rotate(12deg); }
      100% { transform: rotate(0); }
    }
    @keyframes lockRipple {
      0% { transform: scale(0.55); opacity: 0.6; }
      100% { transform: scale(1.5); opacity: 0; }
    }
    @keyframes lockConfirm {
      0% { transform: scale(1); }
      40% { transform: scale(1.07); }
      70% { transform: scale(0.985); }
      100% { transform: scale(1); }
    }
    @media (prefers-reduced-motion: reduce) {
      .lock-group,
      #privacyLockAnim.locked .lock-body,
      #privacyLockAnim.locked .lock-keyhole,
      #privacyLockAnim.locked .lock-ripple,
      #privacyLockAnim.complete .privacy-lock-svg { animation: none; }
      .lock-shackle { transition: stroke 0.6s ease; }
    }
    .privacy-flow-list {
      width: 100%;
      display: flex;
      flex-direction: column;
      gap: 8px;
    }
    .privacy-flow-row {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 12px 14px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      font-size: 13px;
      height: 46px;
      box-sizing: border-box;
      transition: border-color 0.3s ease, background 0.3s ease;
    }
    .privacy-flow-row.active {
      border-color: rgba(255, 255, 255, 0.25);
      background: rgba(255, 255, 255, 0.03);
    }
    .privacy-flow-row.done {
      border-color: rgba(255, 255, 255, 0.18);
    }
    .privacy-flow-step {
      width: 22px; height: 22px;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 10px;
      font-weight: 800;
      color: var(--text-secondary);
      flex-shrink: 0;
      transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease;
    }
    .privacy-flow-row.active .privacy-flow-step,
    .privacy-flow-row.done .privacy-flow-step {
      background: rgba(255, 255, 255, 0.08);
      border-color: rgba(255, 255, 255, 0.3);
      color: var(--text-primary);
    }
    .privacy-flow-text {
      flex: 1;
      color: var(--text-secondary);
      font-weight: 500;
    }
    .privacy-flow-row.active .privacy-flow-text,
    .privacy-flow-row.done .privacy-flow-text {
      color: var(--text-primary);
    }
    /* Step state marker: nothing until the step lands, then a check that
       strokes itself on. Draw + scale run on a single decelerating curve. */
    .privacy-flow-status {
      width: 20px; height: 20px;
      flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      color: var(--text-primary);
    }
    .pf-mark {
      width: 18px; height: 18px;
      overflow: visible;
      opacity: 0;
      transform: scale(0.82);
      transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
    }
    /* The draw hook is on the glyph's path, and a path inside a kgIcon glyph
       may not be edited, so it is selected rather than classed. 23 is the
       Lucide check path's length (22.6 units); the hand path it replaced was
       20.4, which is where the old 21 came from. */
    .pf-mark path {
      stroke-dasharray: 23;
      stroke-dashoffset: 23;
    }
    .privacy-flow-row.done .pf-mark { opacity: 1; transform: scale(1); }
    .privacy-flow-row.done .pf-mark path {
      animation: pfDraw 0.44s cubic-bezier(0.22, 1, 0.36, 1) forwards;
    }
    @keyframes pfDraw { from { stroke-dashoffset: 23; } to { stroke-dashoffset: 0; } }
    @media (prefers-reduced-motion: reduce) {
      .pf-mark { transition: none; }
      .privacy-flow-row.done .pf-mark path { animation: none; stroke-dashoffset: 0; }
    }


    /* Prevent overflow-driven horizontal scroll/jerks on small screens */
    body, html { overflow-x: clip; }
    .hero-mock, .ag-mock { max-width: 100%; }

    /* =========================================
       HOVER TILT  layered parallax + gyro
       ========================================= */
    .tilt-host {
      perspective: 1000px;
      transform-style: preserve-3d;
    }
    .tilt-target {
      transition: transform 0.6s cubic-bezier(0.03, 0.98, 0.52, 0.99);
      will-change: transform;
      transform-style: preserve-3d;
    }
    .tilt-host:hover .tilt-target {
      transition: transform 0.25s cubic-bezier(0.03, 0.98, 0.52, 0.99);
    }
    /* Layered children: pop forward in 3D when tilt-host is "active" */
    .tilt-layer {
      transition: transform 0.6s cubic-bezier(0.03, 0.98, 0.52, 0.99);
      will-change: transform;
      transform-style: preserve-3d;
    }
    .tilt-host.tilt-active .tilt-layer {
      transition: transform 0.25s cubic-bezier(0.03, 0.98, 0.52, 0.99);
    }
    #genContent .hero-mock .mock-prompt.tilt-layer {
      transition: transform 0.6s cubic-bezier(0.03, 0.98, 0.52, 0.99),
                  height 0.45s var(--ease-out-quint), box-shadow 0.3s ease;
    }
    #genContent .hero-mock.tilt-active .mock-prompt.tilt-layer {
      transition: transform 0.42s cubic-bezier(0.2, 0.8, 0.3, 1),
                  height 0.45s var(--ease-out-quint), box-shadow 0.3s ease;
    }
    #genContent .hero-mock:hover .tilt-target,
    #genContent .hero-mock.tilt-active .tilt-layer {
      transition-duration: 0.42s;
      transition-timing-function: cubic-bezier(0.2, 0.8, 0.3, 1);
    }
    /* The hero panel keeps its gentle motion even while tilt is active. */
    .tilt-host.hero-mock {
      animation: floatPanelMain 7.5s ease-in-out infinite;
    }
    /* Main panel: pure vertical bob, slower */
    @keyframes floatPanelMain {
      0%, 100% { transform: translate3d(0, 0, 0); }
      50%      { transform: translate3d(0, -8px, 0); }
    }
    /* Respect reduced motion */
    @media (prefers-reduced-motion: reduce) {
      .tilt-target, .tilt-layer { transform: none !important; }
    }
    /* =========================================
       PAYMENT MODAL  iOS-style expand from button
       ========================================= */
    .pay-backdrop {
      position: fixed;
      inset: 0;
      background: rgba(0, 0, 0, 0);
      backdrop-filter: blur(0px);
      -webkit-backdrop-filter: blur(0px);
      z-index: 1000;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.35s var(--ease-out-quint), backdrop-filter 0.35s ease, background 0.35s ease;
    }
    .pay-backdrop.open {
      opacity: 1;
      pointer-events: auto;
      background: rgba(0, 0, 0, 0.6);
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
    }
    /* The modal lives in the DOM at a fixed position but during animation
       we set its top/left/width/height/border-radius INLINE via JS to make
       it look identical to the source button. Then we transition those
       inline styles to the resting values, producing the FLIP expand. */
    .pay-modal {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: calc(100% - 32px);
      max-width: 480px;
      max-height: calc(100vh - 48px);
      background: rgba(22, 22, 22, 0.85);
      backdrop-filter: var(--glass-blur);
      -webkit-backdrop-filter: var(--glass-blur);
      border: 1px solid var(--border-color);
      border-radius: 22px;
      box-shadow: var(--elev-3), var(--edge-top);
      z-index: 1001;
      opacity: 0;
      pointer-events: none;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      transform-origin: center center;
      will-change: top, left, width, height, border-radius, transform, opacity;
    }
    .pay-modal.animating {
      transition:
        top 0.45s var(--ease-out-quint),
        left 0.45s var(--ease-out-quint),
        width 0.45s var(--ease-out-quint),
        height 0.45s var(--ease-out-quint),
        border-radius 0.45s var(--ease-out-quint),
        opacity 0.28s var(--ease-out-quint),
        transform 0.45s var(--ease-out-quint);
    }
    .pay-modal.open {
      opacity: 1;
      pointer-events: auto;
    }
    /* While the modal is in its "from-button" shrunken state, hide the inner
       content so it doesn't visually leak through during the expand. */
    .pay-modal.collapsed .pay-modal-head,
    .pay-modal.collapsed .pay-modal-viewport {
      opacity: 0;
    }
    .pay-modal-head,
    .pay-modal-viewport {
      transition: opacity 0.22s var(--ease-out-quint);
    }

    .pay-modal-head {
      padding: 22px 24px 18px;
      border-bottom: 1px solid var(--border-color);
      display: flex;
      align-items: flex-start;
      gap: 14px;
      flex-shrink: 0;
    }
    .pay-modal-head-text { flex: 1; min-width: 0; }
    .pay-modal-title {
      font-size: 18px;
      font-weight: 800;
      color: var(--text-primary);
      letter-spacing: -0.3px;
      margin-bottom: 8px;
      line-height: 1.2;
    }
    .pay-modal-sub-row {
      display: flex;
      flex-direction: column;
      gap: 3px;
    }
    .pay-modal-sub {
      font-size: 13px;
      color: var(--text-secondary);
      line-height: 1.4;
    }
    .pay-modal-sub b { color: var(--text-primary); }
    .pay-modal-price {
      font-size: 13px;
      color: var(--text-muted);
      font-weight: 600;
      letter-spacing: 0.1px;
    }
    .pay-modal-price b { color: var(--text-primary); font-weight: 700; }
    .pay-modal-close {
      width: 32px;
      height: 32px;
      border-radius: 50%;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      color: var(--text-secondary);
      font-size: 18px;
      line-height: 1;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      transition: background 0.2s ease, color 0.2s ease, transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1));
      font-family: inherit;
    }
    .pay-modal-close:hover {
      background: var(--bg-hover);
      color: var(--text-primary);
      transform: scale(1.08);
    }
    .pay-modal-close:active { transform: scale(0.94); transition: background 0.2s ease, color 0.2s ease, transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
    .pay-modal-viewport {
      position: relative;
      flex: 1;
      overflow: hidden;
    }
    .pay-modal-pane {
      padding: 18px 20px 22px;
      overflow-y: auto;
      max-height: calc(100vh - 200px);
      transition: transform 0.42s var(--ease-out-quint), opacity 0.32s ease;
    }
    .pay-modal-pane.pane-main {
      position: relative;
    }
    .pay-modal-pane.pane-crypto {
      position: absolute;
      inset: 0;
      transform: translateX(100%);
      opacity: 0;
      pointer-events: none;
    }
    .pay-modal.show-crypto .pane-main {
      transform: translateX(-100%);
      opacity: 0;
      pointer-events: none;
    }
    .pay-modal.show-crypto .pane-crypto {
      transform: translateX(0);
      opacity: 1;
      pointer-events: auto;
    }

    /* 2x2 grid of payment options */
    .pay-options-grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 10px;
    }
    .pay-option {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 9px;
      padding: 18px 12px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 14px;
      cursor: pointer;
      text-decoration: none;
      color: inherit;
      transition: background 0.2s ease, border-color 0.2s ease, transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1));
      opacity: 0;
      transform: translateY(8px);
      animation: payOptionIn 0.5s var(--ease-out-quint) forwards;
      text-align: center;
      min-height: 110px;
      font-family: inherit;
    }
    .pay-modal.open .pay-option:nth-child(1) { animation-delay: 0.12s; }
    .pay-modal.open .pay-option:nth-child(2) { animation-delay: 0.18s; }
    .pay-modal.open .pay-option:nth-child(3) { animation-delay: 0.24s; }
    .pay-modal.open .pay-option:nth-child(4) { animation-delay: 0.30s; }
    @keyframes payOptionIn {
      to { opacity: 1; transform: translateY(0); }
    }
    .pay-option:hover {
      background: var(--bg-hover);
      border-color: rgba(255, 255, 255, 0.22);
      transform: translateY(-3px);
    }
    .pay-option:active { transform: scale(0.94); transition: background 0.2s ease, border-color 0.2s ease, transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
    .pay-option-logo {
      width: 44px;
      height: 44px;
      border-radius: 11px;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      overflow: hidden;
    }
    .pay-option-logo img {
      max-width: 60%;
      max-height: 60%;
      object-fit: contain;
      display: block;
    }
    .pay-option-logo.logo-square img {
      max-width: 70%;
      max-height: 70%;
    }
    .pay-option-title {
      font-size: 14px;
      font-weight: 700;
      color: var(--text-primary);
      line-height: 1.2;
    }
    .pay-option-sub {
      font-size: 11px;
      color: var(--text-muted);
      line-height: 1.4;
      padding: 0 2px;
    }

    /* Crypto sub-pane */
    /* One rule across the modal, not two. The head above already draws a
       full-width divider; this pane used to draw a second, shorter one inset
       by the pane's own padding, so the top of the sheet read as two mismatched
       lines. The row keeps its spacing and drops the border. */
    .pay-crypto-head {
      display: flex;
      align-items: center;
      gap: 10px;
      margin-bottom: 16px;
    }
    /* Matched to the modal's own close control: a quiet circle, not a filled
       box with its own border competing with the title beside it. */
    .pay-crypto-back {
      width: 32px;
      height: 32px;
      border-radius: 50%;
      background: transparent;
      border: 0;
      color: var(--text-secondary);
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      transition: background 0.2s ease, color 0.2s ease, transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1));
      font-family: inherit;
    }
    .pay-crypto-back:hover {
      background: var(--bg-hover);
      color: var(--text-primary);
    }
    .pay-crypto-back:active { transform: scale(0.94); transition: background 0.2s ease, color 0.2s ease, transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
    .pay-crypto-back svg { width: 16px; height: 16px; }
    .pay-crypto-title {
      font-size: 14px;
      font-weight: 700;
      color: var(--text-primary);
    }
    .pay-crypto-grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 8px;
    }
    .pay-crypto-coin {
      display: flex;
      align-items: center;
      gap: 11px;
      padding: 11px 13px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 11px;
      cursor: pointer;
      text-decoration: none;
      color: inherit;
      transition: background 0.2s ease, border-color 0.2s ease, transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1));
    }
    .pay-crypto-coin:hover {
      background: var(--bg-hover);
      border-color: rgba(255, 255, 255, 0.18);
      transform: translateY(-2px);
    }
    .pay-crypto-coin:active { transform: scale(0.94); transition: background 0.2s ease, border-color 0.2s ease, transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
    /* These are buttons now rather than links, and a button centres its text by
       UA default, which left every coin name floating away from its logo. */
    .pay-crypto-coin { text-align: left; font: inherit; }
    .pay-crypto-coin[disabled] { opacity: 0.45; pointer-events: none; }
    /* Stands in when a coin has no logo, so an unfamiliar coin reads as a coin
       rather than as a broken image. */
    .pay-crypto-ticker {
      font-size: 10px;
      font-weight: 700;
      color: var(--text-secondary);
    }
    .pay-crypto-note {
      margin-top: 10px;
      font-size: 12px;
      line-height: 1.45;
      color: var(--text-secondary);
      text-align: center;
    }
    .pay-crypto-note:empty { display: none; }
    .pay-crypto-logo {
      width: 28px;
      height: 28px;
      border-radius: 50%;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      overflow: hidden;
    }
    .pay-crypto-logo img {
      width: 18px;
      height: 18px;
      object-fit: contain;
      display: block;
    }
    .pay-crypto-name {
      font-size: 13px;
      font-weight: 600;
      color: var(--text-primary);
      flex: 1;
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    /* Mobile tweaks */
    @media (max-width: 480px) {
      .pay-modal { max-width: calc(100% - 24px); }
      .pay-modal-head { padding: 18px 18px 14px; }
      .pay-modal-pane { padding: 14px 14px 18px; }
      .pay-options-grid { gap: 8px; }
      .pay-option { padding: 14px 8px; min-height: 100px; gap: 7px; }
      .pay-option-logo { width: 38px; height: 38px; border-radius: 10px; }
      .pay-option-title { font-size: 13px; }
      .pay-option-sub { font-size: 10px; }
      .pay-crypto-grid { gap: 7px; }
      .pay-crypto-coin { padding: 10px 11px; gap: 9px; }
      .pay-modal-title { font-size: 16px; }
    }


    /* =========================================
       FILES — STICKY SCROLL SIMULATION
       ========================================= */

    /* Hero */
    .files-hero {
      padding: 160px 0 80px;
      text-align: center;
      position: relative;
    }
    @media (max-width: 768px) { .files-hero { padding: 90px 0 40px; } }
    .files-hero-inner { max-width: 820px; margin: 0 auto; }
    .files-hero-title {
      font-size: clamp(40px, 7vw, 72px);
      font-weight: 800;
      line-height: 1.04;
      letter-spacing: -2px;
      margin-bottom: 24px;
    }
    .files-hero-sub {
      font-size: 18px;
      color: var(--text-secondary);
      line-height: 1.6;
      margin-bottom: 36px;
      max-width: 640px;
      margin-left: auto;
      margin-right: auto;
    }
    .files-hero-ctas {
      display: flex;
      flex-direction: column;
      gap: 14px;
      max-width: 380px;
      margin: 0 auto;
    }
    @media (min-width: 480px) { .files-hero-ctas { flex-direction: row; max-width: none; justify-content: center; } }
    .files-scroll-cue {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 8px;
      margin-top: 60px;
      color: var(--text-muted);
      font-size: 10px;
      letter-spacing: 1.2px;
      text-transform: uppercase;
      font-weight: 700;
    }
    @media (max-width: 768px) { .files-scroll-cue { margin-top: 30px; } }

    /* =========================================
       Sticky Simulation Grid
       ========================================= */
    .files-sim {
      padding: 40px 0 80px;
      position: relative;
    }
    @media (max-width: 768px) { .files-sim { padding: 20px 0 40px; } }
    .fsim-grid {
      display: grid;
      grid-template-columns: 1fr;
      gap: 40px;
      align-items: start;
    }
    @media (min-width: 1024px) {
      .fsim-grid {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
        gap: 80px;
      }
      /* Files needs a broader reading column without widening the full page
         or changing the shared K Agent simulator. */
      #filesContent .fsim-grid {
        grid-template-columns: minmax(0, 1.04fr) minmax(0, 1fr);
        gap: 64px;
      }
    }

    /* LEFT: scrolling steps */
    .fsim-steps {
      display: flex;
      flex-direction: column;
    }
    .fsim-step {
      min-height: 70vh;
      padding: 80px 0;
      display: flex;
      flex-direction: column;
      justify-content: center;
      scroll-snap-align: center;
      scroll-snap-stop: always;
    }
    @media (max-width: 1023px) {
      .fsim-step {
        min-height: 56svh;
        padding: 28px 0 24px;
        justify-content: flex-start;
        scroll-snap-align: start;
        scroll-snap-stop: always;
      }
      .fsim-step:first-child { padding-top: 24px; }
    }
    /* Snap is handled by JS now (one-step-per-swipe lock) — CSS snap is off. */
    @media (max-width: 1023px) {
      html.fsim-snap-active {
        scroll-snap-type: none;
      }
    }
    @media (max-width: 640px) {
      .fsim-step { min-height: 50svh; padding: 20px 0 18px; }
    }
    .fsim-step:first-child { padding-top: 20px; }
    .fsim-step:last-child { padding-bottom: 20px; }
    .fsim-step h2 {
      font-size: clamp(28px, 4.5vw, 44px);
      font-weight: 800;
      letter-spacing: -1px;
      line-height: 1.1;
      margin-bottom: 18px;
    }
    .fsim-step p {
      font-size: 16px;
      color: var(--text-secondary);
      line-height: 1.65;
      margin-bottom: 22px;
    }
    .fsim-step p b { color: var(--text-primary); }
    .fsim-bullets {
      list-style: none;
      padding: 0;
      margin: 0;
    }
    .fsim-bullets li {
      display: flex;
      align-items: flex-start;
      gap: 12px;
      padding: 9px 0;
      font-size: 14px;
      color: var(--text-primary);
    }
    .fsim-bullets li svg {
      width: 18px;
      height: 18px;
      flex-shrink: 0;
      margin-top: 2px;
      opacity: 0.7;
    }
    .fsim-bullets li span { line-height: 1.5; }
    @media (max-width: 768px) {
      .fsim-bullets { display: none; }
      .fsim-step p { display: none; }
      .fsim-step h2 { display: none; }
      .fsim-step {
        min-height: 38svh;
        padding: 14px 0;
      }
      .fsim-step:first-child { padding-top: 14px; }
      .fsim-mobile-heading {
        display: flex;
        align-items: center;
        justify-content: center;
        text-align: center;
        min-height: 52px;
        padding: 10px 8px 4px 8px;
        position: relative;
      }
      .fsim-mobile-heading h2 {
        font-size: clamp(17px, 4.6vw, 22px);
        font-weight: 800;
        letter-spacing: -0.6px;
        line-height: 1.15;
        margin: 0;
        color: var(--text-primary);
        transition: opacity 0.35s var(--ease-out-expo), transform 0.35s var(--ease-out-expo);
        opacity: 1;
      }
      .fsim-mobile-heading h2.fading {
        opacity: 0;
        transform: translateY(8px);
      }
    }
    @media (min-width: 769px) {
      .fsim-mobile-heading { display: none; }
    }
    .fsim-code {
      background: var(--bg-tertiary);
      padding: 2px 7px;
      border-radius: 5px;
      font-size: 0.9em;
      font-family: var(--font-sf);
      color: var(--text-primary);
    }
    .fsim-code-sm {
      background: var(--bg-tertiary);
      padding: 1px 5px;
      border-radius: 3px;
      font-size: 11px;
      font-family: var(--font-sf);
      color: var(--text-primary);
    }
    /* RIGHT (desktop) / BOTTOM (mobile): device frame wrapper */
    .fsim-stage-wrap {
      position: relative;
      align-self: stretch;
    }
    .fsim-stage {
      position: sticky;
      top: calc((100vh - min(78vh, 760px) - 74px) / 2 + 50px);
    }
    /* Mobile: device docks to top of viewport, full-width edge-to-edge */
    @media (max-width: 1023px) {
      .fsim-stage-wrap {
        position: sticky;
        /* Absorbing the URL bar. Sizes stay in svh on purpose: the block's
           height feeds the document height, and changing that mid-scroll is
           exactly what shoves every following element around. The sticky
           OFFSET is free to move though - it changes nothing in flow - so it
           takes half of whatever extra height the collapsed chrome exposed.
           The panel drifts down as the bar retracts and stays optically
           centred instead of sitting above a growing empty band, and it
           glides back when the bar returns. Both units are equal on desktop
           and while the chrome is visible, so this is a no-op there. */
        top: calc(60px + (100dvh - 100svh) / 2);
        z-index: 50;
        align-self: start;
        order: -1;
        padding: 6px 0 8px 0;
        pointer-events: auto;
        margin: 0 calc(50% - 50vw);
        padding-left: calc(50vw - 50% + 6px);
        padding-right: calc(50vw - 50% + 6px);
        background: var(--bg-primary);
        max-height: calc(100svh - 64px);
        overflow: visible;
        /* Safari iOS: promote sticky element to its own compositor layer so
           it scrolls smoothly without jerking. Without these hints, Safari
           re-rasterizes the sticky element each frame as the page moves,
           which combined with the gradient pseudo-elements below causes
           visible jitter on momentum scroll. */
        -webkit-transform: translate3d(0, 0, 0);
        transform: translate3d(0, 0, 0);
        will-change: transform;
        -webkit-backface-visibility: hidden;
        backface-visibility: hidden;
      }
      .fsim-stage-wrap::before {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        bottom: -28px;
        height: 28px;
        background: linear-gradient(180deg, var(--bg-primary), transparent);
        pointer-events: none;
      }
      .fsim-stage-wrap::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        top: -8px;
        height: 8px;
        background: var(--bg-primary);
        pointer-events: none;
      }
      .fsim-stage {
        position: relative;
        top: auto;
        transform: none;
        padding: 0;
        pointer-events: auto;
      }
      .fsim-device {
        box-shadow: 0 12px 36px rgba(0,0,0,0.65), 0 0 0 1px rgba(255,255,255,0.08);
        border-radius: 14px;
        /* Safari: keep the device frame on its own layer too, so the
           inner cross-fading stage layers don't trigger re-rasterization
           of the entire sticky container. */
        -webkit-transform: translateZ(0);
        transform: translateZ(0);
      }
    }
    @media (max-width: 640px) {
      .fsim-stage-wrap {
        top: calc(56px + (100dvh - 100svh) / 2);
        padding-left: calc(50vw - 50% - 12px);
        padding-right: calc(50vw - 50% - 12px);
      }
    }




    /* Device chrome */
    .fsim-device {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 18px;
      overflow: hidden;
      box-shadow: 0 30px 80px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.04);
    }
    .fsim-titlebar {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 12px 16px;
      background: var(--bg-tertiary);
      border-bottom: 1px solid var(--border-color);
    }
    .fsim-dots { display: flex; gap: 6px; }
    .fsim-dots span {
      width: 11px; height: 11px;
      border-radius: 50%;
      background: var(--bg-secondary);
    }
    .fsim-url {
      flex: 1;
      text-align: center;
      font-size: 12px;
      color: var(--text-secondary);
      font-family: var(--font-sf);
      transition: opacity 0.35s ease;
    }

    /* The screen area that holds all stage layers */
    .fsim-screen {
      position: relative;
      height: min(78vh, 760px);
      min-height: 560px;
      overflow: hidden;
    }
    @media (max-width: 1200px) { .fsim-screen { height: min(74vh, 700px); min-height: 520px; } }
    /* Stacked layout (device docks under a sticky caption): every stage layer
       is absolutely positioned, so the screen has no natural height and a
       fixed min-height was the only thing sizing it. That left a dead band
       under the caption on tall phones and pushed the caption off-screen on
       short ones. Derive the height from the viewport instead.
       Subtracted: sticky offset + wrap padding + titlebar + the stage rail
       and its labels, plus the caption itself below 769px where it shows. */
    @media (max-width: 1023px) {
      .fsim-screen {
        height: calc(100svh - 198px);
        min-height: 300px;
        max-height: 900px;
      }
    }
    @media (max-width: 768px) {
      /* Phone: the rail is hidden (see below) and the caption is the only
         thing under the device, so the screen takes back that room. */
      .fsim-screen {
        height: calc(100svh - 172px);
        max-height: 880px;
      }
    }





    /* Each stage layer absolutely stacked, cross-fades */
    .fsim-layer {
      position: absolute;
      inset: 0;
      padding: 22px;
      opacity: 0;
      transform: translateY(12px) scale(0.985);
      transition: opacity 0.5s var(--ease-out-expo), transform 0.5s var(--ease-out-expo);
      pointer-events: none;
    }
    .fsim-stage[data-active-stage="1"] .fsim-layer[data-stage="1"],
    .fsim-stage[data-active-stage="2"] .fsim-layer[data-stage="2"],
    .fsim-stage[data-active-stage="3"] .fsim-layer[data-stage="3"],
    .fsim-stage[data-active-stage="4"] .fsim-layer[data-stage="4"],
    .fsim-stage[data-active-stage="5"] .fsim-layer[data-stage="5"],
    .fsim-stage[data-active-stage="6"] .fsim-layer[data-stage="6"],
    .fsim-stage[data-active-stage="7"] .fsim-layer[data-stage="7"],
    .fsim-stage[data-active-stage="8"] .fsim-layer[data-stage="8"] {
      opacity: 1;
      transform: translateY(0) scale(1);
      pointer-events: auto;
    }

    /* Hidden stage panes keep display:block for the crossfade, so their
       animations would otherwise tick invisibly through the whole section.
       Pause everything in inactive panes; the active pane resumes below. */
    #fsim .fsim-layer *,
    #fsim .fsim-layer *::before,
    #fsim .fsim-layer *::after {
      animation-play-state: paused;
    }
    #fsim .fsim-stage[data-active-stage="1"] .fsim-layer[data-stage="1"] *,
    #fsim .fsim-stage[data-active-stage="1"] .fsim-layer[data-stage="1"] *::before,
    #fsim .fsim-stage[data-active-stage="1"] .fsim-layer[data-stage="1"] *::after,
    #fsim .fsim-stage[data-active-stage="2"] .fsim-layer[data-stage="2"] *,
    #fsim .fsim-stage[data-active-stage="2"] .fsim-layer[data-stage="2"] *::before,
    #fsim .fsim-stage[data-active-stage="2"] .fsim-layer[data-stage="2"] *::after,
    #fsim .fsim-stage[data-active-stage="3"] .fsim-layer[data-stage="3"] *,
    #fsim .fsim-stage[data-active-stage="3"] .fsim-layer[data-stage="3"] *::before,
    #fsim .fsim-stage[data-active-stage="3"] .fsim-layer[data-stage="3"] *::after,
    #fsim .fsim-stage[data-active-stage="4"] .fsim-layer[data-stage="4"] *,
    #fsim .fsim-stage[data-active-stage="4"] .fsim-layer[data-stage="4"] *::before,
    #fsim .fsim-stage[data-active-stage="4"] .fsim-layer[data-stage="4"] *::after,
    #fsim .fsim-stage[data-active-stage="5"] .fsim-layer[data-stage="5"] *,
    #fsim .fsim-stage[data-active-stage="5"] .fsim-layer[data-stage="5"] *::before,
    #fsim .fsim-stage[data-active-stage="5"] .fsim-layer[data-stage="5"] *::after,
    #fsim .fsim-stage[data-active-stage="6"] .fsim-layer[data-stage="6"] *,
    #fsim .fsim-stage[data-active-stage="6"] .fsim-layer[data-stage="6"] *::before,
    #fsim .fsim-stage[data-active-stage="6"] .fsim-layer[data-stage="6"] *::after,
    #fsim .fsim-stage[data-active-stage="7"] .fsim-layer[data-stage="7"] *,
    #fsim .fsim-stage[data-active-stage="7"] .fsim-layer[data-stage="7"] *::before,
    #fsim .fsim-stage[data-active-stage="7"] .fsim-layer[data-stage="7"] *::after,
    #fsim .fsim-stage[data-active-stage="8"] .fsim-layer[data-stage="8"] *,
    #fsim .fsim-stage[data-active-stage="8"] .fsim-layer[data-stage="8"] *::before,
    #fsim .fsim-stage[data-active-stage="8"] .fsim-layer[data-stage="8"] *::after {
      animation-play-state: running;
    }

    /* Rail on right side of device (vertical) */
    .fsim-device {
      position: relative;
    }
    .fsim-rail {
      position: absolute;
      top: 56px;
      bottom: 18px;
      right: -64px;
      width: 44px;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 12px;
      pointer-events: none;
    }
    .fsim-rail-track {
      position: relative;
      width: 3px;
      flex: 1;
      background: var(--bg-tertiary);
      border-radius: 2px;
      overflow: hidden;
    }
    .fsim-rail-fill {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 14%;
      background: linear-gradient(180deg,
        rgba(255,255,255,0.35) 0%,
        rgba(255,255,255,1) 25%,
        rgba(255,255,255,0.35) 50%,
        rgba(255,255,255,1) 75%,
        rgba(255,255,255,0.35) 100%);
      background-size: 100% 200%;
      transition: height 0.5s var(--ease-out-expo);
      border-radius: 2px;
    }
    @keyframes fsimSeamShimmer {
      from { background-position: 0 0%; }
      to   { background-position: 0 200%; }
    }
    .fsim-rail-labels {
      position: absolute;
      top: 56px;
      bottom: 18px;
      right: -160px;
      width: 90px;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      font-size: 10px;
      font-weight: 700;
      letter-spacing: 0.3px;
      text-transform: uppercase;
      pointer-events: none;
    }
    .fsim-rail-labels span {
      color: var(--text-muted);
      transition: color 0.35s ease, transform 0.35s ease;
      text-align: left;
      position: relative;
      padding-left: 0;
    }
    .fsim-stage[data-active-stage="1"] .fsim-rail-labels span[data-stage="1"],
    .fsim-stage[data-active-stage="2"] .fsim-rail-labels span[data-stage="2"],
    .fsim-stage[data-active-stage="3"] .fsim-rail-labels span[data-stage="3"],
    .fsim-stage[data-active-stage="4"] .fsim-rail-labels span[data-stage="4"],
    .fsim-stage[data-active-stage="5"] .fsim-rail-labels span[data-stage="5"],
    .fsim-stage[data-active-stage="6"] .fsim-rail-labels span[data-stage="6"],
    .fsim-stage[data-active-stage="7"] .fsim-rail-labels span[data-stage="7"],
    .fsim-stage[data-active-stage="8"] .fsim-rail-labels span[data-stage="8"] {
      color: var(--text-primary);
      transform: translateX(2px);
    }
    /* On smaller screens, fall back to horizontal rail below device */
    @media (max-width: 1200px) {
      .fsim-rail {
        position: static;
        width: auto;
        flex-direction: column;
        align-items: stretch;
        margin-top: 18px;
        padding: 0 6px;
        gap: 0;
      }
      .fsim-rail-track {
        width: 100%;
        flex: 0 0 auto;
        height: 3px;
        margin-bottom: 0;
      }
      .fsim-rail-fill {
        position: relative;
        height: 100%;
        width: 14%;
        background: linear-gradient(90deg,
          rgba(255,255,255,0.35) 0%,
          rgba(255,255,255,1) 25%,
          rgba(255,255,255,0.35) 50%,
          rgba(255,255,255,1) 75%,
          rgba(255,255,255,0.35) 100%);
        background-size: 200% 100%;
        transition: width 0.5s var(--ease-out-expo);
      }
      .fsim-rail-labels {
        position: static;
        width: 100%;
        flex-direction: row;
        justify-content: space-between;
        font-size: 10px;
        margin-top: 12px;
        gap: 2px;
        letter-spacing: 0.2px;
      }
      .fsim-rail-labels span {
        padding-left: 0;
        text-align: center;
        flex: 1 1 0;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-weight: 700;
      }
      .fsim-rail-labels span:first-child { text-align: left; }
      .fsim-rail-labels span:last-child { text-align: right; }
    }
    /* Phone: the stage rail is dropped entirely - the device is worth more
       than the progress read-out at this size, and the step counter in the
       title bar already says where you are. */
    @media (max-width: 768px) {
      .fsim-rail { display: none; }
    }
    @media (max-width: 640px) {
      .fsim-rail-labels {
        font-size: 10px;
        margin-top: 10px;
        letter-spacing: 0;
      }
      /* Phone-length overrides for the Files sim's own wording only - #ksim
         shares this rail component but ships its own short labels. */
      #fsim .fsim-rail-labels span[data-stage="1"] {
        font-size: 0;
      }
      #fsim .fsim-rail-labels span[data-stage="1"]::after {
        content: 'Create';
        font-size: 10px;
        font-weight: 700;
        letter-spacing: 0;
        text-transform: uppercase;
      }
      #fsim .fsim-rail-labels span[data-stage="3"] {
        font-size: 0;
      }
      #fsim .fsim-rail-labels span[data-stage="3"]::after {
        content: 'Share';
        font-size: 10px;
        font-weight: 700;
        letter-spacing: 0;
        text-transform: uppercase;
      }
    }








    /* =========================================
       STAGE 1 — Image Gen Panel
       ========================================= */
    .fsim-gen-panel {
      height: 100%;
      display: flex;
      flex-direction: column;
      gap: 12px;
    }
    .fsim-gen-label {
      font-size: 10px;
      font-weight: 800;
      letter-spacing: 0.7px;
      color: var(--text-muted);
    }
    .fsim-gen-prompt {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      padding: 12px 14px;
      font-family: var(--font-sf);
      font-size: 12px;
      color: var(--text-primary);
      line-height: 1.6;
      word-break: break-word;
    }
    .fsim-gen-controls {
      display: flex;
      gap: 6px;
      flex-wrap: wrap;
    }
    .fsim-gen-chip {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 8px;
      padding: 7px 11px;
      font-size: 11px;
      color: var(--text-primary);
      font-weight: 600;
      display: flex;
      align-items: center;
      gap: 6px;
    }
    .fsim-chip-k {
      font-size: 10px;
      color: var(--text-muted);
      letter-spacing: 0.5px;
      text-transform: uppercase;
      font-weight: 800;
    }
    /* Drawn product chrome, and the product's own buttons are the chip
       material now (The No Pure White Rule, DESIGN.md:190). The hairline is an
       inset ring because border: none is load bearing on these measured
       boxes. */
    .fsim-gen-btn {
      background: var(--bg-hover);
      color: var(--text-primary);
      border: none;
      box-shadow: inset 0 0 0 1px var(--hairline-hover);
      border-radius: 9px;
      padding: 10px 16px;
      font-size: 13px;
      font-weight: 700;
      cursor: default;
      display: inline-flex;
      align-items: center;
      gap: 7px;
      align-self: flex-start;
    }
    .fsim-gen-output {
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 8px;
      min-height: 0;
    }
    .fsim-gen-output-label {
      font-size: 10px;
      font-weight: 800;
      letter-spacing: 0.7px;
      color: var(--text-muted);
    }
    .fsim-gen-grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 8px;
      flex: 1;
      min-height: 0;
    }
    .fsim-gen-tile {
      border-radius: 10px;
      overflow: hidden;
      background: var(--bg-tertiary);
      position: relative;
      border: 2px solid transparent;
      transition: border-color 0.3s ease, opacity 0.3s ease;
    }
    .fsim-gen-tile img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
    }
    .fsim-tile-picked {
      border-color: rgba(255, 255, 255, 0.5);
      box-shadow: 0 0 0 4px rgba(255,255,255,0.05), 0 8px 24px rgba(255,255,255,0.1);
      transform: scale(1.02);
    }
    .fsim-tile-pick-badge {
      position: absolute;
      top: 8px;
      right: 8px;
      width: 22px;
      height: 22px;
      border-radius: 50%;
      background: #fff;
      color: #000;
      display: flex;
      align-items: center;
      justify-content: center;
      animation: pickBadgeIn 0.5s var(--ease-out-expo);
    }
    @keyframes pickBadgeIn {
      from { transform: scale(0); }
      to { transform: scale(1); }
    }

    /* =========================================
       STAGE 2  Upload + Optimize (two-card before/after)
       ========================================= */
    .fsim-uo-panel {
      height: 100%;
      display: flex;
      flex-direction: column;
      gap: 14px;
      padding: 4px 2px;
    }

    /* Status header */
    .fsim-uo-header {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 14px;
      padding: 12px 16px;
      display: flex;
      align-items: center;
      gap: 12px;
      animation: fsimUoFadeIn 0.45s cubic-bezier(0.16, 1, 0.3, 1);
    }
    .fsim-uo-header-icon {
      width: 34px; height: 34px;
      border-radius: 10px;
      background: rgba(74,222,128,0.1);
      border: 1px solid rgba(74,222,128,0.3);
      color: #30d158;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
    }
    .fsim-uo-header-title {
      font-size: 13px;
      font-weight: 700;
      color: var(--text-primary);
      margin-bottom: 2px;
    }
    .fsim-uo-header-sub {
      font-size: 11px;
      color: var(--text-muted);
      font-family: var(--font-sf);
    }
    .fsim-uo-header-status {
      margin-left: auto;
      display: flex;
      align-items: center;
      gap: 6px;
      font-size: 10px;
      font-weight: 700;
      color: #30d158;
      letter-spacing: 0.4px;
      text-transform: uppercase;
    }
    .fsim-uo-header-status .dot {
      width: 6px; height: 6px;
      border-radius: 50%;
      background: #30d158;
      box-shadow: 0 0 8px rgba(74,222,128,0.6);
    }

    /* The flex container that holds the two cards + arrow  fills available space */
    .fsim-uo-flow {
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 14px;
      min-height: 0;
    }

    /* --- Before/after comparison wipe --- */
    .fsim-uo-compare {
      position: relative;
      flex: 1;
      min-height: 0;
      border-radius: 14px;
      overflow: hidden;
      border: 1px solid var(--border-color);
      background: var(--bg-tertiary);
    }
    .fsim-uo-img {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
      object-position: center 25%;
    }
    .fsim-uo-clip {
      position: absolute;
      inset: 0;
      /* JS animates clip-path inset(0 X% 0 0); PNG side lives on top */
      transition: clip-path 1.4s var(--ease-out-quint);
      will-change: clip-path;
    }
    .fsim-uo-divider {
      position: absolute;
      top: 0; bottom: 0;
      left: 100%;
      width: 2px;
      margin-left: -1px;
      background: rgba(255,255,255,0.85);
      box-shadow: 0 0 0 0.5px rgba(0,0,0,0.35);
      transition: left 1.4s var(--ease-out-quint);
    }
    .fsim-uo-grip {
      position: absolute;
      top: 50%; left: 50%;
      transform: translate(-50%, -50%);
      width: 26px; height: 26px;
      border-radius: 50%;
      background: rgba(18,18,18,0.75);
      backdrop-filter: blur(8px);
      -webkit-backdrop-filter: blur(8px);
      border: 1px solid rgba(255,255,255,0.4);
    }
    .fsim-uo-grip::before, .fsim-uo-grip::after {
      content: '';
      position: absolute;
      top: 50%;
      width: 5px; height: 5px;
      border-left: 1.5px solid rgba(255,255,255,0.85);
      border-bottom: 1.5px solid rgba(255,255,255,0.85);
    }
    .fsim-uo-grip::before { left: 6px; transform: translateY(-50%) rotate(45deg); }
    .fsim-uo-grip::after { right: 6px; transform: translateY(-50%) rotate(225deg); }
    .fsim-uo-side-tag {
      position: absolute;
      bottom: 10px;
      font-family: var(--font-sf);
      font-size: 10px;
      letter-spacing: 0.3px;
      color: rgba(255,255,255,0.85);
      background: rgba(10,10,10,0.72);
      backdrop-filter: blur(8px);
      -webkit-backdrop-filter: blur(8px);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 8px;
      padding: 4px 8px;
      opacity: 0;
      transition: opacity 0.5s ease;
      pointer-events: none;
    }
    .fsim-uo-side-tag b { font-weight: 700; color: #fff; margin-right: 6px; }
    .fsim-uo-side-tag.left { left: 10px; }
    .fsim-uo-side-tag.right { right: 10px; }
    .fsim-uo-compare.tags-on .fsim-uo-side-tag { opacity: 1; }

    /* --- Size bars: the honest way to show -89% --- */
    .fsim-uo-bars {
      display: flex;
      flex-direction: column;
      gap: 8px;
      flex-shrink: 0;
    }
    .fsim-uo-bar-row {
      display: flex;
      align-items: center;
      gap: 10px;
      font-family: var(--font-sf);
      font-size: 11px;
    }
    .fsim-uo-bar-label {
      width: 38px;
      text-align: right;
      color: var(--text-muted);
      font-weight: 700;
      letter-spacing: 0.4px;
    }
    .fsim-uo-bar-track {
      flex: 1;
      height: 6px;
      border-radius: 3px;
      background: var(--bg-secondary);
    }
    .fsim-uo-bar-fill {
      height: 100%;
      border-radius: 3px;
      width: 0%;
      background: rgba(255,255,255,0.35);
      transition: width 1.2s var(--ease-out-quint);
    }
    .fsim-uo-bar-fill.green { background: #30d158; }
    .fsim-uo-bar-val {
      width: 74px;
      color: var(--text-secondary);
      font-variant-numeric: tabular-nums;
    }
    .fsim-uo-verdict {
      align-self: center;
      font-size: 12px;
      color: var(--text-secondary);
      opacity: 0;
      transform: translateY(4px);
      transition: opacity 0.5s ease, transform 0.5s var(--ease-out-expo);
    }
    .fsim-uo-verdict.visible { opacity: 1; transform: none; }
    .fsim-uo-verdict .pct {
      color: #30d158;
      font-weight: 800;
      font-family: var(--font-sf);
    }

    @media (max-width: 640px) {
      .fsim-uo-bar-val { width: 60px; }
      .fsim-uo-side-tag { font-size: 10px; padding: 3px 6px; }
      .fsim-uo-header { padding: 10px 12px; }
      .fsim-uo-header-icon { width: 30px; height: 30px; }
    }


    /* =========================================
       STAGE 3  Global CDN (world map redesign)
       ========================================= */
    .fsim-cdn-panel {
      height: 100%;
      display: flex;
      flex-direction: column;
      gap: 12px;
      padding: 4px 2px;
    }
    .fsim-cdn-header {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 14px;
      padding: 12px 14px;
      display: flex;
      align-items: center;
      gap: 12px;
    }
    .fsim-cdn-header-icon {
      width: 34px; height: 34px;
      border-radius: 10px;
      background: rgba(246,130,31,0.1);
      border: 1px solid rgba(246,130,31,0.25);
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
    }
    .fsim-cdn-header-title {
      font-size: 13px;
      font-weight: 700;
      color: var(--text-primary);
      margin-bottom: 2px;
    }
    .fsim-cdn-header-sub {
      font-size: 11px;
      color: var(--text-muted);
      font-family: var(--font-sf);
    }
    .fsim-cdn-header-status {
      margin-left: auto;
      display: flex;
      align-items: center;
      gap: 6px;
      font-size: 10px;
      font-weight: 700;
      color: #30d158;
      letter-spacing: 0.4px;
      text-transform: uppercase;
    }
    .fsim-cdn-header-status .dot {
      width: 6px; height: 6px;
      border-radius: 50%;
      background: #30d158;
      box-shadow: 0 0 8px rgba(74,222,128,0.6);
    }

    /* World map */
    .fsim-cdn-map {
      /* Fills the panel so the stage never leaves a dead band on a tall
         phone screen. The 600x320 drawing letterboxes inside it; labels are
         placed against the drawn map (fsimCdnMapBox), not this card, so they
         stay on their nodes at any shape. */
      flex: 1;
      min-height: 0;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 14px;
      padding: 14px 14px 12px;
      position: relative;
      overflow: hidden;
    }
    .fsim-cdn-map-svg {
      width: 100%;
      height: 100%;
      display: block;
    }
    /* Quiet, editorial map: faint white land dots, one origin node, arcs
       propagating outward, arrival pings, white traffic packets. No glow
       blobs, no drop-shadows, no dashed neon. */
    .fsim-cdn-dc {
      fill: #30d158;
      transform-box: fill-box;
      transform-origin: center;
    }
    .fsim-cdn-dc.arrive { animation: fsimCdnNodeIn 0.5s var(--ease-settle) both; }
    .fsim-cdn-dc.origin { fill: #ffffff; }
    @keyframes fsimCdnNodeIn {
      from { transform: scale(0); }
      to { transform: scale(1); }
    }
    .fsim-cdn-ping {
      fill: none;
      stroke: rgba(74,222,128,0.5);
      stroke-width: 1;
      transform-box: fill-box;
      transform-origin: center;
      animation: fsimCdnPing 0.9s ease-out forwards;
      pointer-events: none;
    }
    @keyframes fsimCdnPing {
      from { transform: scale(1); opacity: 0.8; }
      to { transform: scale(4.2); opacity: 0; }
    }
    .fsim-cdn-arc {
      fill: none;
      stroke: rgba(255,255,255,0.22);
      stroke-width: 1;
      transition: stroke 1.4s ease;
    }
    .fsim-cdn-arc.settled { stroke: rgba(255,255,255,0.1); }
    .fsim-cdn-pulse { fill: rgba(255,255,255,0.9); }

    /* Floating badges */
    .fsim-cdn-badges {
      position: absolute;
      inset: 14px;
      pointer-events: none;
    }
    .fsim-cdn-badge {
      position: absolute;
      transform: translate(-50%, -150%);
      font-size: 10px;
      font-weight: 700;
      color: #fff;
      background: rgba(10,10,10,0.85);
      backdrop-filter: blur(8px);
      -webkit-backdrop-filter: blur(8px);
      border: 1px solid rgba(255,255,255,0.12);
      border-radius: 10px;
      padding: 3px 7px;
      white-space: nowrap;
      opacity: 0;
      transition: opacity 0.4s ease, transform 0.4s ease;
      font-family: var(--font-sf);
      font-variant-numeric: tabular-nums;
      letter-spacing: 0.2px;
    }
    .fsim-cdn-badge.visible {
      opacity: 1;
      transform: translate(-50%, -170%);
    }
    .fsim-cdn-badge.below { transform: translate(-50%, 50%); }
    .fsim-cdn-badge.below.visible { transform: translate(-50%, 70%); }
    .fsim-cdn-badge .ms { color: #30d158; margin-left: 4px; }


    /* Bottom stats */
    .fsim-cdn-stats {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 8px;
    }
    .fsim-cdn-stat {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 12px;
      padding: 10px 8px 9px;
      text-align: center;
    }
    .fsim-cdn-stat-v {
      font-size: 17px;
      font-weight: 800;
      color: var(--text-primary);
      font-variant-numeric: tabular-nums;
      letter-spacing: -0.3px;
      line-height: 1;
      margin-bottom: 4px;
      font-family: var(--font-sf);
    }
    .fsim-cdn-stat-k {
      font-size: 10px;
      font-weight: 700;
      letter-spacing: 0.5px;
      color: var(--text-muted);
      text-transform: uppercase;
    }
    @media (max-width: 640px) {
      .fsim-cdn-stat-v { font-size: 14px; }
      .fsim-cdn-stat { padding: 8px 4px; }
      .fsim-cdn-nearest-tag { font-size: 10px; padding: 4px 8px; top: 10px; left: 12px; }
      .fsim-cdn-badge {
        font-size: 10px;
        padding: 2px 5px;
        border-radius: 8px;
        letter-spacing: 0;
        font-weight: 600;
      }
      .fsim-cdn-badge .ms { margin-left: 3px; }
    }





    /* =========================================
       STAGE 3 — Dashboard Panel
       ========================================= */
    .fsim-dash-panel {
      height: 100%;
      display: flex;
      flex-direction: column;
      gap: 12px;
    }
    .fsim-dash-toolbar {
      display: flex;
      gap: 10px;
      align-items: center;
    }
    .fsim-dash-search {
      flex: 1;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 9px;
      padding: 9px 12px;
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 12px;
      color: var(--text-muted);
    }
    .fsim-dash-add {
      background: var(--bg-hover);
      color: var(--text-primary);
      border: none;
      box-shadow: inset 0 0 0 1px var(--hairline-hover);
      border-radius: 9px;
      padding: 9px 14px;
      font-size: 12px;
      font-weight: 700;
      cursor: default;
    }
    .fsim-dash-grid {
      flex: 1;
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      grid-auto-rows: 1fr;
      gap: 12px;
      min-height: 0;
      overflow-y: auto;
      padding-right: 2px;
    }
    .fsim-dash-grid::-webkit-scrollbar { width: 4px; }
    .fsim-dash-grid::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 2px; }
    .fsim-dash-card {
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 12px;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      position: relative;
      transition: background-color 0.3s ease, border-color 0.3s ease;
    }
    .fsim-dash-highlight {
      border-color: rgba(255,255,255,0.3);
      box-shadow: 0 0 0 1px rgba(255,255,255,0.06), 0 8px 24px rgba(255,255,255,0.05);
    }
    .fsim-dash-new {
      position: absolute;
      top: 8px;
      right: 8px;
      background: var(--bg-hover);
      color: var(--text-primary);
      box-shadow: inset 0 0 0 1px var(--hairline-hover);
      font-size: 10px;
      font-weight: 800;
      padding: 3px 7px;
      border-radius: 5px;
      letter-spacing: 0.5px;
      animation: pickBadgeIn 0.5s var(--ease-out-expo);
    }
    .fsim-dash-thumb {
      flex: 1;
      min-height: 0;
      overflow: hidden;
      background: var(--bg-secondary);
    }
    .fsim-dash-thumb img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      object-position: center top;
    }
    .fsim-dash-info {
      padding: 10px 12px 12px;
      flex-shrink: 0;
    }
    .fsim-dash-title {
      font-size: 12px;
      font-weight: 700;
      color: var(--text-primary);
      margin-bottom: 3px;
    }
    .fsim-dash-meta {
      font-size: 10px;
      color: var(--text-muted);
      display: flex;
      align-items: center;
      gap: 5px;
    }
    .fsim-dot-pub, .fsim-dot-priv {
      width: 6px;
      height: 6px;
      border-radius: 50%;
      display: inline-block;
    }
    .fsim-dot-pub { background: #30d158; }
    .fsim-dot-priv { background: #ff4444; }

    /* =========================================
       STAGE 4 — Copy Panel
       ========================================= */
    .fsim-copy-panel {
      height: 100%;
      display: flex;
      flex-direction: column;
      gap: 14px;
    }
    .fsim-copy-breadcrumb {
      font-size: 11px;
      color: var(--text-muted);
      font-weight: 600;
      letter-spacing: 0.3px;
    }
    .fsim-copy-image-card {
      flex: 1;
      position: relative;
      border-radius: 12px;
      overflow: hidden;
      min-height: 0;
    }
    .fsim-copy-image-card img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
    }
    .fsim-copy-overlay {
      position: absolute;
      bottom: 0; left: 0; right: 0;
      padding: 14px;
      background: linear-gradient(transparent, rgba(0,0,0,0.85));
      display: flex;
      justify-content: space-between;
      align-items: flex-end;
    }
    .fsim-copy-meta {
      font-size: 11px;
      color: rgba(255,255,255,0.65);
      font-family: var(--font-sf);
      text-transform: uppercase;
      letter-spacing: 0.5px;
    }
    .fsim-copy-actions {
      display: flex;
      gap: 6px;
    }
    .fsim-copy-act {
      background: rgba(255,255,255,0.12);
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
      border: 1px solid rgba(255,255,255,0.18);
      border-radius: 8px;
      color: #fff;
      padding: 7px 11px;
      font-size: 11px;
      font-weight: 700;
      cursor: default;
      font-family: var(--font-sf);
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .fsim-copy-pulse {
      background: rgba(255,255,255,0.25);
      border-color: rgba(255,255,255,0.4);
      animation: copyPulse 1.6s ease-in-out infinite;
    }
    @keyframes copyPulse {
      0%, 100% { transform: scale(1); }
      50% { transform: scale(1.08); }
    }
    .fsim-copy-toast {
      background: var(--bg-tertiary);
      border: 1px solid rgba(255,255,255,0.18);
      border-radius: 12px;
      padding: 12px 14px;
      /* No entrance animation here on purpose: the stage unpauses every
         descendant animation when it activates, so a keyframe entrance would
         play the toast in and then drop it back to its inline opacity:0 -
         the split-second flash on scroll-in. fsimReplayCopy() owns the
         reveal via the inline opacity/transform transition. */
    }
    .fsim-copy-toast-head {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 12px;
      font-weight: 700;
      color: var(--text-primary);
      margin-bottom: 7px;
    }
    .fsim-copy-toast-head svg {
      color: #30d158;
    }
    .fsim-copy-code {
      display: block;
      background: var(--bg-secondary);
      padding: 7px 10px;
      border-radius: 6px;
      font-family: var(--font-sf);
      font-size: 11px;
      color: var(--text-secondary);
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    /* Stage 7 copy panel needs relative positioning for cursor overlay */
    .fsim-copy-panel {
      position: relative;
    }

    /* =========================================
       STAGE 7  Paste / Editor Panel
       ========================================= */

    .fsim-paste-panel {
      height: 100%;
      display: flex;
      flex-direction: column;
      gap: 12px;
    }
    .fsim-paste-tabs {
      display: flex;
      align-items: center;
      gap: 4px;
      border-bottom: 1px solid var(--border-color);
    }
    .fsim-paste-tab {
      padding: 9px 14px;
      font-size: 12px;
      font-weight: 600;
      color: var(--text-muted);
      border-bottom: 2px solid transparent;
      margin-bottom: -1px;
    }
    .fsim-paste-tab-active {
      color: var(--text-primary);
      border-bottom-color: #fff;
    }
    .fsim-paste-greeting-nav {
      margin-left: auto;
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 0 4px 6px 0;
    }
    .fsim-greet-dot {
      width: 7px;
      height: 7px;
      border-radius: 50%;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      padding: 0;
      cursor: default;
      transition: background 0.25s ease, border-color 0.25s ease, transform 0.25s ease;
    }
    .fsim-greet-dot-active {
      background: #fff;
      border-color: #fff;
      transform: scale(1.2);
      box-shadow: 0 0 8px rgba(255,255,255,0.5);
    }
    .fsim-greet-counter {
      font-size: 10px;
      font-weight: 700;
      color: var(--text-muted);
      letter-spacing: 0.4px;
      font-variant-numeric: tabular-nums;
      margin-left: 4px;
    }
    .fsim-greet-counter span { color: var(--text-primary); }
    .fsim-paste-editor {
      flex: 1;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      padding: 16px;
      font-family: var(--font-sf);
      font-size: 12px;
      line-height: 1.75;
      color: var(--text-primary);
      white-space: pre-wrap;
      word-break: break-word;
      overflow-y: auto;
      min-height: 0;
      transition: opacity 0.35s ease;
    }
    .fsim-paste-editor.fsim-greet-fading {
      opacity: 0.15;
    }
    .fsim-ed-caret { display: none; }
    .fsim-paste-editor img {
      max-width: 220px;
      width: 100%;
      border-radius: 10px;
      margin: 8px 0;
      display: block;
      box-shadow: 0 6px 20px rgba(0,0,0,0.4);
      animation: fsimPasteImgIn 0.6s cubic-bezier(0.16, 1, 0.3, 1);
    }
    @keyframes fsimPasteImgIn {
      from { opacity: 0; transform: translateY(8px) scale(0.96); filter: blur(4px); }
      to   { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
    }
    .fsim-paste-md-token {
      color: #30d158;
      font-weight: 600;
    }
    .fsim-paste-italic {
      color: var(--text-muted);
      font-style: italic;
    }
    .fsim-paste-foot {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
    .fsim-paste-saved {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 11px;
      color: var(--text-secondary);
    }
    .fsim-paste-btn {
      background: var(--bg-hover);
      color: var(--text-primary);
      border: none;
      box-shadow: inset 0 0 0 1px var(--hairline-hover);
      border-radius: 9px;
      padding: 9px 14px;
      font-size: 12px;
      font-weight: 700;
      cursor: default;
    }


    /* =========================================
       STAGE 4 — Metadata Panel (slides over image)
       ========================================= */
    /* Absolute, not margin-compensated: the old margin: -22px cancelled the
       layer's desktop padding exactly, but the padding drops to 16px and 12px
       on smaller screens while the margin stayed 22 — with height: 100% that
       left a dead strip below the stage equal to twice the difference. */
    .fsim-meta-stage {
      position: absolute;
      inset: 0;
      overflow: hidden;
      border-radius: 0;
    }
    .fsim-meta-bg {
      position: absolute;
      inset: 0;
      overflow: hidden;
    }
    .fsim-meta-bg img {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
      filter: blur(0px);
    }
    .fsim-meta-bg-shade {
      position: absolute;
      inset: 0;
      background: linear-gradient(90deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.4) 30%, rgba(0,0,0,0.85) 100%);
      backdrop-filter: blur(2px);
      -webkit-backdrop-filter: blur(2px);
    }
    .fsim-meta-panel {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      width: 78%;
      max-width: 460px;
      background: rgba(15,15,15,0.94);
      backdrop-filter: blur(20px) saturate(140%);
      -webkit-backdrop-filter: blur(20px) saturate(140%);
      border-left: 1px solid rgba(255,255,255,0.08);
      box-shadow: -20px 0 60px rgba(0,0,0,0.6);
      display: flex;
      flex-direction: column;
      overflow: hidden;
      transform: translateX(100%);
      transition: transform 0.6s var(--ease-out-quint);
    }
    @media (max-width: 640px) {
      .fsim-meta-panel { width: 88%; }
    }
    .fsim-stage[data-active-stage="5"] .fsim-meta-panel {
      transform: translateX(0);
    }
    .fsim-meta-head {
      padding: 16px 20px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      border-bottom: 1px solid rgba(255,255,255,0.06);
      flex-shrink: 0;
    }
    .fsim-meta-head h3 {
      font-size: 14px;
      font-weight: 700;
      color: var(--text-primary);
      margin: 0;
    }
    .fsim-meta-close {
      background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.1);
      width: 26px;
      height: 26px;
      border-radius: 50%;
      color: var(--text-secondary);
      font-size: 16px;
      line-height: 1;
      cursor: default;
      display: flex;
      align-items: center;
      justify-content: center;
      font-family: inherit;
    }
    .fsim-meta-body {
      padding: 14px 18px 18px;
      overflow-y: hidden;
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 14px;
      overscroll-behavior: contain;
      touch-action: none;
      pointer-events: none;
    }
    .fsim-meta-body::-webkit-scrollbar { width: 4px; }
    .fsim-meta-body::-webkit-scrollbar-track { background: transparent; }
    .fsim-meta-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 2px; }
    .fsim-meta-section { display: flex; flex-direction: column; gap: 6px; }
    .fsim-meta-label {
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-size: 10px;
      font-weight: 800;
      letter-spacing: 0.7px;
      color: var(--text-muted);
      text-transform: uppercase;
    }
    .fsim-meta-copy {
      background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 6px;
      padding: 3px 8px;
      font-size: 10px;
      font-weight: 700;
      color: var(--text-secondary);
      letter-spacing: 0.4px;
      cursor: default;
      text-transform: uppercase;
    }
    .fsim-meta-value {
      background: rgba(255,255,255,0.03);
      border: 1px solid rgba(255,255,255,0.06);
      border-radius: 9px;
      padding: 10px 12px;
      font-family: var(--font-sf);
      font-size: 11px;
      line-height: 1.55;
      color: var(--text-secondary);
      /* Roomier than the old 76px clamp: the panel runs full screen height
         with a pinned footer, so tall screens had a void between the
         parameter grid and the button while both prompts sat clipped at
         three lines. Show the metadata instead of the empty panel. */
      max-height: 128px;
      overflow-y: auto;
      word-break: break-word;
    }
    .fsim-meta-value::-webkit-scrollbar { width: 3px; }
    .fsim-meta-value::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 2px; }
    .fsim-meta-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 6px;
    }
    .fsim-meta-chip {
      background: rgba(255,255,255,0.03);
      border: 1px solid rgba(255,255,255,0.06);
      border-radius: 7px;
      padding: 7px 9px;
    }
    .fsim-meta-chip .k {
      font-size: 10px;
      font-weight: 800;
      letter-spacing: 0.5px;
      color: var(--text-muted);
      text-transform: uppercase;
      margin-bottom: 2px;
    }
    .fsim-meta-chip .v {
      font-size: 11px;
      font-weight: 600;
      color: var(--text-primary);
      font-family: var(--font-sf);
      word-break: break-word;
    }
    @keyframes fsimApplyRipple {
      0%   { box-shadow: 0 0 0 0 rgba(255,255,255,0.55); opacity: 1; }
      100% { box-shadow: 0 0 0 22px rgba(255,255,255,0); opacity: 0; }
    }

    /* Floating animated cursor for inspect stage demo */
    .fsim-cursor-pointer {
      position: absolute;
      width: 22px;
      height: 22px;
      pointer-events: none;
      z-index: 30;
      opacity: 0;
      transform: translate(-4px, -2px) scale(0.9);
      transition: opacity 0.25s ease, transform 0.45s var(--ease-out-expo), left 0.6s cubic-bezier(0.6, 0.05, 0.3, 1), top 0.6s cubic-bezier(0.6, 0.05, 0.3, 1);
      filter: drop-shadow(0 2px 6px rgba(0,0,0,0.6));
    }
    .fsim-cursor-pointer.visible {
      opacity: 1;
      transform: translate(-4px, -2px) scale(1);
    }
    .fsim-cursor-pointer.tapping {
      transform: translate(-4px, -2px) scale(0.82);
    }
    .fsim-cursor-pointer svg { display: block; width: 100%; height: 100%; }
    .fsim-cursor-tap-ring {
      position: absolute;
      width: 28px;
      height: 28px;
      border-radius: 50%;
      pointer-events: none;
      z-index: 29;
      border: 2px solid rgba(255,255,255,0.85);
      opacity: 0;
      transform: translate(-50%, -50%) scale(0.4);
    }
    .fsim-cursor-tap-ring.firing {
      animation: fsimCursorTapRing 0.55s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    }
    @keyframes fsimCursorTapRing {
      0%   { opacity: 0.9; transform: translate(-50%, -50%) scale(0.4); }
      60%  { opacity: 0.5; }
      100% { opacity: 0; transform: translate(-50%, -50%) scale(1.8); }
    }
    /* Highlight tapped buttons briefly */
    .fsim-meta-copy.fsim-cursor-hit {
      animation: fsimCopyHit 0.5s cubic-bezier(0.16, 1, 0.3, 1);
    }
    @keyframes fsimCopyHit {
      0%   { background: rgba(255,255,255,0.06); transform: scale(1); }
      40%  { background: rgba(255,255,255,0.3); transform: scale(0.94); }
      100% { background: rgba(255,255,255,0.06); transform: scale(1); }
    }
    @keyframes fsimApplyHit {
      0%   { transform: scale(1); }
      40%  { transform: scale(0.94); }
      100% { transform: scale(1); }
    }



    /* =========================================
       STAGE 5 — Regenerate (Image Gen with imported settings)
       ========================================= */
    .fsim-regen-panel {
      height: 100%;
      display: flex;
      flex-direction: column;
      gap: 11px;
    }
    .fsim-regen-banner {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 9px 12px;
      background: rgba(74,222,128,0.08);
      border: 1px solid rgba(74,222,128,0.25);
      border-radius: 9px;
      font-size: 11px;
      color: #30d158;
      animation: fsimBannerSlide 0.5s cubic-bezier(0.16, 1, 0.3, 1);
    }
    .fsim-regen-banner b { color: #fff; font-weight: 700; }
    .fsim-regen-banner svg { flex-shrink: 0; }
    @keyframes fsimBannerSlide {
      from { opacity: 0; transform: translateY(-8px); }
      to   { opacity: 1; transform: translateY(0); }
    }
    .fsim-gen-btn-active {
      background: linear-gradient(90deg, var(--bg-hover), var(--bg-tertiary), var(--bg-hover));
    }
    .fsim-regen-tile {
      position: relative;
      background: var(--bg-tertiary);
      overflow: hidden;
    }
    .fsim-regen-tile img {
      opacity: 0;
      animation: fsimTileResolve 1.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    }
    .fsim-stage[data-active-stage="6"] .fsim-regen-tile img {
      animation-play-state: running;
    }
    .fsim-regen-tile::after {
      content: '';
      position: absolute;
      inset: 0;
      background: linear-gradient(110deg,
        var(--bg-tertiary) 0%,
        rgba(255,255,255,0.04) 25%,
        rgba(255,255,255,0.12) 50%,
        rgba(255,255,255,0.04) 75%,
        var(--bg-tertiary) 100%);
      background-size: 250% 100%;
      animation: fsimSeamShimmer 1.6s linear infinite;
      opacity: 1;
      transition: opacity 0.5s ease;
      pointer-events: none;
    }
    .fsim-regen-tile.fsim-tile-done::after {
      opacity: 0;
      animation: none;
    }
    @keyframes fsimTileResolve {
      0%   { opacity: 0; filter: blur(14px); transform: scale(1.05); }
      50%  { opacity: 0.8; filter: blur(6px); transform: scale(1.02); }
      100% { opacity: 1; filter: blur(0); transform: scale(1); }
    }

    /* =========================================
       MOBILE POLISH — tighter spacing, smaller fonts inside device
       ========================================= */
    @media (max-width: 1023px) {
      .fsim-layer { padding: 16px; }
      .fsim-gen-prompt { font-size: 11px; padding: 10px 12px; }
      .fsim-gen-chip { padding: 6px 9px; font-size: 11px; }
      .fsim-gen-btn { padding: 9px 14px; font-size: 12px; }
      .fsim-gen-output-label, .fsim-gen-label { font-size: 10px; }
      .fsim-gen-grid { gap: 6px; }
      .fsim-upload-source { padding: 10px; gap: 10px; }
      .fsim-upload-source-thumb { width: 50px; height: 50px; }
      .fsim-upload-fname { font-size: 12px; }
      .fsim-upload-fmeta { font-size: 10px; }
      .fsim-upload-target { padding: 12px; }
      .fsim-upload-target-head { font-size: 11px; margin-bottom: 9px; }
      .fsim-upload-status { font-size: 11px; }
      .fsim-dash-toolbar { gap: 8px; }
      .fsim-dash-search { font-size: 11px; padding: 8px 10px; }
      .fsim-dash-add { font-size: 11px; padding: 8px 12px; }
      .fsim-dash-title { font-size: 11px; }
      .fsim-dash-meta { font-size: 10px; }
      .fsim-dash-info { padding: 8px 10px; }
      .fsim-meta-head { padding: 13px 16px; }
      .fsim-meta-head h3 { font-size: 13px; }
      .fsim-meta-body { padding: 12px 14px 14px; gap: 11px; }
      .fsim-meta-value { font-size: 10px; padding: 9px 11px; max-height: 60px; }
      .fsim-meta-chip { padding: 6px 8px; }
      .fsim-meta-chip .v { font-size: 11px; }
      .fsim-regen-banner { font-size: 11px; padding: 8px 11px; }
      .fsim-copy-meta { font-size: 10px; }
      .fsim-copy-toast-head { font-size: 11px; }
      .fsim-copy-code { font-size: 10px; padding: 6px 8px; }
      .fsim-paste-tab { font-size: 11px; padding: 8px 11px; }
      .fsim-paste-editor { font-size: 11px; padding: 13px; }
      .fsim-paste-saved { font-size: 10px; }
      .fsim-paste-btn { font-size: 11px; padding: 8px 12px; }
      .fsim-titlebar { padding: 10px 14px; gap: 10px; }
      .fsim-dots span { width: 9px; height: 9px; }
      .fsim-url { font-size: 11px; }
    }
    @media (max-width: 640px) {
      .fsim-layer { padding: 12px; }
      .fsim-meta-panel { box-shadow: -10px 0 40px rgba(0,0,0,0.7); }
      .fsim-meta-grid { gap: 5px; }
      .fsim-meta-chip .k { font-size: 10px; }
      .fsim-meta-chip .v { font-size: 10px; }
    }

    /* =========================================
       FINAL PAYOFF
       ========================================= */
    .files-payoff {
      padding: 100px 0;
      background: radial-gradient(ellipse at top, rgba(255,255,255,0.03), transparent 70%);
    }
    @media (max-width: 768px) { .files-payoff { padding: 60px 0; } }
    .files-payoff-title {
      font-size: clamp(32px, 5vw, 56px);
      font-weight: 800;
      letter-spacing: -1.5px;
      line-height: 1.06;
      margin-bottom: 18px;
    }
    .files-final-chat {
      max-width: 680px;
      margin: 0 auto;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 20px;
      overflow: hidden;
      box-shadow: 0 30px 80px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.04);
    }
    .ffc-header {
      display: flex;
      align-items: center;
      gap: 14px;
      padding: 16px 20px;
      background: var(--bg-tertiary);
      border-bottom: 1px solid var(--border-color);
    }
    .ffc-avatar {
      width: 44px; height: 44px;
      border-radius: 50%;
      overflow: hidden;
      flex-shrink: 0;
      border: 2px solid rgba(255,255,255,0.08);
    }
    .ffc-avatar img { width: 100%; height: 100%; object-fit: cover; }
    .ffc-name-block { flex: 1; min-width: 0; }
    .ffc-name {
      font-size: 15px;
      font-weight: 700;
      color: var(--text-primary);
    }
    .ffc-status {
      font-size: 11px;
      color: var(--text-muted);
      display: flex;
      align-items: center;
      gap: 6px;
      margin-top: 2px;
    }
    .ffc-status-dot {
      width: 7px; height: 7px;
      border-radius: 50%;
      background: #30d158;
    }
    .ffc-platform-badge {
      font-size: 10px;
      font-weight: 700;
      color: var(--text-secondary);
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      padding: 4px 10px;
      border-radius: 20px;
      letter-spacing: 0.3px;
    }
    .ffc-body {
      padding: 24px 28px;
      display: flex;
      flex-direction: column;
      gap: 16px;
    }
    @media (max-width: 640px) { .ffc-body { padding: 20px; } }
    .ffc-msg-italic {
      color: var(--text-secondary);
      font-style: italic;
      font-size: 15px;
      line-height: 1.65;
    }
    .ffc-italic-inline {
      color: var(--text-secondary);
      font-style: italic;
    }
    .ffc-msg-quote {
      color: var(--text-primary);
      font-size: 15px;
      line-height: 1.6;
      font-weight: 500;
    }
    .ffc-img-wrap {
      margin: 6px auto;
      border-radius: 14px;
      overflow: hidden;
      max-width: 340px;
      box-shadow: 0 10px 30px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.04);
    }
    .ffc-img-wrap img {
      width: 100%;
      display: block;
    }
    .ffc-input-row {
      padding: 14px 20px;
      background: var(--bg-tertiary);
      border-top: 1px solid var(--border-color);
      display: flex;
      gap: 10px;
      align-items: center;
    }
    .ffc-input-field {
      flex: 1;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      padding: 10px 14px;
      font-size: 13px;
      color: var(--text-muted);
    }
    .ffc-send-btn {
      background: var(--bg-hover);
      color: var(--text-primary);
      border: none;
      box-shadow: inset 0 0 0 1px var(--hairline-hover);
      width: 38px;
      height: 38px;
      border-radius: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: default;
      flex-shrink: 0;
    }

    /* ==========================================================
       APPLE POLISH LAYER — type details, unified interaction
       physics, card elevation, reduced motion. Appended last so
       equal-specificity rules win the cascade.
       ========================================================== */

    /* --- Type & detail --- */
    .hero h1, .sec h2, .final-cta h2, .ag-show-text h2 { text-wrap: balance; }
    .sec-sub, .hero-sub { text-wrap: pretty; }
    ::selection { background: rgba(255, 255, 255, 0.88); color: #0a0a0a; }
    :where(a, button, input, select, textarea, [role="tab"]):focus-visible {
      outline: 3px solid rgba(255, 255, 255, 0.3);
      outline-offset: 2px;
    }
    :where(a, button):focus:not(:focus-visible) { outline: none; }

    /* macOS traffic lights on mock-window titlebars */
    .mock-titlebar .dots span:nth-child(1), .code-mock-head .dots span:nth-child(1) { background: #ff5f57; }
    .mock-titlebar .dots span:nth-child(2), .code-mock-head .dots span:nth-child(2) { background: #febc2e; }
    .mock-titlebar .dots span:nth-child(3), .code-mock-head .dots span:nth-child(3) { background: #28c840; }

    /* --- Unified press physics: everything tactile presses down fast
       and springs back on release --- */
    .nav-links a, .foot-row a {
      transition: color 0.2s ease, transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1));
    }
    .faq-q { transition: transform var(--dur-move) var(--ease-settle); }
    /* The estate press (global.press, 2026-09-23): .94 on the shared curves. */
    .nav-links a:active, .foot-row a:active,
    .price-cta:active, .help-badge:active {
      transform: scale(0.94);
      transition: color 0.2s ease, transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1));
    }
    .faq-q:active { transform: scale(0.99); transition: transform var(--dur-press) var(--ease-press); }

    /* --- Card elevation: shared resting shadow + faint top light-catch,
       deeper shadow on hover (existing translateY(-3px) hovers stay) --- */
    .step, .feat, .price, .rp-card, .platform-card, .hq-card,
    .usecase-card, .why-card, .toolkit-card {
      box-shadow: var(--elev-1), var(--edge-top);
      transition: border-color 0.3s ease,
                  transform 0.55s var(--ease-settle),
                  box-shadow var(--dur-move) ease;
    }
    .step:hover, .feat:hover, .price:hover, .rp-card:hover, .platform-card:hover,
    .hq-card:hover, .usecase-card:hover, .why-card:hover, .toolkit-card:hover {
      box-shadow: var(--elev-2), var(--edge-top);
    }

    /* ===== SPECULAR HOVER =====
       Replaces the uniform border-brighten. A flat outline that lights up all
       the way round tells you nothing about where you are; it is the same
       cheap signal a white bloom gives, just quieter.

       These cards are glass. Glass under a moving light source picks up a
       highlight that travels with the source, and its edge catches hardest
       where the light is closest. So: two layers driven by the real pointer
       position (--px/--py, written by the rAF loop in initCardSheen).

         ::before  a soft sheen across the surface, wide and low-contrast
         ::after   a 1px rim lit only near the cursor, via a mask that punches
                   out the middle so the gradient survives on the border alone

       Both fade in on hover, so a card at rest is completely inert. Cursor
       only; touch and reduced-motion get the plain border, handled below. */
    .step, .feat, .price, .rp-card, .platform-card,
    .hq-card, .usecase-card, .why-card, .toolkit-card {
      --px: 50%;
      --py: 0%;
    }
    .step::before, .feat::before, .price:not(.featured)::before, .rp-card::before,
    .platform-card::before, .hq-card::before, .usecase-card::before,
    .why-card::before, .toolkit-card::before,
    .step::after, .feat::after, .price::after, .rp-card::after,
    .platform-card::after, .hq-card::after, .usecase-card::after,
    .why-card::after, .toolkit-card::after {
      content: '';
      position: absolute;
      inset: 0;
      border-radius: inherit;
      pointer-events: none;
      opacity: 0;
      transition: opacity 0.5s var(--ease-out-expo);
      z-index: 0;
    }
    /* surface sheen */
    .step::before, .feat::before, .price:not(.featured)::before, .rp-card::before,
    .platform-card::before, .hq-card::before, .usecase-card::before,
    .why-card::before, .toolkit-card::before {
      background: radial-gradient(380px circle at var(--px) var(--py),
        rgba(255,255,255,0.055),
        rgba(255,255,255,0.018) 38%,
        transparent 68%);
    }
    /* rim light: gradient confined to the 1px border by an xor mask */
    .step::after, .feat::after, .price::after, .rp-card::after,
    .platform-card::after, .hq-card::after, .usecase-card::after,
    .why-card::after, .toolkit-card::after {
      padding: 1px;
      background: radial-gradient(240px circle at var(--px) var(--py),
        rgba(255,255,255,0.5),
        rgba(255,255,255,0.12) 42%,
        transparent 72%);
      -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
              mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
      -webkit-mask-composite: xor;
              mask-composite: exclude;
    }
    .step:hover::before, .feat:hover::before, .price:not(.featured):hover::before,
    .rp-card:hover::before, .platform-card:hover::before, .hq-card:hover::before,
    .usecase-card:hover::before, .why-card:hover::before, .toolkit-card:hover::before,
    .step:hover::after, .feat:hover::after, .price:hover::after,
    .rp-card:hover::after, .platform-card:hover::after, .hq-card:hover::after,
    .usecase-card:hover::after, .why-card:hover::after, .toolkit-card:hover::after {
      opacity: 1;
    }
    /* keep real content above both layers */
    .step > *, .feat > *, .price > *, .rp-card > *, .platform-card > *,
    .hq-card > *, .usecase-card > *, .why-card > *, .toolkit-card > * {
      position: relative;
      z-index: 1;
    }
    /* ...but children that are positioned by design must keep their own
       positioning. The blanket rule above has the same specificity as their
       own class rules and comes later, so it was pinning the corner badges
       and card numbers back into the content flow, where top/right offsets
       pushed them on top of the card icon. */
    .feat > .feat-tag,
    .why-card > .why-num,
    .spot > .spot-glow {
      position: absolute;
    }
    /* No pointer to track: fall back to the plain edge. */
    @media (hover: none), (prefers-reduced-motion: reduce) {
      .step::before, .feat::before, .price:not(.featured)::before, .rp-card::before,
      .platform-card::before, .hq-card::before, .usecase-card::before,
      .why-card::before, .toolkit-card::before,
      .step::after, .feat::after, .price::after, .rp-card::after,
      .platform-card::after, .hq-card::after, .usecase-card::after,
      .why-card::after, .toolkit-card::after { display: none; }
      .step:hover, .feat:hover, .price:hover, .rp-card:hover,
      .platform-card:hover, .hq-card:hover, .usecase-card:hover,
      .why-card:hover, .toolkit-card:hover { border-color: var(--hairline-hover); }
    }

    /* Active nav link (section tracking) */
    .nav-links a.active { color: var(--text-primary); }

    /* --- Files-sim stage entrances: elements materialize in a cascade
       when a stage activates (driven by fsimStaggerIn) --- */
    .fsim-enter {
      opacity: 0;
      transform: translateY(14px) scale(0.985);
    }
    .fsim-enter.fsim-enter-in {
      opacity: 1;
      transform: none;
      transition: opacity 0.6s var(--ease-out-expo), transform 0.6s var(--ease-out-expo);
    }
    @media (prefers-reduced-motion: reduce) {
      .fsim-enter { opacity: 1 !important; transform: none !important; transition: none !important; }
    }

    /* --- Cinematic hero entrance: staggered materialize on first load,
       gated by a one-shot body class so it never fights the tab cascade --- */
    @keyframes pageRise {
      from { opacity: 0; transform: translateY(26px) scale(0.985); filter: blur(6px); }
      to { opacity: 1; transform: none; filter: none; }
    }
    @keyframes pageRiseFlat {
      from { opacity: 0; transform: translateY(30px) scale(0.985); }
      to { opacity: 1; transform: none; }
    }
    body.page-entering .hero h1 { animation: pageRise 0.9s var(--ease-out-expo) 0.15s both; }
    body.page-entering .hero-sub { animation: pageRise 0.9s var(--ease-out-expo) 0.28s both; }
    body.page-entering .hero-ctas { animation: pageRise 0.9s var(--ease-out-expo) 0.4s both; }
    body.page-entering .hero-trust { animation: pageRise 0.9s var(--ease-out-expo) 0.52s both; }
    /* Mock panel: no blur (it hosts the 3D tilt + glass), rise only */
    body.page-entering .hero-mock { animation: pageRiseFlat 1.1s var(--ease-out-expo) 0.35s both; }

    /* --- Film grain: makes flat black read as material, not void --- */
    body::after {
      content: '';
      position: fixed;
      inset: 0;
      background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/><feColorMatrix type='saturate' values='0'/></filter><rect width='160' height='160' filter='url(%23n)' opacity='0.5'/></svg>");
      background-size: 160px 160px;
      opacity: 0.028;
      pointer-events: none;
      z-index: 2000;
    }

    /* --- Cursor spotlight on cards: a soft light that tracks the pointer.
       Injected .spot-glow span (no pseudo conflicts), monochrome only --- */
    .spot { position: relative; }
    .spot .spot-glow {
      position: absolute;
      inset: 0;
      border-radius: inherit;
      pointer-events: none;
      opacity: 0;
      transition: opacity 0.35s ease;
      background: radial-gradient(300px circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, 0.08), transparent 62%);
    }
    .spot:hover .spot-glow { opacity: 1; }

    /* --- Featured pricing tier gets physical presence on desktop --- */
    @media (min-width: 900px) {
      .price.featured { transform: scale(1.04); }
      .price.featured:hover { transform: scale(1.02); }
    }

    /* --- Reduced motion: curated, not a global nuke — transition
       durations go near-zero (not none) so transitionend still fires
       for the pay-modal FLIP; untouchable systems (fsim, carousel,
       mock cycles) keep their own behavior --- */
    @media (prefers-reduced-motion: reduce) {
      .reveal { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
      .marquee { animation-play-state: paused !important; }
      .mock-frame, .ag-mock, .lock-group,
      .hero-mock, .tilt-host.hero-mock { animation: none !important; }
      /* Loading affordances keep their meaning without the sweep: the
         skeleton stays a skeleton, the state label stays a state label. */
      .mock-tile.empty, .ag-batch-img.skel,
      .ag-batch-stage.shimmer, .engine-label.active,
      .mock-status.gen-active .label {
        animation: none !important;
        background-position: 50% 50% !important;
      }
      .mock-tile img, .ag-batch-img img { animation: none !important; }
      .engine-label.active, .ag-batch-stage.shimmer,
      .mock-status.gen-active .label {
        -webkit-text-fill-color: #ffbd2e !important;
        color: #ffbd2e !important;
      }
      body.page-entering .hero h1,
      body.page-entering .hero-sub, body.page-entering .hero-ctas,
      body.page-entering .hero-trust, body.page-entering .hero-mock { animation: none !important; }
      .spot .spot-glow { display: none !important; }
      .pay-modal.animating, .pay-backdrop, .svc-pill, .faq-a, .nav-inner,
      .billing-pill, .billing-xfade, .billing-hfade, .pay-guide-pill,
      .pay-net-strip,
      .step, .feat, .price, .rp-card, .platform-card, .hq-card,
      .usecase-card, .why-card, .toolkit-card { transition-duration: 0.01ms !important; }
    }

  
    /* 2026-10-04 lists without ticks: plan lines are plain text with air. */
    .price ul li { padding: 5px 0; color: var(--text-secondary); }
  
    /* 2026-10-04 no decorative green; King is a sheet behind "More tiers". */
    /* The gateway's payment styles also paint this chip green; doubled class wins. */
    .billing-saving.billing-saving { background: rgba(255,255,255,0.1); color: var(--text-primary); }
    /* Monthly / Annual reads as a capsule, not a rounded square (owner 10-04).
       Doubled classes beat the gateway's copy of the same rules. */
    .billing-switch.billing-switch { border-radius: 999px; border: 0; box-shadow: 0 4px 14px rgba(0,0,0,0.35); }
    .billing-switch.billing-switch .billing-pill, .billing-switch.billing-switch button { border-radius: 999px; }
    .billing-saving.billing-saving { border-radius: 999px; padding: 3px 8px; }
    /* The nav's Generate / API / Files thumb was too bright (owner 10-04). */
    html body .svc-switch .svc-btn.active.active { background: rgba(255,255,255,0.045); box-shadow: inset 0 1px 0 rgba(255,255,255,0.07), inset 0 -1px 0 rgba(0,0,0,0.3), 0 1px 2px rgba(0,0,0,0.3); }
    /* Plan buttons: every tier the same, Elite included (owner 10-04). */
    .price-grid .price.featured .price-cta, .price-grid .price.featured .price-cta:hover { background: rgba(237,237,237,0.04); border-color: rgb(255,255,255); transform: none; }
    .price .more-tiers { margin-top: 10px; }
    .more-tiers { display: block; margin: 12px auto 0; padding: 6px 10px; background: none; border: 0; color: var(--text-secondary); font: inherit; font-size: 13px; cursor: pointer; transition: color .2s ease; }
    .more-tiers:hover { color: var(--text-primary); }
    .king-sheet-dialog { margin: auto; padding: 0; border: 0; background: transparent; color: inherit; width: min(400px, calc(100% - 32px)); max-height: calc(100dvh - 32px); overflow: auto; }
    .king-sheet-dialog::backdrop { background: rgba(0,0,0,0.6); }
    .king-sheet-dialog .price { background: var(--bg-secondary); backdrop-filter: none; -webkit-backdrop-filter: none; }
    .king-sheet-close { position: absolute; z-index: 2; top: 16px; right: 16px; width: 28px; height: 28px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; background: rgba(255,255,255,0.06); color: var(--text-secondary); cursor: pointer; }
    .king-sheet-close svg { width: 14px; height: 14px; }
    .king-sheet-close:hover { color: var(--text-primary); }
    @media (prefers-reduced-motion: no-preference) {
      .king-sheet-dialog[open] { animation: kingSheetIn .32s cubic-bezier(.2,.9,.25,1); }
      .king-sheet-dialog[open]::backdrop { animation: kingSheetFade .2s ease; }
    }
    @keyframes kingSheetIn { from { opacity: 0; translate: 0 12px; scale: .98; } }
    @keyframes kingSheetFade { from { opacity: 0; } }
  
    /* ===== LANDING VISUALS (2026-10-04) =====
       Real material in place of icon cards and text-only sections: a real
       streamed reply, real app screenshots, real pictures with the prompts and
       models that made them. Every class is lv- so nothing older can match. */
    .lv-chat { background: var(--bg-secondary); border: 1px solid var(--hairline); border-radius: 16px; padding: 20px 22px 16px; display: flex; flex-direction: column; gap: 14px; min-height: 460px; text-align: left; }
    .lv-chat-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; padding-bottom: 12px; border-bottom: 1px solid var(--hairline); }
    .lv-who { font-weight: 650; color: var(--text-primary); }
    .lv-sub { color: var(--text-muted); font-size: 13px; }
    .lv-seg { margin-left: auto; display: flex; gap: 2px; }
    .lv-seg button { font: inherit; font-size: 12px; color: var(--text-secondary); background: none; border: 0; padding: 5px 10px; border-radius: 999px; cursor: pointer; white-space: nowrap; transition: color .2s ease, background-color .2s ease; }
    .lv-seg button.on { color: var(--text-primary); background: rgba(255,255,255,0.07); }
    .lv-msg.lv-user { align-self: flex-end; max-width: 78%; background: rgba(255,255,255,0.06); border-radius: 14px; padding: 10px 14px; color: var(--text-secondary); font-size: 14px; line-height: 1.5; }
    .lv-msg.lv-bot { font-size: 15.5px; line-height: 1.62; color: #dcdcdc; white-space: pre-wrap; min-height: 220px; }
    .lv-caret { display: inline-block; width: 7px; height: 1em; vertical-align: -2px; background: var(--text-secondary); margin-left: 1px; animation: lvBlink 1s steps(1) infinite; }
    @keyframes lvBlink { 50% { opacity: 0; } }
    .lv-chat-foot { margin-top: auto; font-size: 12px; color: var(--text-muted); font-family: ui-monospace, "SF Mono", Menlo, monospace; padding-top: 10px; border-top: 1px solid var(--hairline); }

    .lv-split { display: grid; grid-template-columns: 1fr; gap: 40px; align-items: center; }
    @media (min-width: 960px) { .lv-split { grid-template-columns: 4fr 7fr; gap: 56px; } }
    .sec .lv-split h2 { font-size: clamp(28px, 3.4vw, 40px); letter-spacing: -0.035em; line-height: 1.08; margin-bottom: 14px; }
    .lv-facts { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 10px; }
    .lv-facts li { color: var(--text-secondary); font-size: 14px; }
    .lv-facts b { color: var(--text-primary); font-weight: 600; margin-right: 8px; }
    .lv-shot { margin: 0; border-radius: 14px; overflow: hidden; border: 1px solid rgba(255,255,255,0.12); background: #000; box-shadow: 0 30px 80px rgba(0,0,0,0.55); }
    .lv-shot img { display: block; width: 100%; height: auto; }

    .lv-duo { display: grid; grid-template-columns: 1fr; gap: 20px; }
    @media (min-width: 900px) { .lv-duo { grid-template-columns: 1fr 1fr; } }
    .lv-duo article { background: var(--bg-secondary); border: 1px solid var(--hairline); border-radius: 16px; padding: 22px 24px; text-align: left; }
    .lv-duo header { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding-bottom: 12px; margin-bottom: 14px; border-bottom: 1px solid var(--hairline); }
    .lv-duo header span { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12px; color: var(--text-muted); }
    .lv-duo p { color: #d6d6d6; line-height: 1.62; font-size: 15px; margin: 0; }
    .lv-duo p + p { margin-top: 12px; }

    .lv-wallsec { position: relative; margin-bottom: 56px; }
    .lv-wall-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 8px 24px; margin-bottom: 20px; }
    .sec .lv-wall-head h3 { font-size: 20px; font-weight: 600; letter-spacing: -0.01em; margin: 0; }
    .lv-note { color: var(--text-secondary); font-size: 14px; line-height: 1.6; margin-top: 18px; max-width: 46ch; }
    .lv-wall { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; max-height: 640px; overflow: hidden; align-items: start; }
    .lv-col { display: grid; gap: 10px; }
    .lv-col:nth-child(even) { margin-top: 56px; }
    .lv-wall img { width: 100%; height: auto; display: block; border-radius: 10px; background: var(--bg-tertiary); }
    .lv-fade { position: absolute; left: 0; right: 0; bottom: 0; height: 220px; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 20px; background: linear-gradient(transparent, var(--bg-primary) 78%); }
    .lv-fade .cta-secondary { padding: 12px 22px; border-radius: 999px; }
    @media (max-width: 720px) {
      .lv-wall { grid-template-columns: 1fr 1fr; max-height: 620px; }
      .lv-col:nth-child(n+3) { display: none; }
    }

    .lv-pairs { display: grid; grid-template-columns: 1fr; gap: 28px 20px; max-width: 1080px; margin: 0 auto; }
    @media (min-width: 600px) { .lv-pairs { grid-template-columns: 1fr 1fr; } }
    @media (min-width: 960px) { .lv-pairs { grid-template-columns: repeat(3, 1fr); } }
    .lv-pairs figure { margin: 0; }
    .lv-pairs img { width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 12px; display: block; background: var(--bg-tertiary); }
    .lv-pairs figcaption { margin-top: 12px; display: grid; gap: 8px; justify-items: start; text-align: left; }
    .lv-chip { display: inline-block; font-size: 11px; font-weight: 600; color: var(--text-primary); background: rgba(255,255,255,0.08); border-radius: 999px; padding: 2px 8px; white-space: nowrap; }
    .lv-pairs code, .lv-meta code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12px; line-height: 1.55; color: var(--text-secondary); }

    .lv-cap { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end; gap: 8px 24px; margin-bottom: 24px; }
    .sec .lv-cap h2 { font-size: clamp(28px, 3.4vw, 40px); line-height: 1.1; letter-spacing: -0.035em; margin: 0; }

    #filesContent .files-hero .lv-fhero { display: grid; grid-template-columns: 1fr; gap: 40px; align-items: center; }
    @media (min-width: 1024px) {
      #filesContent .files-hero .lv-fhero { grid-template-columns: 5fr 6fr; gap: 48px; }
      #filesContent .files-hero .lv-fhero .files-hero-inner { text-align: left; margin: 0; }
      #filesContent .files-hero .lv-fhero .files-hero-ctas { justify-content: flex-start; }
    }
    .lv-fgal { position: relative; }
    .lv-wall.lv-tight { gap: 8px; max-height: 560px; -webkit-mask: linear-gradient(#000 70%, transparent); mask: linear-gradient(#000 70%, transparent); }
    .lv-tight .lv-col { gap: 8px; }
    .lv-tight img { border-radius: 8px; }
    .lv-linkpill { position: absolute; left: 50%; bottom: 28px; transform: translateX(-50%); display: flex; align-items: center; gap: 10px; max-width: calc(100% - 24px); background: rgba(18,18,18,0.86); -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); border: 1px solid rgba(255,255,255,0.14); border-radius: 999px; padding: 9px 10px 9px 14px; white-space: nowrap; box-shadow: 0 12px 40px rgba(0,0,0,0.5); }
    .lv-linkpill code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12px; color: var(--text-primary); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
    .lv-dot { width: 7px; height: 7px; border-radius: 50%; background: #30d158; flex: none; }
    .lv-copied { font-size: 12px; font-weight: 600; background: rgba(255,255,255,0.08); border-radius: 999px; padding: 3px 10px; flex: none; }

    .lv-tri { display: grid; grid-template-columns: 1fr; gap: 20px; }
    @media (min-width: 900px) { .lv-tri { grid-template-columns: repeat(3, 1fr); } }
    .lv-tri figure { margin: 0; background: var(--bg-secondary); border: 1px solid var(--hairline); border-radius: 16px; padding: 14px; display: flex; flex-direction: column; gap: 14px; text-align: left; }
    .lv-tri figcaption { color: var(--text-secondary); font-size: 14px; padding: 0 4px 4px; }
    .lv-tri figcaption b { display: block; color: var(--text-primary); font-weight: 600; margin-bottom: 2px; }
    .lv-t-gal { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; aspect-ratio: 1; }
    .lv-t-gal img { width: 100%; height: 100%; object-fit: cover; border-radius: 8px; min-height: 0; }
    .lv-t-read, .lv-t-prev { aspect-ratio: 1; position: relative; overflow: hidden; border-radius: 8px; }
    .lv-t-read img, .lv-t-prev img { width: 100%; height: 100%; object-fit: cover; display: block; }
    .lv-meta { position: absolute; left: 0; right: 0; bottom: 0; display: grid; gap: 6px; justify-items: start; padding: 40px 12px 12px; background: linear-gradient(transparent, rgba(0,0,0,0.82)); }
    .lv-meta code { color: #cfcfcf; }
    .lv-t-prev img { filter: blur(22px) brightness(0.8); transform: scale(1.15); }
    .lv-lock { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 13px; font-weight: 600; background: rgba(10,10,10,0.6); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); border-radius: 999px; padding: 8px 14px; white-space: nowrap; }
    @media (prefers-reduced-motion: reduce) { .lv-caret { animation: none; } }
      /*lv-player-css*/
    .lv-player { margin: 0; text-align: left; }
    .lv-screen { position: relative; aspect-ratio: 16 / 10; border-radius: 14px; overflow: hidden; background: #111; border: 1px solid rgba(255,255,255,0.12); box-shadow: 0 30px 80px rgba(0,0,0,0.55); }
    .lv-clip { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; opacity: 0; transform: scale(1.015); transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1), transform 0.9s cubic-bezier(0.22, 1, 0.36, 1); }
    .lv-clip.on { opacity: 1; transform: none; }
    @media (prefers-reduced-motion: reduce) { .lv-clip { transition: none; transform: none; } }
/*/lv-player-css*/
  

.pay-modal.open:not(.animating):not(.show-crypto){top:50%!important;left:50%!important;transform:translate(-50%,-50%)!important;width:min(480px,calc(100vw - 24px))!important;max-height:calc(100dvh - 40px)}
.pay-modal.open:not(.animating) .pay-modal-viewport{min-height:0}
.pay-modal.open:not(.animating) .pane-main{height:100%;max-height:100%;box-sizing:border-box}


.billing-controls{display:flex;flex-direction:column;align-items:center;gap:12px;margin:0 auto 38px;text-align:center}
/* The billing picker is the switch this page already has, not a second design
   for the same job. Tray, sliding pill, radius and the 0.42s glide are the
   nav's .svc-switch / .svc-pill. Before this it had no pill at all: a white
   fill jumped between the two buttons with no motion of any kind. */
.billing-switch{position:relative;display:inline-flex;align-items:center;gap:0;padding:4px;
  border:1px solid var(--border-color);border-radius:12px;background:rgba(20,20,20,.6);
  backdrop-filter:var(--glass-blur);-webkit-backdrop-filter:var(--glass-blur);
  box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 4px 14px rgba(0,0,0,.35),0 1px 2px rgba(0,0,0,.2)}
.billing-pill{position:absolute;top:4px;bottom:4px;left:0;width:0;z-index:0;
  background:var(--bg-tertiary);border:1px solid rgba(255,255,255,.08);border-radius:9px;
  transition:left .42s var(--ease-glide),width .42s var(--ease-glide);
  box-shadow:0 1px 0 rgba(255,255,255,.05) inset,0 2px 6px rgba(0,0,0,.25)}
/* first placement must not slide in from zero width */
.billing-switch.no-anim .billing-pill{transition:none}
.billing-switch button{position:relative;z-index:1;display:flex;align-items:center;justify-content:center;
  gap:9px;border:0;border-radius:9px;min-height:44px;padding:10px 18px;font:inherit;font-size:15px;
  font-weight:600;color:var(--text-muted);background:transparent;cursor:pointer;white-space:nowrap;
  transition:color .3s ease}
.billing-switch button[aria-pressed="true"]{color:var(--text-primary)}
.billing-switch button:hover:not([aria-pressed="true"]){color:var(--text-secondary)}
.billing-saving{font-size:11px;padding:3px 6px;border-radius:5px;background:rgba(255,255,255,.13);color:var(--text-primary);white-space:nowrap}
/* Copy that changes with the period leaves upward and the replacement rises
   into its place, so the prices read as one control changing rather than four
   separate labels blinking. Heights glide too, or the grid below would jump
   the moment the intro paragraph rewraps. */
.billing-xfade{transition:opacity .17s ease,transform .17s ease}
.billing-xfade.is-out{opacity:0;transform:translateY(-4px)}
.billing-xfade.is-in{opacity:0;transform:translateY(4px)}
.billing-xfade.no-anim{transition:none}
.billing-hfade{transition:height .26s var(--ease-glide);overflow:hidden}
.price-billing-note{font-size:13px;color:var(--text-secondary);line-height:1.5;min-height:20px;margin:-14px 0 16px}
.price-billing-note strong{font-weight:500;color:var(--text-primary)}.price-billing-note small{display:block;color:#30d158;font-size:12px}
.pay-billing-note{font-size:12px;line-height:1.5;margin:12px 0 0;color:var(--text-secondary)}
.pay-option[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
.billing-switch button:focus-visible{outline:2px solid var(--text-primary);outline-offset:4px}
@media(max-width:480px){.billing-switch button{padding:10px 14px;font-size:14px}.billing-controls{margin-bottom:28px}.price-billing-note{min-height:0}}


    /* THE COIN PICKER, restored 2026-09-08.

       This pane spent a while as a searchable accordion: one full-width row per
       token, each expanding into a list of networks with a fee note on every
       line. It read as a form. The look it had before that - and the one asked
       for again - is a shop shelf: a grid of logos you recognise at a glance.

       The network step survives, because a token really can settle on several
       chains, but it is now a strip of pills that opens under the coin you
       tapped, and only for a coin that has more than one. */
    .pay-coin-grid{grid-column:1/-1;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
    @media(min-width:620px){.pay-coin-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
    .pay-coin-tile[aria-expanded="true"]{background:var(--bg-hover);border-color:rgba(255,255,255,.22)}
    .pay-net-strip{grid-column:1/-1;display:grid;grid-template-rows:0fr;
      transition:grid-template-rows .42s var(--ease-glide)}
    .pay-net-strip.open{grid-template-rows:1fr}
    .pay-net-inner{overflow:hidden;min-height:0}
    /* the padding lives on the row, never on the animating track, or the
       height animation fights its own padding for the first few frames */
    .pay-net-row{display:flex;flex-wrap:wrap;gap:7px;padding:9px 2px 4px;
      color:var(--text-secondary);font-size:13px}
    .pay-net-pill{font:inherit;font-size:13px;font-weight:600;color:var(--text-primary);
      background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:999px;
      padding:9px 15px;min-height:40px;cursor:pointer;
      transition:background .2s ease,border-color .2s ease,transform var(--kg-press-out,100ms cubic-bezier(0.4,0,0.6,1))}
    .pay-net-pill:hover:not(:disabled){background:var(--bg-hover);border-color:rgba(255,255,255,.2)}
    .pay-net-pill:active:not(:disabled){transform:scale(.94);transition:background .2s ease,border-color .2s ease,transform var(--kg-press-in,100ms cubic-bezier(0.4,0,0.6,1))}
    .pay-net-pill:disabled{opacity:.4;cursor:not-allowed}
    .pay-net-pill:focus-visible{outline:2px solid var(--text-primary);outline-offset:2px}


.pay-crypto-guide-host{grid-column:1/-1;min-width:0;margin-bottom:12px}
.pay-crypto-guide-host [hidden]{display:none!important}
.pay-modal.open.show-crypto:not(.animating):not(.show-crypto-guide){top:50%!important;left:50%!important;transform:translate(-50%,-50%)!important;width:min(480px,calc(100vw - 24px))!important;max-height:calc(100dvh - 40px)}
.pay-modal.show-crypto.show-crypto-guide{width:min(780px,calc(100vw - 32px))!important;max-width:780px;height:min(850px,calc(100dvh - 40px))!important;max-height:calc(100dvh - 40px);top:50%!important;left:50%!important;transform:translate(-50%,-50%)!important}
.pay-modal.show-crypto-guide .pane-crypto{max-height:none}
.pay-crypto-guide{padding:22px;border:1px solid var(--border-color);border-radius:16px;background:var(--bg-secondary);color:var(--text-primary);font-size:14px;line-height:1.55}
.pay-guide-heading{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:16px}
.pay-guide-heading h3{display:flex;align-items:center;gap:10px;font-size:20px;line-height:1.3;margin:0}
.pay-guide-info{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:1.5px solid currentColor;border-radius:50%;font-size:14px;font-weight:700;flex:none;color:#73baff}
.pay-guide-intro,.pay-guide-instructions,.pay-guide-footnote{margin:0;color:var(--text-secondary)}
/* Same switch as the nav and the billing picker: one pill that measures the
   selected tab and glides. left/top/width/height are all set, so it stays
   correct when the row wraps onto a second line on a phone. */
.pay-guide-tabs{position:relative;display:flex;flex-wrap:wrap;gap:6px;margin:18px 0}
.pay-guide-pill{position:absolute;left:0;top:0;width:0;height:0;z-index:0;pointer-events:none;
  background:var(--bg-tertiary);border:1px solid rgba(255,255,255,.08);border-radius:9px;
  box-shadow:0 1px 0 rgba(255,255,255,.05) inset,0 2px 6px rgba(0,0,0,.25);
  transition:left .42s var(--ease-glide),top .42s var(--ease-glide),
             width .42s var(--ease-glide),height .42s var(--ease-glide)}
.pay-guide-tabs.no-anim .pay-guide-pill{transition:none}
.pay-guide-tabs button{position:relative;z-index:1;font:inherit;border:0;color:var(--text-muted);
  background:transparent;border-radius:9px;min-height:44px;padding:8px 12px;cursor:pointer;
  white-space:nowrap;transition:color .3s ease}
.pay-guide-tabs button[aria-selected="true"]{color:var(--text-primary)}
.pay-guide-tabs button:hover[aria-selected="false"]{color:var(--text-secondary)}
.pay-guide-provider{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:20px;padding:17px 0;border-bottom:1px solid var(--border-color)}
.pay-guide-provider:first-child{padding-top:4px}.pay-guide-provider:last-child{border-bottom:0}
.pay-guide-provider h4{font-size:16px;font-weight:600;margin:0 0 3px}.pay-guide-provider p{color:var(--text-secondary);margin:0}
.pay-guide-provider .pay-guide-tip{color:#74ce91;margin-top:4px}
.pay-guide-visit{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:44px;white-space:nowrap;color:var(--text-primary);font-weight:600;padding:6px 10px;border-radius:9px}
.pay-guide-visit:hover{background:var(--bg-hover)}
.pay-guide-instructions{border-top:1px solid var(--border-color);padding-top:18px;margin-top:8px}.pay-guide-footnote{font-size:12px;margin-top:12px}
.pay-crypto-guide :is(button,a):focus-visible{outline:2px solid var(--text-primary);outline-offset:3px}
@media(max-width:480px){.pay-crypto-guide{padding:15px;font-size:13px}.pay-guide-heading{gap:8px}.pay-guide-heading h3{font-size:18px}.pay-guide-provider{gap:8px}.pay-guide-tabs button{padding:7px 9px}.pay-guide-visit{padding:6px}.pay-modal.show-crypto.show-crypto-guide{width:calc(100vw - 24px)!important;max-width:calc(100vw - 24px)}}
    /* THE BAR'S CONTROLS AGREE ON ONE SIZE (2026-09-25). The owner, on the
       top bar: "the switch on the landing page is big yet get started button
       is so small". Measured at 1440: the product tray 44 tall with 36px
       cells, Get started 28 tall at 13px, the links 14px. Every control in
       the bar is now 36 tall with 14px words - the tray by a 3px inset round
       30px cells, Get started as a 36px capsule - and the product on show
       wears the dimmer thumb (.07, 12% top rim) instead of the .12 slab.
       Stated last, and one element more specific than every earlier layer,
       because four earlier rules (this page's, its phone rule, and the main
       worker's button aliases) each set part of it. */
    html body .svc-switch { padding: 3px; gap: 2px; }
    html body .svc-switch .svc-btn { height: 30px; padding: 0 9px; }
    html body .svc-switch .svc-btn.active {
      background: rgba(255, 255, 255, 0.07);
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), inset 0 -1px 0 rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.3);
    }
    html body .svc-switch .svc-l { font-size: 14px; }
    html body .nav-links a.nav-cta,
    html body a.nav-cta {
      display: inline-flex; align-items: center; justify-content: center;
      box-sizing: border-box; height: 36px; min-height: 36px; padding: 0 16px;
      border-radius: 999px; font-size: 14px; line-height: 1;
      background: rgba(237, 237, 237, 0.07);
    }
  
    /* No pointer-tracked light on panels (owner 10-04): the sheen, rim and spotlight stay off. */
    .step::before, .feat::before, .price:not(.featured)::before, .rp-card::before, .platform-card::before, .hq-card::before, .usecase-card::before, .why-card::before, .toolkit-card::before, .step::after, .feat::after, .price::after, .rp-card::after, .platform-card::after, .hq-card::after, .usecase-card::after, .why-card::after, .toolkit-card::after { opacity: 0 !important; }
    .spot .spot-glow { display: none !important; }
  

/* THE FOCUS POLICY. COPY FIRST (DESIGN.md:138). Source: this block, written
   once for the estate on 2026-09-14 and copied into every Kyrune surface.
   Licence: this repo. UNCHANGED between the copies: the selectors, their order
   and the 2px geometry. EDITED, and why: one line, --kg-focus-ink, is restated
   to this surface's own ink token, which is the palette edit the Copy First
   Rule allows.

   The browser's square focus rectangle never paints on a Kyrune surface.
   Nothing that is not a control shows a ring in any state, so a heading the
   page focuses for a screen reader still takes the focus and shows nothing.
   Pointer and touch focus shows nothing at all. A keyboard ring lands only on
   a control, because a keyboard visitor has no other way to see where they
   are: A 1px HAIRLINE AT 60% INK, 2px off, drawn around the control's own
   radius (2px of full ink until 2026-09-20; the owner: "remove the focus
   thing or make the outline super thin", and DESIGN.md "Buttons" now states
   the hairline for the whole estate). There is a 6px
   floor under a control that states none so the ring can never be a square.
   That floor is written at zero specificity, so a control with a radius of its
   own keeps it and nothing moves at rest. A text field takes no ring at all:
   its caret and its own border are the affordance (DESIGN.md, Inputs). */
:root { --kg-focus-ink: rgba(237, 237, 237, 0.6); }
:focus:not(:focus-visible) { outline: none; }
:not(a, button, input, select, textarea, summary, [role="button"], [role="link"], [role="tab"], [role="menuitem"], [role="switch"], [role="checkbox"], [role="radio"], [role="option"], [contenteditable="true"], [tabindex]:not([tabindex="-1"])):is(:focus, :focus-visible) { outline: none; }
[tabindex="-1"]:is(:focus, :focus-visible) { outline: none; }
svg:is(:focus, :focus-visible), svg :is(:focus, :focus-visible) { outline: none; }
:where(a, button, input, select, textarea, summary, [role="button"], [role="link"], [role="tab"], [role="menuitem"], [role="switch"], [role="checkbox"], [role="radio"], [role="option"], [tabindex]:not([tabindex="-1"])):where(:focus-visible) { border-radius: 6px; }
:is(a, button, select, summary, input:is([type="checkbox"], [type="radio"], [type="range"], [type="button"], [type="submit"], [type="reset"], [type="file"]), [role="button"], [role="link"], [role="tab"], [role="menuitem"], [role="switch"], [role="checkbox"], [role="radio"], [role="option"], [tabindex]:not([tabindex="-1"])):not(svg, svg *):focus-visible { outline: 1px solid var(--kg-focus-ink); outline-offset: 2px; }
input:not([type="checkbox"], [type="radio"], [type="range"], [type="button"], [type="submit"], [type="reset"], [type="file"], [type="image"], [type="color"]):is(:focus, :focus-visible), textarea:is(:focus, :focus-visible), [contenteditable="true"]:is(:focus, :focus-visible) { outline: none; }

/* kg-buttons: the one capsule. Tokens fall back to the estate ink. */
/* THE PRESS SPRING (2026-09-23): in = stiffness 900 damping 40, out = 420 / 16 with velocity 2. */
:root{--kg-press-in:100ms cubic-bezier(0.4,0,0.6,1); --kg-press-out:100ms cubic-bezier(0.4,0,0.6,1)}
@supports (transition-timing-function: linear(0, 1)){:root{
  --kg-press-in:160ms linear(0, 0.2809 5%, 0.4942 10%, 0.6529 15%, 0.7689 20%, 0.8518 25%, 0.9098 30%, 0.9493 35%, 0.9754 40%, 0.9919 45%, 1.0018 50%, 1.0072 55%, 1.0097 60%, 1.0103 65%, 1.0099 70%, 1.0089 75%, 1.0076 80%, 1.0063 85%, 1.0051 90%, 1.004 95%, 1);
  --kg-press-out:653ms linear(0, 0.5257 2.5%, 0.9642 5%, 1.3156 7.5%, 1.5537 10%, 1.6787 12.5%, 1.7111 15%, 1.6649 17.5%, 1.5667 20%, 1.4330 22.5%, 1.2871 25%, 1.1506 27.5%, 1.0275 30%, 0.9302 32.5%, 0.8642 35%, 0.8252 37.5%, 0.8127 40%, 0.8213 42.5%, 0.8458 45%, 0.8799 47.5%, 0.9169 50%, 0.9545 52.5%, 0.9878 55%, 1.0147 57.5%, 1.0333 60%, 1.0448 62.5%, 1.0492 65%, 1.0477 67.5%, 1.0419 70%, 1.0332 72.5%, 1.0235 75%, 1.0136 77.5%, 1.0045 80%, 0.9974 82.5%, 0.9919 85%, 0.9886 87.5%, 0.9872 90%, 0.9873 92.5%, 0.9887 95%, 0.9908 97.5%, 1);
}}
.kg-btn{
  --kg-btn-ink: var(--kg-ink, var(--text-primary, #ededed));
  --kg-btn-rim: inset -1px 1px 0 0 rgba(255,255,255,.10), inset 1px -1px 0 0 rgba(255,255,255,.10);
  --kg-btn-drop: 0 4px 19px rgba(0,0,0,.4);
  position:relative; display:inline-flex; align-items:center; justify-content:center; gap:8px;
  box-sizing:border-box; margin:0; border:0; border-radius:999px;
  height:36px; padding:0 16px; font:inherit; font-size:14px; font-weight:650; line-height:1.2;
  white-space:nowrap; text-decoration:none; cursor:pointer; user-select:none; -webkit-user-select:none;
  appearance:none; -webkit-appearance:none; -webkit-tap-highlight-color:transparent; touch-action:manipulation;
  -webkit-backdrop-filter:none; backdrop-filter:none;
  color:var(--kg-btn-ink); background:rgba(237,237,237,.04); box-shadow:var(--kg-btn-rim), var(--kg-btn-drop);
  transition:transform var(--kg-press-out), color 200ms cubic-bezier(0.22,1,0.36,1);
}
.kg-btn svg{flex:0 0 auto; width:18px; height:18px}
/* NO HOVER: nothing changes under the pointer (the owner, 2026-09-20). */
.kg-btn:hover{background:inherit}
.kg-btn:active:not(:disabled):not([aria-disabled="true"]){transform:scale(.94); transition:transform var(--kg-press-in), color 200ms cubic-bezier(0.22,1,0.36,1)}
.kg-btn:focus{outline:none}
.kg-btn:focus-visible{outline:1px solid rgba(237,237,237,.6); outline-offset:2px}
.kg-btn:disabled,.kg-btn[aria-disabled="true"]{cursor:not-allowed; box-shadow:none}
/* sizes */
.kg-btn-s{height:28px; padding:0 12px; font-size:13px}
.kg-btn-s svg{width:16px; height:16px}
.kg-btn-l{height:44px; padding:0 22px; font-size:15px}
.kg-btn-l svg{width:20px; height:20px}
/* tiers: steps on one alpha ladder, never a new grey, never white */
.kg-btn-primary{background:rgba(237,237,237,.07); color:var(--kg-btn-ink); box-shadow:var(--kg-btn-rim), var(--kg-btn-drop)}
.kg-btn-primary:hover{background:rgba(237,237,237,.07)}
.kg-btn-primary:disabled,.kg-btn-primary[aria-disabled="true"]{background:rgba(237,237,237,.04); color:rgba(237,237,237,.30)}
.kg-btn-secondary{background:rgba(237,237,237,.04); color:var(--kg-btn-ink); box-shadow:var(--kg-btn-rim), var(--kg-btn-drop)}
.kg-btn-secondary:hover{background:rgba(237,237,237,.04)}
.kg-btn-secondary:disabled,.kg-btn-secondary[aria-disabled="true"]{color:rgba(237,237,237,.18)}
.kg-btn-quiet{background:transparent; color:rgba(237,237,237,.60); box-shadow:none}
.kg-btn-quiet:hover{background:transparent}
.kg-btn-quiet:disabled,.kg-btn-quiet[aria-disabled="true"]{color:rgba(237,237,237,.18)}
.kg-btn-destructive{background:rgba(255,69,58,.15); color:#ff453a; box-shadow:var(--kg-btn-rim)}
.kg-btn-destructive:hover{background:rgba(255,69,58,.15)}
.kg-btn-destructive:disabled,.kg-btn-destructive[aria-disabled="true"]{color:rgba(255,69,58,.30)}
/* the icon disc: two diameters and an info circle, the glyph half the disc (2026-09-23) */
.kg-btn-disc{width:32px; height:32px; padding:0; gap:0; border-radius:50%}
.kg-btn-disc svg{width:16px; height:16px}
.kg-btn-disc-s{width:28px; height:28px; padding:0; gap:0; border-radius:50%}
.kg-btn-disc-s svg{width:14px; height:14px}
.kg-btn-disc-xs{width:26px; height:26px; padding:0; gap:0; border-radius:50%}
.kg-btn-disc-xs svg{width:14px; height:14px}
/* A finger gets 44pt as REACH, never as size: a transparent extension of the
   button, so nothing drawn changes on a phone. The owner, 2026-09-20 evening:
   buttons that grew on the phone "ruined the UI in some places". */
@media (pointer:coarse){
  .kg-btn::after{content:""; position:absolute; top:50%; left:50%; width:max(100%,44px); height:max(100%,44px); transform:translate(-50%,-50%); border-radius:inherit}
}
@media (prefers-reduced-motion:reduce){ .kg-btn{transition:none} .kg-btn:active:not(:disabled):not([aria-disabled="true"]){transform:none; transition:none} }
/* =====================================================================
   MENU - shared by the account menu and the tile overflow menu.
   It now opens on the same Framework7 iOS popover motion as the sampler
   picker and every other choice menu: kgpMenuScaleIn / kgpMenuSlideIn from
   KG_PICKER_CSS. It used to run kgPopIn at 0.32s, which is why the account
   menu and the sampler picker felt like two different products.
   ===================================================================== */
.kg-menu {
  position: fixed;
  z-index: 4000;
  min-width: 208px;
  max-width: min(280px, calc(100vw - 16px));
  padding: 0;
  border-radius: 13px;
  overflow: hidden;
  background: rgba(28, 28, 31, 0.82);
  -webkit-backdrop-filter: blur(30px) saturate(170%);
  backdrop-filter: blur(30px) saturate(170%);
  border: 1px solid rgba(255, 255, 255, 0.13);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 18px 44px rgba(0, 0, 0, 0.55);
  /* F7 popover-on-bottom popover-on-left: origin right top, offset -50% / -80px. */
  transform-origin: right top;
  --kgp-menu-off-x: -50%;
  --kgp-menu-off-y: -80px;
  animation:
    kgpMenuScaleIn var(--kgp-menu-scale-in) var(--kgp-menu-curve) both,
    kgpMenuSlideIn var(--kgp-menu-slide-in) var(--kgp-menu-curve) both;
}
.kg-menu[hidden] { display: none; }
.kg-menu.kg-menu-out {
  pointer-events: none;
  animation: kgpMenuScaleOut var(--kgp-menu-scale-out) var(--kgp-menu-curve-out) both;
}
.kg-menu [role="menuitem"] {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  background: none;
  color: var(--text-primary);
  font: inherit;
  font-size: 13.5px;
  text-align: left;
  cursor: pointer;
  transition: background 0.2s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.1s cubic-bezier(0.4, 0, 0.6, 1);
}
.kg-menu [role="menuitem"] + [role="menuitem"] { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07); }
.kg-menu [role="menuitem"]:active { transform: scale(0.97); }
.kg-menu [role="menuitem"] svg { width: 16px; height: 16px; flex: 0 0 auto; }
.kg-menu .kg-menu-danger { color: var(--kammii-danger, #ff453a); }
@media (prefers-reduced-transparency: reduce) {
  .kg-menu { background: var(--bg-secondary); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .kg-menu { animation: none; }
}

/* ---- FOCUS: the standard-s one hairline, keyboard only ------------- */
html .nav-cta:focus-visible,
html .cta-primary:focus-visible,
html .cta-secondary:focus-visible,
html .price-cta:focus-visible,
html .img-btn:focus-visible,
html .help-badge:focus-visible,
html .pay-modal-close:focus-visible,
html .pay-crypto-back:focus-visible,
html .pay-crypto-coin:focus-visible {
  outline: 1px solid rgba(237, 237, 237, 0.6);
  outline-offset: 2px;
}
/* .faq-q takes no rule of its own. Measured on kammii.ai after this block
   shipped: focus-policy.js already draws exactly this hairline on it at
   (0,2,1), which outranks anything written here at (0,1,2), so an inset
   variant would have been a rule that reads as intent and paints nothing.
   The nine selectors above are in the same position and are kept only as
   the floor for an engine that narrows the shared policy-s :is() list. */

/* ---- PRESS: the only feedback, the standard-s spring (2026-09-23) --- */
html .nav-cta,
html .cta-primary,
html .cta-secondary,
html .price-cta,
html .img-btn,
html .help-badge,
html .pay-modal-close,
html .pay-crypto-back {
  transition: transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1)),
              color 200ms cubic-bezier(0.22, 1, 0.36, 1);
  -webkit-tap-highlight-color: transparent;
}
html .nav-cta:active,
html .cta-primary:active,
html .cta-secondary:active,
html .price-cta:active,
html .img-btn:active,
html .help-badge:active,
html .pay-modal-close:active,
html .pay-crypto-back:active {
  transform: scale(0.94);
  transition: transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)),
              color 200ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* No backdrop blur rests on a button, and nothing on this page idles in
   an animation any more: the iOS breathing pulse the census recorded on
   the three primary CTAs is cancelled here as well as absent from the
   served markup, so a copy that still carries it cannot reintroduce it. */
html .nav-cta,
html .cta-primary,
html .cta-secondary,
html .price-cta,
html .img-btn,
html .help-badge,
html .pay-modal-close,
html .pay-crypto-back,
html .fsim-gen-btn,
html .fsim-paste-btn,
html .fsim-meta-copy,
html .ffc-send-btn {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  animation: none;
}

/* ---- THE ALPHA LADDER ---------------------------------------------- */
/* Primary, rgba(237,237,237,.10) with light ink (.14 until 2026-09-23). */
html .nav-links a.nav-cta,
html .nav-cta,
html .cta-primary,
html .price.featured .price-cta {
  background: rgba(237, 237, 237, 0.10);
  color: var(--text-primary, #ededed);
  border: 0;
  box-shadow:
    inset -1px 1px 0 0 rgba(255, 255, 255, 0.1),
    inset 1px -1px 0 0 rgba(255, 255, 255, 0.1),
    0 4px 19px rgba(0, 0, 0, 0.4);
  filter: none;
}
/* Secondary, the .04 step (.05 until 2026-09-23). The four simulation buttons are here too: they
   are drawn inside a product mock, so they have to read as the estate-s
   buttons or the mock is showing a product that does not exist. */
html .cta-secondary,
html .price-cta,
html .img-btn,
html .help-badge,
html .fsim-gen-btn,
html .fsim-paste-btn,
html .ffc-send-btn {
  background: rgba(237, 237, 237, 0.04);
  color: var(--text-primary, #ededed);
  border: 0;
  box-shadow:
    inset -1px 1px 0 0 rgba(255, 255, 255, 0.1),
    inset 1px -1px 0 0 rgba(255, 255, 255, 0.1),
    0 4px 19px rgba(0, 0, 0, 0.4);
  filter: none;
}

/* ---- NO HOVER: nothing changes under the pointer on any button ------ */
/* The page-s own hover rules cannot be deleted from here (the markup is a
   generated constant), so each is answered at its tier-s resting value.
   Measured before and after a real hover, every declaration matches. */
html .nav-cta:hover,
html .cta-primary:hover,
html .price.featured .price-cta:hover {
  background: rgba(237, 237, 237, 0.10);
  color: var(--text-primary, #ededed);
  border: 0;
  box-shadow:
    inset -1px 1px 0 0 rgba(255, 255, 255, 0.1),
    inset 1px -1px 0 0 rgba(255, 255, 255, 0.1),
    0 4px 19px rgba(0, 0, 0, 0.4);
}
html .cta-secondary:hover,
html .price-cta:hover,
html .img-btn:hover,
html .help-badge:hover,
html .pay-modal-close:hover,
html .pay-crypto-back:hover {
  background: rgba(237, 237, 237, 0.04);
  color: var(--text-primary, #ededed);
  border: 0;
  box-shadow:
    inset -1px 1px 0 0 rgba(255, 255, 255, 0.1),
    inset 1px -1px 0 0 rgba(255, 255, 255, 0.1),
    0 4px 19px rgba(0, 0, 0, 0.4);
}
/* The page-s hover lifts are cancelled only while nothing is pressed, so
   the press above still takes the button down under a pointer. */
html .nav-cta:hover:not(:active),
html .cta-primary:hover:not(:active),
html .price.featured .price-cta:hover:not(:active),
html .cta-secondary:hover:not(:active),
html .price-cta:hover:not(:active),
html .img-btn:hover:not(:active),
html .help-badge:hover:not(:active),
html .pay-modal-close:hover:not(:active),
html .pay-crypto-back:hover:not(:active) { transform: none; }

/* ---- THE ONE CAPSULE, AND THE THREE SIZES --------------------------- */
html .nav-cta,
html .cta-primary,
html .cta-secondary,
html .price-cta,
html .fsim-gen-btn,
html .fsim-paste-btn {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: 999px;
  font-weight: 650;
  line-height: 1.2;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  appearance: none;
  -webkit-appearance: none;
}
/* The pricing CTA fills its card-s width, the hero pair fills its column. */
html .price-cta { display: flex; width: 100%; }
html .cta-primary, html .cta-secondary { display: flex; }
/* S - 28. The phone rule that shrank the nav CTA to 12px type and a 10px
   corner is answered here too: one drawn size at 390 and at 1440, which is
   what the no-growth rule asks for read in both directions. */
html .nav-links a.nav-cta,
html .nav-cta,
html .fsim-gen-btn,
html .fsim-paste-btn {
  min-height: 28px;
  height: auto;
  padding: 0 12px;
  font-size: 13px;
  font-weight: 650;
  border-radius: 999px;
}
/* One label weight. The featured pricing CTA carried 700 at (0,3,0) and
   the nav CTA 700 at (0,2,1), which is two emphases for one tier: the
   fill already says which of the four is the recommended plan. */
html .price.featured .price-cta { font-weight: 650; }
/* M - 36 */
html .price-cta {
  min-height: 36px;
  height: auto;
  padding: 0 16px;
  font-size: 14px;
}
/* L - 44 */
html .cta-primary,
html .cta-secondary {
  min-height: 44px;
  height: auto;
  padding: 0 22px;
  font-size: 15px;
}
html .cta-primary svg,
html .cta-secondary svg { width: 20px; height: 20px; }
html .fsim-gen-btn svg { width: 16px; height: 16px; }

/* ---- THE ICON DISCS -------------------------------------------------- */
/* Copied from account-pricing.js, which carries the OTHER copy of this same
   pay modal: 32 with an 18px glyph, the two diameters the estate has. The
   close disc was the only control in the estate that GREW on hover. */
html .pay-modal-close,
html .pay-crypto-back {
  display: flex; align-items: center; justify-content: center; flex: none;
  width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(237, 237, 237, 0.04);
  box-shadow:
    inset -1px 1px 0 0 rgba(255, 255, 255, 0.1),
    inset 1px -1px 0 0 rgba(255, 255, 255, 0.1),
    0 4px 19px rgba(0, 0, 0, 0.4);
  color: var(--text-primary, #ededed);
  /* 18px draws the times GLYPH this copy still uses as its close mark
     (the account copy calls kgIcon("x", 18) for the same 18px picture).
     Swapping the character for the Lucide x is an icon-lane markup edit,
     not a button look, so the size the glyph needs is stated here. */
  cursor: pointer; font: inherit; font-size: 18px; line-height: 1;
}
html .pay-modal-close svg,
html .pay-crypto-back svg { width: 18px; height: 18px; }
/* The simulator-s send control is the same disc, 36 with a 20px glyph: it
   stands in a composer row, which is where the estate draws the larger of
   the two diameters. It was a 38px square with a 10px corner. */
html .ffc-send-btn {
  box-sizing: border-box;
  width: 36px; height: 36px; padding: 0; gap: 0; border-radius: 50%;
}
html .ffc-send-btn svg { width: 20px; height: 20px; }

/* ---- FOUR ARGUED DIVERGENCES ---------------------------------------- */
/* 1. .img-btn keeps its 76px plate height. It carries a 36px logo image,
      not a label, so the standard-s 44 would crush the thing the control
      exists to show. It takes the capsule, the tier, the press, the focus
      hairline and the no-hover rule - everything except the height. */
html .img-btn {
  box-sizing: border-box;
  width: 100%;
  height: 76px;
  border-radius: 999px;
  cursor: pointer;
}
/* 2. .help-badge keeps 28px and takes NO coarse-pointer reach. It is a
      corner badge pinned half outside the plate above, so a 44pt reach
      would sit on top of that plate and swallow taps meant for it. The
      white keyword fill with a black label is gone; so is the scale(1.15)
      hover, which was the page-s only growing control. */
html .help-badge {
  box-sizing: border-box;
  width: 28px; height: 28px;
  border-radius: 50%;
  font-weight: 650;
}
/* 3. .faq-q keeps its full-width row geometry and its gentler press. A
      disclosure header is a row inside a card, the way the generator-s
      menu rows are; scaling a full-bleed row to .96 reads as a glitch. It
      takes the behaviour and the inset hairline only. */
html .faq-q:active { transform: scale(0.99); }
/* 4. .pay-crypto-coin and .pay-crypto-guide stay CHOICE TILES, copied from
      account-pricing.js line for line rather than made capsules: a coin
      row is a list item in a picker, which DESIGN.md holds outside the
      button standard on purpose. Only the lift on hover goes. */
html .pay-crypto-coin {
  border: 0;
  transition: background-color .18s ease, transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1));
}
html .pay-crypto-coin:hover { background: var(--bg-hover); transform: none; }
/* The estate press (global.press, 2026-09-23), as on the account sheet. */
html .pay-crypto-coin:active { transform: scale(0.94); transition: background-color .18s ease, transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }

/* ---- THE READ-ONLY CHIPS -------------------------------------------- */
/* Five chips inside the product mocks wore five radii (20 / 8 / 8 / 7 / 6)
   and the same fill-plus-hairline recipe the real buttons used, which the
   census called the single biggest source of "is that clickable?" on this
   surface. They are not controls, so they do not take a tier; they take
   one radius, the tag shape DESIGN.md already states, so a capsule on this
   page means a control and a tag means a tag. */
html .render-stat-chip,
html .fsim-step-pill,
html .fsim-gen-chip,
html .fsim-uo-size-pill,
html .fsim-meta-chip,
html .fsim-meta-copy { border-radius: 999px; }

/* ---- REACH WITHOUT SIZE --------------------------------------------- */
/* The owner, 2026-09-20 evening: buttons that grew on the phone "ruined
   the UI in some places". A finger gets 44pt as a transparent extension
   of the control, so nothing drawn changes at 390. Copied from
   shared/kg-buttons.js and from account-pricing.js. */
@media (pointer: coarse) {
  html .nav-cta,
  html .price-cta,
  html .pay-modal-close,
  html .pay-crypto-back,
  html .ffc-send-btn { position: relative; }
  html .nav-cta::after,
  html .price-cta::after,
  html .pay-modal-close::after,
  html .pay-crypto-back::after,
  html .ffc-send-btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: max(100%, 44px);
    height: max(100%, 44px);
    transform: translate(-50%, -50%);
    border-radius: inherit;
  }
}

/* ---- WHAT THE GATEWAY APPENDS AFTER THIS BLOCK --------------------- */
/* kammii.ai does not serve this document unchanged: the gateway runs
   updateLandingPage() over it, and updatePaymentPanel() there splices its
   own payment bundle (payments-ui.generated.js) in at the end of the
   head - AFTER
   this block, so on equal specificity it wins. It replaces the pay
   modal-s markup and adds the billing picker, the network pills and the
   crypto guide. Nothing it adds overrides a tier set above, because the
   html prefix outranks its plain class selectors. Three things it does
   carry are the estate-s, not the pay sheet-s, to decide:
     - three rings at 2px solid full ink (the billing switch at offset 4,
       the network pill at 2, the guide-s buttons and links at 3),
     - a hover on the network pill and one on the guide-s visit link.
   DESIGN.md states one hairline for the whole estate and no hover on a
   button, so they are answered here at one element deeper. The right
   home for the fix is the gateway-s own payments bundle; this is the
   floor until that lane moves, and it is recorded in the lane report. */
html .billing-switch button:focus-visible,
html .pay-net-pill:focus-visible,
html .pay-crypto-guide :is(button, a):focus-visible {
  outline: 1px solid rgba(237, 237, 237, 0.6);
  outline-offset: 2px;
}
html .pay-net-pill:hover:not(:disabled) {
  background: var(--bg-tertiary);
  border-color: var(--border-color);
}
/* The estate press (global.press, 2026-09-23) over the bundle-s .96. */
html .pay-net-pill { transition: background .2s ease, border-color .2s ease, transform var(--kg-press-out, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
html .pay-net-pill:active:not(:disabled) { transform: scale(0.94); transition: background .2s ease, border-color .2s ease, transform var(--kg-press-in, 100ms cubic-bezier(0.4, 0, 0.6, 1)); }
html .pay-guide-visit:hover { background: transparent; }

@media (prefers-reduced-motion: reduce) {
  html .nav-cta,
  html .cta-primary,
  html .cta-secondary,
  html .price-cta,
  html .img-btn,
  html .help-badge,
  html .pay-modal-close,
  html .pay-crypto-back { transition: none; }
}

    /* Digital twin of the generator's model-import surface. Reuses the page's
       mock-frame chrome, the fsim cursor, the heroWord morph keyframes and the
       ksim model-card vocabulary. Progress is the size number itself counting
       up: no bars, no dots, no checkmarks, no status tags. */
    .imp-stage { position: relative; }
    /* grid items default to min-width auto, so the mono link and filename
       were propagating their min-content width up and pinning the whole
       window at ~354px on narrow phones - let the column shrink and the
       text ellipsize instead */
    .imp-show .imp-mock-col { min-width: 0; }
    /* no hairline under the chrome in this window: spacing does the separating */
    .imp-mock-col .mock-titlebar { border-bottom: none; padding-bottom: 8px; margin-bottom: 8px; }
    .imp-btn {
      display: inline-flex; align-items: center; justify-content: center;
      padding: 8px 14px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 9px;
      font-size: 12px; font-weight: 650; letter-spacing: -0.1px;
      color: var(--text-primary);
      white-space: nowrap;
    }
    .imp-btn.imp-hit { animation: impBtnHit 0.5s cubic-bezier(0.16, 1, 0.3, 1); }
    @keyframes impBtnHit {
      0%   { background: var(--bg-tertiary); transform: scale(1); }
      40%  { background: rgba(255,255,255,0.24); transform: scale(0.94); }
      100% { background: var(--bg-tertiary); transform: scale(1); }
    }
    .imp-field {
      display: flex; align-items: center;
      height: 43px;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: 10px;
      padding: 0 14px;
      font-family: var(--font-sf);
      font-size: 12px;
      line-height: 1.4;
      color: var(--text-secondary);
      white-space: nowrap;
      overflow: hidden;
      transition: border-color 0.3s ease;
    }
    /* tapping the field focuses it, like a real input */
    .imp-field.imp-hit { border-color: rgba(255,255,255,0.35); }
    .imp-field .imp-ph { color: var(--text-muted); display: inline-block; }
    #impUrl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
    .imp-field .imp-ph.is-gone { display: none; }
    .imp-field .imp-ph.imp-morph-out, .imp-transfer span.imp-morph-out { animation: heroWordOut 0.22s var(--ease-out-quint) forwards; }
    .imp-transfer {
      display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
      height: 17px; /* reserved even while empty so the library never shifts */
      margin-top: 10px;
      padding: 0 2px;
      font-family: var(--font-sf);
      font-size: 12px;
      line-height: 1.4;
      color: var(--text-secondary);
      visibility: hidden; opacity: 0;
      transition: opacity 0.3s ease, visibility 0.3s;
    }
    .imp-transfer.is-on { visibility: visible; opacity: 1; }
    .imp-transfer.is-on .imp-tname, .imp-transfer.is-on .imp-tsize { animation: heroWordIn 0.5s var(--ease-out-quint); }
    .imp-tname { min-width: 0; overflow: hidden; text-overflow: ellipsis; display: inline-block; }
    .imp-tsize { color: var(--text-primary); font-variant-numeric: tabular-nums; flex-shrink: 0; display: inline-block; }
    /* category groups mirror the real UI's gallery structure: an uppercase
       title row with its import button, then the card row beneath it */
    .imp-group { margin-top: 18px; }
    .imp-group-head {
      display: flex; align-items: center; justify-content: space-between; gap: 12px;
      margin-bottom: 10px;
    }
    .imp-group-title {
      font-size: 12px; font-weight: 700;
      letter-spacing: 0.04em; text-transform: uppercase;
      color: var(--text-primary);
    }
    .imp-row {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 12px;
    }
    .imp-card { min-width: 0; }
    .imp-card-img {
      width: 100%; aspect-ratio: 3 / 4;
      border-radius: 10px;
      background: var(--bg-tertiary);
      overflow: hidden;
      margin-bottom: 8px;
    }
    .imp-card-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
    .imp-card-name {
      font-size: 12px; font-weight: 600; color: var(--text-primary); text-align: center;
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    /* imported slots hold their space from the start so nothing shifts;
       the card arrives the way a real asset does: the empty tile shows up
       while the file is still downloading and sweeps like every other
       loading tile on the page, then the preview blur-loads into it and
       the name settles underneath */
    .imp-card.is-new { opacity: 0; visibility: hidden; transition: opacity 0.4s ease, visibility 0.4s; }
    .imp-card.is-new.is-wait, .imp-card.is-new.is-in { opacity: 1; visibility: visible; }
    .imp-card.is-new .imp-card-img { position: relative; }
    .imp-card.is-new .imp-card-img::after {
      content: '';
      position: absolute; inset: 0;
      background: linear-gradient(100deg, transparent 32%, rgba(255,255,255,0.07) 50%, transparent 68%);
      transform: translateX(-100%);
    }
    .imp-card.is-new.is-wait .imp-card-img::after { animation: impSweep 1.1s linear infinite; }
    @keyframes impSweep { to { transform: translateX(100%); } }
    .imp-card.is-new .imp-card-img img { opacity: 0; }
    .imp-card.is-new.is-in .imp-card-img img { opacity: 1; animation: impImgLoad 0.7s var(--ease-out-quint); }
    @keyframes impImgLoad {
      from { opacity: 0; filter: blur(16px); transform: scale(1.05); }
      to   { opacity: 1; filter: blur(0);   transform: none; }
    }
    .imp-card.is-new .imp-card-name { opacity: 0; transition: opacity 0.35s ease 0.15s; }
    .imp-card.is-new.is-in .imp-card-name { opacity: 1; }
    @media (max-width: 480px) {
      /* phone: everything scales down together so the window keeps the same
         proportions it has on desktop instead of oversized chrome over tiny cards */
      .imp-mock-col .mock-frame { padding: 14px; }
      .imp-mock-col .mock-titlebar { padding-bottom: 6px; margin-bottom: 6px; }
      .imp-field { height: 38px; font-size: 11px; padding: 0 12px; }
      .imp-transfer { font-size: 11px; height: 15px; margin-top: 8px; }
      .imp-group { margin-top: 14px; }
      .imp-group-head { margin-bottom: 8px; }
      .imp-group-title { font-size: 11px; }
      .imp-btn { font-size: 11px; padding: 6px 10px; border-radius: 8px; }
      .imp-row { gap: 8px; }
      .imp-card-img { border-radius: 8px; margin-bottom: 6px; }
      .imp-card-name { font-size: 10px; }
    }
    @media (min-width: 1024px) {
      /* alternate with the AutoGen section: window left, text right */
      .imp-show .ag-show-text { order: 2; }
      .imp-show .imp-mock-col { order: 1; }
    }
    @media (prefers-reduced-motion: reduce) {
      .imp-btn.imp-hit, .imp-transfer.is-on .imp-tname, .imp-transfer.is-on .imp-tsize,
      .imp-card.is-new.is-in .imp-card-img img, .imp-card.is-new.is-wait .imp-card-img::after { animation: none; }
    }
  

    /* ===================================================================
       K AGENT SIMULATOR (#ksim)
       Hand-built in the same idiom as the Files simulator: the fsim device
       frame and scroll machinery, wrapped around a faithful recreation of
       the real K Agent interface. The composer, control panels, character
       card and their animations copy the exact CSS values, class anatomy
       and status strings of the production /autogen page (worker.js);
       model thumbnails are the live files.kammii.org assets the real
       model gallery uses, and the copy comes from the K Agent fixtures.
       =================================================================== */

    /* ---- section header ---- */
    #ksim .ksim-head { text-align: center; max-width: 760px; margin: 0 auto 26px; }
    #ksim .ksim-head h2 {
      font-size: clamp(30px, 4.6vw, 46px);
      font-weight: 800; letter-spacing: -1.2px; line-height: 1.08;
      margin: 0 0 16px;
    }
    #ksim .ksim-head p {
      font-size: 16px; line-height: 1.65; color: var(--text-secondary);
      max-width: 640px; margin: 0 auto;
    }
    #ksim .ksim-head p b { color: var(--text-primary); }

    /* ---- app shell inside the device screen ---- */
    #ksim .ksim-app {
      position: absolute; inset: 0;
      display: flex; flex-direction: column;
      background: #0a0a0a;
    }
    #ksim .ksim-topbar {
      display: flex; align-items: center; gap: 8px;
      padding: 10px 12px;
      flex-shrink: 0;
    }
    /* real .ag-fullscreen-btn / .ag-chat-new-corner-btn / .ag-chat-drawer-toggle
       (fullscreen K Agent): 36px, 12px radius, dark glass */
    #ksim .ksim-cornerbtn {
      width: 36px; height: 36px; flex-shrink: 0;
      display: inline-flex; align-items: center; justify-content: center;
      border-radius: 12px;
      border: 1px solid rgba(255,255,255,0.16);
      background: rgba(20,20,20,0.34);
      color: rgba(255,255,255,0.88);
    }
    #ksim .ksim-cornerbtn svg { width: 16px; height: 16px; }
    #ksim .ksim-hamburger { display: none; }
    /* real .ag-agent-model-button: the agent-LLM picker pill */
    #ksim .ksim-agent-pill {
      height: 34px; min-width: 104px;
      display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
      padding: 0 9px 0 11px;
      border-radius: 13px;
      border: 1px solid rgba(255,255,255,0.16);
      background: rgba(20,20,20,0.34);
      color: rgba(255,255,255,0.92); font-size: 12px; font-weight: 900;
    }
    #ksim .ksim-agent-pill svg { width: 13px; height: 13px; color: rgba(255,255,255,0.62); }
    #ksim .ksim-topbar-spacer { flex: 1; }

    /* ---- chat log area: the stage layers live here ---- */
    #ksim .ksim-log { position: relative; flex: 1; min-height: 0; }
    #ksim .fsim-layer {
      padding: 12px 16px;
      overflow: hidden;
      display: flex; flex-direction: column; gap: 10px;
    }
    /* A chat column that auto-scrolls upward as content grows, the way the
       real log follows agToolChatScrollToBottom. No CSS transition here: the
       shift is driven per frame by a damped follower in flowTick, because a
       transition restarted every 400ms turns steady text growth into a series
       of visible hops — the column would sit still, then lurch a line at once. */
    #ksim .ksim-chatflow {
      display: flex; flex-direction: column; gap: 10px;
      will-change: transform;
    }

    /* ---- composer (persistent) — real .ag-chat-compose, fullscreen values ---- */
    #ksim .ksim-composer {
      flex-shrink: 0;
      margin: 8px 12px 12px;
      /* A WRAPPING flex row, exactly like .ag-chat-compose. Collapsed it is one
         line: [+] [text] [effort mic send]. It does not grow by stretching a
         middle column, and that was the tell. */
      display: flex; flex-flow: row wrap; align-items: center; gap: 4px 6px;
      min-height: 50px;
      padding: 7px 9px; box-sizing: border-box;
      border-radius: 26px;
      border: 1px solid rgba(255,255,255,0.16);
      background: rgba(20,20,20,0.34);
      -webkit-backdrop-filter: blur(28px);
      backdrop-filter: blur(28px);
      box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), 0 10px 34px rgba(0,0,0,0.4);
      /* height is driven from composerFit so the pill can grow on a curve
         instead of snapping between layouts; --kgrow keeps every part of the
         expansion on one clock. */
      --kgrow: 0.34s;
      /* A later line wrap is not a re-layout, so it does not get the
         expansion's clock: the box just follows the field up on a short
         curve. Sharing --kgrow made every wrapped line read as the whole
         expansion animation replaying. */
      --kline: 0.19s;
      transition: height var(--kgrow) var(--ease-out-quint),
                  border-radius 0.26s cubic-bezier(0.2,0.9,0.18,1);
    }
    /* Source order matches the real one so the reflow is pure `order` swapping:
       plus 1, text 2, controls 3. */
    #ksim .ksim-plus { order: 1; flex: 0 0 auto; }
    #ksim .ksim-input-row { order: 2; flex: 1 1 auto; min-width: 40px; display: block; padding: 2px 6px; min-height: 26px; }
    #ksim .ksim-controls-right { order: 3; flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
    /* The second the prompt needs a second line, agAutoResizeTextarea puts
       .is-expanded on the pill: the text claims a full-width row of its own at
       the TOP, and the plus and the controls drop underneath it. That is what
       makes the real composer climb up the conversation as you type. */
    #ksim .ksim-composer.is-expanded { border-radius: 24px; align-items: flex-end; }
    #ksim .ksim-composer.is-expanded .ksim-input-row { order: 1; flex-basis: 100%; padding: 4px 6px 2px; }
    #ksim .ksim-composer.is-expanded .ksim-plus { order: 2; }
    #ksim .ksim-composer.is-expanded .ksim-controls-right { order: 3; margin-left: auto; }
    /* real liquid-glass composer discs (.ag-chat-plus/.ag-chat-mic/.ag-chat-action) */
    #ksim .ksim-glassbtn {
      width: 36px; height: 36px; flex-shrink: 0;
      display: inline-flex; align-items: center; justify-content: center;
      border-radius: 999px;
      border: 1px solid transparent;
      background: rgba(255,255,255,0.075);
      color: #f2f2f2;
      -webkit-backdrop-filter: blur(18px);
      backdrop-filter: blur(18px);
      box-shadow: 0 2px 8px rgba(0,0,0,0.26), 0 8px 22px rgba(0,0,0,0.2);
      transition: transform 0.34s cubic-bezier(0.34,1.45,0.5,1);
    }
    #ksim .ksim-glassbtn svg { width: 20px; height: 20px; }
    #ksim .ksim-glassbtn.is-pressed { transform: scale(0.92); }
    /* real .ag-chat-action-icons: the send arrow swaps to a stop square while
       the turn is running, with the app's own spring transition */
    #ksim .ksim-action-icons { position: relative; width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; }
    #ksim .ksim-action-icons svg {
      position: absolute; top: 50%; left: 50%; width: 20px; height: 20px;
      transform: translate(-50%, -50%) scale(1);
      transition: opacity 0.26s cubic-bezier(0.22,1,0.36,1), transform 0.32s cubic-bezier(0.34,1.56,0.64,1);
    }
    #ksim .ksim-action-arrow { opacity: 1; }
    #ksim .ksim-action-square { opacity: 0; transform: translate(-50%, -50%) scale(0.4) rotate(-90deg); }
    #ksim .ksim-glassbtn.is-stop .ksim-action-arrow { opacity: 0; transform: translate(-50%, -50%) scale(0.4) rotate(90deg); }
    #ksim .ksim-glassbtn.is-stop .ksim-action-square { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0deg); }

    /* real .ag-chat-activity: the breathing status line above the reply */
    /* The status line collapses instead of display-toggling: popping it in and
       out moved the reply a full row in one frame, which read as the reply
       jumping the moment its text appeared. The -10px margin when collapsed
       cancels the column's flex gap so the closed state truly costs 0px. */
    #ksim .ksim-activity {
      align-self: flex-start; display: inline-flex; align-items: center; gap: 8px;
      max-width: 85%; margin: 2px 0 0; font-size: 13px;
      color: rgba(255,255,255,0.62);
      max-height: 24px; overflow: hidden;
      transition: max-height 0.3s var(--ease-out-quint), opacity 0.22s ease,
                  margin-top 0.3s var(--ease-out-quint);
    }
    #ksim .ksim-activity-text { animation: ksimBreathe 2.8s ease-in-out infinite; }
    @keyframes ksimBreathe { 0%, 100% { opacity: 0.62; } 50% { opacity: 1; } }
    #ksim .ksim-activity.is-gone { max-height: 0; opacity: 0; margin-top: -10px; }
    #ksim .ksim-activity.is-gone .ksim-activity-text { animation-play-state: paused; }
    /* real .ag-chat-msg.assistant: no bubble, plain text, left aligned */
    #ksim .ksim-reply {
      align-self: flex-start; max-width: 85%;
      font-size: 14px; line-height: 1.55;
      color: rgba(255,255,255,0.9);
    }
    /* .ag-chat-compose textarea, verbatim apart from the 13px type the sim uses
       at this scale. height is written by composerFit on every character, the
       way agAutoResizeTextarea writes it on every keystroke. */
    #ksim .ksim-composer-text {
      width: 100%; min-height: 24px; height: 24px; max-height: 124px;
      padding: 2px 2px; border: 0; background: transparent;
      overflow-y: hidden; display: block;
      line-height: 1.4; resize: none; outline: 0;
      color: var(--text-primary, #fff);
      font: inherit; font-size: 13px;
      scrollbar-width: none;
    }
    /* FLIP moves these when the pill reflows; --kgrow keeps them on its clock.
       The text row's width snaps in one frame because a line break cannot be
       tweened, so it settles in over the same curve and the reflow reads as the
       field arriving rather than as a cut. */
    /* No will-change here. These sit inside the composer's backdrop-filter, and
       promoting them permanently made every stage re-composite the blurred
       layer each frame, which cost ~20fps across the whole simulator for two
       transforms that run three times per message. */
    #ksim .ksim-composer.is-reflow .ksim-input-row { animation: ksimRowSettle var(--kgrow) var(--ease-out-quint); }
    @keyframes ksimRowSettle { from { opacity: 0.35; } to { opacity: 1; } }
    #ksim .ksim-composer-text::-webkit-scrollbar { display: none; }
    #ksim .ksim-composer-text::placeholder { color: rgba(255,255,255,0.34); }
    /* real .ag-chat-effort-btn: word-label pill, same glass as the discs */
    /* real .ag-chat-effort-btn, as a bare word label. The glass fill belongs to
       the round discs either side of it; carrying it here as well gave the
       composer two competing pill shapes. */
    #ksim .ksim-effort {
      height: 36px; flex-shrink: 0;
      display: inline-flex; align-items: center; gap: 3px;
      padding: 0 6px 0 10px;
      border: 0;
      background: none;
      color: #f2f2f2;
      font-size: 12px; font-weight: 800; white-space: nowrap;
    }
    #ksim .ksim-effort svg { width: 13px; height: 13px; color: rgba(255,255,255,0.55); }

    /* ---- shared beat primitives ---- */
    #ksim .ksim-in { opacity: 0; }
    #ksim .ksim-live .ksim-in {
      animation: ksimIn 0.5s var(--ease-out-quint) forwards;
      animation-delay: var(--d, 0ms);
    }
    @keyframes ksimIn {
      from { opacity: 0; transform: translateY(10px) scale(0.988); filter: blur(5px); }
      to   { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
    }

    #ksim .ksim-empty {
      position: absolute; inset: 0;
      display: flex; align-items: center; justify-content: center;
      font-size: clamp(20px, 2.4vw, 27px); font-weight: 850;
      color: rgba(255,255,255,0.92);
      transition: opacity 0.4s ease, transform 0.4s var(--ease-out-expo);
    }
    #ksim .ksim-empty.is-gone { opacity: 0; transform: translateY(-8px); }

    #ksim .ksim-bubble {
      align-self: flex-end;
      max-width: 84%;
      padding: 9px 13px;
      border-radius: 16px;
      background: rgba(255,255,255,0.075);
      border: 1px solid rgba(255,255,255,0.06);
      color: rgba(255,255,255,0.94);
      font-size: 13px; line-height: 1.45;
      flex-shrink: 0;
    }

    #ksim .ksim-label {
      font-size: 10px; font-weight: 800; letter-spacing: 0.7px; text-transform: uppercase;
      color: var(--text-muted);
    }
    #ksim .ksim-label.is-gen { color: #ffbd2e; }
    #ksim .ksim-live .ksim-label.is-gen { animation: ksimPulse 1.3s ease-in-out infinite; }
    #ksim .ksim-label.is-done { color: #34d17a; animation: none; }
    /* Status words change with the page's blur crossfade (heroWord keyframes
       are document-global). Listed after the pulse/is-done rules so the morph
       owns the animation slot for its 0.2s/0.5s window. */
    #ksim .ksim-live .ksim-label.swap-out, #ksim .ksim-label.swap-out, #ksim .ksim-run-sub.swap-out { animation: heroWordOut 0.22s var(--ease-out-quint) forwards; }
    #ksim .ksim-live .ksim-label.swap-in, #ksim .ksim-label.swap-in, #ksim .ksim-run-sub.swap-in { animation: heroWordIn 0.5s var(--ease-out-quint); }
    @keyframes ksimPulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }

    #ksim .ksim-run {
      border: 1px solid rgba(255,255,255,0.07);
      border-radius: 14px;
      background: rgba(255,255,255,0.022);
      overflow: hidden;
      flex-shrink: 0;
    }
    #ksim .ksim-run-head { padding: 9px 12px 7px; }
    #ksim .ksim-run-sub { font-size: 11px; color: rgba(255,255,255,0.42); margin-top: 2px; }
    #ksim .ksim-grid3 {
      display: grid; grid-template-columns: repeat(3, 1fr);
      gap: 8px; padding: 0 12px 11px;
    }
    #ksim .ksim-tile {
      position: relative;
      aspect-ratio: 2 / 3;
      border-radius: 9px;
      overflow: hidden;
      background: rgba(255,255,255,0.045);
    }
    #ksim .ksim-tile img {
      width: 100%; height: 100%; object-fit: cover; display: block;
      opacity: 0;
    }
    /* The sweep rides on transform, not background-position. Stage 6 runs six
       of these at once and animating background-position repaints every tile
       every frame, which dropped that stage to ~40fps; a translate is handed to
       the compositor and costs nothing. The tile's own background supplies the
       flat fill, so the band only carries the highlight. */
    #ksim .ksim-tile::after {
      content: ""; position: absolute; inset: 0;
      background: linear-gradient(100deg, rgba(255,255,255,0) 35%, rgba(255,255,255,0.075) 50%, rgba(255,255,255,0) 65%);
      transform: translateX(-100%);
    }
    #ksim .ksim-live .ksim-tile.ksim-shimmer::after {
      animation: ksimShimmer 1.1s linear infinite;
    }
    #ksim .ksim-live .ksim-tile[style*="--r"]::after {
      animation: ksimShimmer 1.1s linear infinite, ksimSkelOut 0.32s var(--ease-glide) forwards;
      animation-delay: 0s, var(--r);
    }
    #ksim .ksim-live .ksim-tile[style*="--r"] img {
      animation: ksimTileIn 0.65s var(--ease-out-quint) forwards;
      animation-delay: var(--r);
    }
    @keyframes ksimShimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
    @keyframes ksimSkelOut { to { opacity: 0; } }
    @keyframes ksimTileIn {
      from { opacity: 0; transform: scale(1.045); filter: blur(7px); }
      to   { opacity: 1; transform: scale(1); filter: blur(0); }
    }

    /* a run card that has not started yet is not in the log at all */
    #ksim .ksim-run.is-hidden { display: none; }
    /* single-result run (the landscape regeneration) */

    #ksim .ksim-actions { display: flex; gap: 6px; padding: 0 12px 11px; }
    #ksim .ksim-act {
      display: inline-flex; align-items: center; gap: 6px;
      padding: 6px 11px; border-radius: 9px;
      border: 1px solid rgba(255,255,255,0.1);
      background: rgba(255,255,255,0.045);
      color: rgba(255,255,255,0.88);
      font-size: 12px; font-weight: 650;
    }
    #ksim .ksim-act svg { width: 12px; height: 12px; }
    #ksim .ksim-prow {
      display: flex; align-items: center; justify-content: space-between;
      padding: 9px 12px;
      border-top: 1px solid rgba(255,255,255,0.05);
      font-size: 10px; font-weight: 800; letter-spacing: 0.7px; text-transform: uppercase;
      color: rgba(255,255,255,0.38);
    }
    #ksim .ksim-prow svg { width: 12px; height: 12px; opacity: 0.5; }

    /* =================================================================
       stage 2 — the REAL in-chat control panels. These are the clones the
       agent appends via show_image_settings: .setting-group cards with the
       production model gallery and size grid (.ag-chat-control-clone).
       Values below are copied from worker.js verbatim.
       ================================================================= */
    #ksim .ksim-sg {
      width: min(100%, 460px); box-sizing: border-box;
      align-self: flex-start; flex-shrink: 0;
      background: #141414;
      border: 1px solid #2a2a2a;
      border-radius: 16px;
      padding: 16px;
      opacity: 0;
    }
    #ksim .ksim-live .ksim-sg {
      animation: ksimControlIn 0.34s cubic-bezier(0.22,1,0.36,1) forwards;
      animation-delay: var(--d, 0ms);
    }
    @keyframes ksimControlIn {
      from { opacity: 0; transform: translateY(8px) scale(0.985); }
      to   { opacity: 1; transform: translateY(0) scale(1); }
    }
    #ksim .ksim-ph { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 14px; }
    #ksim .ksim-ptitle { font-size: 14px; font-weight: 600; color: #888; text-transform: uppercase; letter-spacing: 0.5px; }
    #ksim .ksim-bmode { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 500; color: #888; }
    /* real .cm-toggle, checked state */
    #ksim .ksim-cm-toggle { position: relative; display: inline-block; width: 40px; height: 22px; flex-shrink: 0; }
    #ksim .ksim-cm-slider {
      position: absolute; inset: 0; border-radius: 22px;
      background: rgba(255,255,255,0.2); border: 1px solid #fff;
    }
    #ksim .ksim-cm-slider::before {
      content: ""; position: absolute; height: 16px; width: 16px; left: 2px; bottom: 2px;
      border-radius: 50%; background: #fff; transform: translateX(18px);
    }
    #ksim .ksim-help {
      width: 16px; height: 16px; border-radius: 50%; flex-shrink: 0;
      display: inline-flex; align-items: center; justify-content: center;
      border: 1px solid #2a2a2a; color: #555; font-size: 10px; font-weight: 700;
    }
    #ksim .ksim-credits {
      font-size: 11px; color: #ffbd2e; margin: 0 0 12px; line-height: 1.5;
      padding: 8px 12px; background: rgba(255,189,46,0.1);
      border: 1px solid rgba(255,189,46,0.2); border-radius: 8px;
    }
    #ksim .ksim-credits b { font-weight: 700; }
    #ksim .ksim-msearch { position: relative; display: flex; align-items: center; margin-bottom: 12px; }
    #ksim .ksim-msearch svg { position: absolute; left: 12px; width: 16px; height: 16px; color: #555; }
    #ksim .ksim-msearch-box {
      width: 100%; height: 40px; box-sizing: border-box;
      padding: 0 12px 0 36px;
      border: 1px solid #2a2a2a; border-radius: 10px; background: #1f1f1f;
      color: #555; font-size: 13px;
      display: flex; align-items: center;
    }
    /* real .model-gallery / .model-card (140px, 3/4 image, 3px select border) */
    #ksim .ksim-mgallery { overflow: hidden; padding: 4px 0; }
    #ksim .ksim-mtrack { display: flex; gap: 12px; transition: transform 0.9s cubic-bezier(0.22,1,0.36,1); }
    #ksim .ksim-mcard { flex-shrink: 0; width: 140px; }
    #ksim .ksim-mcard-img {
      width: 100%; aspect-ratio: 3 / 4;
      border-radius: 10px; background: #1f1f1f; margin-bottom: 10px;
      overflow: hidden; border: 3px solid transparent;
      transition: all 0.2s ease;
    }
    #ksim .ksim-mcard-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
    #ksim .ksim-mcard.selected .ksim-mcard-img { border-color: #fff; }
    #ksim .ksim-mcard.ksim-picked .ksim-mcard-img { animation: ksimSizePick 0.42s cubic-bezier(0.22,1,0.36,1); }
    #ksim .ksim-mcard-name {
      font-size: 12px; font-weight: 600; color: #fff; text-align: center;
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    @keyframes ksimSizePick { 0% { transform: scale(0.96); } 55% { transform: scale(1.035); } 100% { transform: scale(1); } }
    /* real .setting-row / .setting-label span / .size-grid — the size panel is
       the FULL production panel, so it is taller than the device screen and the
       chat column scrolls to it, exactly like the real log does */
    #ksim .ksim-srow + .ksim-srow { margin-top: 20px; padding-top: 20px; border-top: 1px solid #2a2a2a; }
    #ksim .ksim-slabel { font-size: 14px; font-weight: 500; color: #fff; }
    #ksim .ksim-size-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-top: 12px; }
    @media (min-width: 500px) { #ksim .ksim-size-grid { grid-template-columns: repeat(4, 1fr); } }
    /* real Resolution Scale block + range input (22px white thumb on a 6px track) */
    #ksim .ksim-resblock { margin-top: 14px; }
    #ksim .ksim-reshead { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
    #ksim .ksim-ressub { font-size: 12px; color: #888; }
    #ksim .ksim-resval { font-size: 12px; font-weight: 600; color: #fff; }
    #ksim .ksim-resticks { display: flex; justify-content: space-between; margin-top: 4px; }
    #ksim .ksim-resticks span { font-size: 10px; color: #555; }
    #ksim .ksim-range {
      -webkit-appearance: none; appearance: none;
      width: 100%; height: 6px; border-radius: 3px;
      background: #1f1f1f; pointer-events: none; opacity: 1;
    }
    #ksim .ksim-range::-webkit-slider-thumb {
      -webkit-appearance: none; appearance: none;
      width: 22px; height: 22px; border-radius: 50%;
      background: #fff; box-shadow: 0 2px 8px rgba(0,0,0,0.3);
    }
    #ksim .ksim-range::-moz-range-thumb {
      width: 22px; height: 22px; border-radius: 50%;
      background: #fff; border: none;
    }
    /* real .slider-with-input + .value-input */
    #ksim .ksim-slider-row { display: flex; align-items: center; gap: 16px; margin-top: 12px; }
    #ksim .ksim-slider-wrap { flex: 1; position: relative; display: block; }
    #ksim .ksim-value-input {
      width: 70px; box-sizing: border-box; padding: 10px 12px;
      border: 1px solid #2a2a2a; border-radius: 6px;
      font-size: 14px; font-weight: 600;
      background: #1f1f1f; color: #fff; text-align: center;
      font-variant-numeric: tabular-nums;
    }
    #ksim .ksim-size-opt {
      padding: 14px 12px; background: #1f1f1f;
      border: 2px solid transparent; border-radius: 10px;
      text-align: center; transition: all 0.2s ease;
    }
    #ksim .ksim-size-opt.selected { border-color: #fff; background: rgba(255,255,255,0.1); }
    #ksim .ksim-size-opt.ksim-picked { animation: ksimSizePick 0.42s cubic-bezier(0.22,1,0.36,1); }
    #ksim .ksim-size-name { font-size: 15px; font-weight: 600; color: #fff; margin-bottom: 4px; }
    #ksim .ksim-size-dims { font-size: 13px; color: #888; }
    #ksim .ksim-whrow { display: flex; gap: 16px; margin-top: 12px; align-items: center; }
    #ksim .ksim-wh { flex: 1; display: flex; align-items: center; gap: 10px; }
    #ksim .ksim-wh-k { font-size: 14px; font-weight: 600; color: #fff; }
    #ksim .ksim-wh-v {
      flex: 1; padding: 10px; box-sizing: border-box;
      border: 1px solid #2a2a2a; background: #1f1f1f; color: #fff;
      border-radius: 10px; font-weight: 600; text-align: center; font-size: 13px;
      font-variant-numeric: tabular-nums;
    }
    /* real .ag-qbq-btn row (Quality / Balance / Quantity) */
    #ksim .ksim-qbq-row { display: flex; gap: 6px; margin-top: 10px; }
    #ksim .ksim-qbq-btn {
      flex: 1; padding: 8px 4px;
      background: #1f1f1f; border: 2px solid transparent; border-radius: 8px;
      text-align: center; transition: all 0.2s ease;
      font-size: 12px; font-weight: 600; color: #fff;
    }
    #ksim .ksim-qbq-btn.selected { border-color: #fff; background: rgba(255,255,255,0.1); }
    #ksim .ksim-qbq-btn.ksim-picked { animation: ksimSizePick 0.42s cubic-bezier(0.22,1,0.36,1); }
    #ksim .ksim-qbq-sub { font-size: 10px; font-weight: 400; color: #555; display: block; margin-top: 2px; }
    #ksim .ksim-mp { font-size: 12px; color: #888; margin-top: 8px; }

    /* the agent narrates each settings change, like the real control results do */
    #ksim .ksim-setline {
      font-size: 12px; color: rgba(255,255,255,0.5);
      display: flex; align-items: center; gap: 7px; flex-shrink: 0;
    }
    #ksim .ksim-setline svg { width: 12px; height: 12px; color: #34d17a; flex-shrink: 0; }

    /* ---- stage 3: thinking + answer ---- */
    #ksim .ksim-think {
      border: 1px solid rgba(255,255,255,0.07);
      border-radius: 10px;
      padding: 8px 11px;
      flex-shrink: 0;
    }
    #ksim .ksim-think-head {
      display: flex; align-items: center; gap: 6px;
      font-size: 11px; font-weight: 650; color: rgba(255,255,255,0.66);
    }
    #ksim .ksim-think-head svg { width: 11px; height: 11px; opacity: 0.55; transition: transform 0.3s var(--ease-glide); }
    #ksim .ksim-think.is-closed .ksim-think-head svg { transform: rotate(-90deg); }
    #ksim .ksim-think-timer { margin-left: auto; font-size: 11px; color: rgba(255,255,255,0.35); font-family: var(--font-sf); }
    #ksim .ksim-think-collapse {
      display: grid; grid-template-rows: 1fr;
      transition: grid-template-rows 0.4s var(--ease-glide), opacity 0.3s ease;
    }
    #ksim .ksim-think.is-closed .ksim-think-collapse { grid-template-rows: 0fr; opacity: 0; }
    #ksim .ksim-think-body {
      font-size: 11px; line-height: 1.55; color: rgba(255,255,255,0.4);
      overflow: hidden; min-height: 0; padding-top: 6px;
    }
    #ksim .ksim-answer { font-size: 12px; line-height: 1.6; color: rgba(255,255,255,0.86); }
    #ksim .ksim-answer p { margin: 0 0 7px; }
    #ksim .ksim-answer p:last-child { margin-bottom: 0; }
    #ksim .ksim-answer b { color: #fff; font-weight: 750; }
    #ksim .ksim-answer .ksim-code {
      padding: 1px 5px; border-radius: 5px;
      background: rgba(255,255,255,0.075);
      color: rgba(255,255,255,0.94);
      font-family: var(--font-sf);
      font-size: 0.88em;
    }
    #ksim .ksim-alias { display: flex; align-items: center; gap: 7px; margin: 0 0 5px; }
    #ksim .ksim-alias svg { width: 11px; height: 11px; color: rgba(255,255,255,0.35); flex-shrink: 0; }

    /* =================================================================
       stage 4 — the REAL character card (.ag-card-panel anatomy):
       74px avatar head with JSON/PNG export buttons, tag chips with the
       spring pop, field rows, and the greetings carousel whose text is
       written live in the green Cline-style "added" hunk with a block
       caret — exactly how agCardStreamInto renders card creation.
       ================================================================= */
    #ksim .ksim-ccp {
      width: min(100%, 460px); box-sizing: border-box;
      align-self: flex-start; flex-shrink: 0;
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 18px;
      background: #131313;
      overflow: hidden;
      opacity: 0;
      --kspring: cubic-bezier(0.34,1.4,0.6,1);
    }
    #ksim .ksim-live .ksim-ccp {
      animation: ksimCardIn 0.6s var(--kspring) forwards;
      animation-delay: var(--d, 0ms);
    }
    @keyframes ksimCardIn {
      from { opacity: 0; transform: translateY(16px) scale(0.97); }
      to   { opacity: 1; transform: translateY(0) scale(1); }
    }
    #ksim .ksim-cc-head { display: flex; align-items: center; gap: 12px; padding: 14px 14px 12px; }
    #ksim .ksim-cc-avatar {
      width: 74px; height: 74px; flex: 0 0 auto;
      border-radius: 16px; overflow: hidden;
      background: #1d1d1d; border: 1px solid rgba(255,255,255,0.1);
    }
    #ksim .ksim-cc-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
    #ksim .ksim-cc-headmeta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
    #ksim .ksim-cc-kicker {
      font-size: 10px; font-weight: 800; letter-spacing: 0.7px; text-transform: uppercase;
      color: rgba(255,255,255,0.4);
    }
    #ksim .ksim-cc-name { font-size: 18px; font-weight: 750; color: #fff; padding: 2px 0 3px; min-height: 1.2em; }
    #ksim .ksim-cc-headbtns { flex: 0 0 auto; display: flex; flex-direction: column; gap: 6px; }
    #ksim .ksim-xbtn {
      min-width: 52px; height: 30px; box-sizing: border-box; padding: 0 10px;
      display: inline-flex; align-items: center; justify-content: center;
      border-radius: 9px; border: 1px solid rgba(255,255,255,0.14);
      color: rgba(255,255,255,0.85);
      font-size: 11px; font-weight: 800; letter-spacing: 0.4px;
    }
    #ksim .ksim-xbtn.solid { background: var(--bg-hover); color: var(--text-primary); border-color: var(--hairline-strong); }
    #ksim .ksim-cc-fields { border-top: 1px solid rgba(255,255,255,0.07); }
    #ksim .ksim-frow {
      display: flex; flex-direction: column; gap: 6px;
      padding: 11px 14px;
      border-bottom: 1px solid rgba(255,255,255,0.05);
    }
    #ksim .ksim-flabel {
      font-size: 10px; font-weight: 800; letter-spacing: 0.6px; text-transform: uppercase;
      color: rgba(255,255,255,0.42);
    }
    #ksim .ksim-fpre { font-size: 13px; line-height: 1.5; color: rgba(255,255,255,0.8); white-space: pre-wrap; word-break: break-word; }
    #ksim .ksim-cc-tags { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
    #ksim .ksim-cc-tag {
      display: inline-flex; align-items: center; gap: 3px;
      font-size: 11px; font-weight: 700; color: rgba(255,255,255,0.78);
      background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 999px; padding: 3px 5px 3px 9px;
      opacity: 0;
    }
    #ksim .ksim-cc-tag i { font-style: normal; color: rgba(255,255,255,0.4); font-size: 13px; line-height: 1; padding: 0 3px; }
    #ksim .ksim-live .ksim-cc-tag {
      animation: ksimTagPop 0.55s var(--kspring, cubic-bezier(0.34,1.56,0.64,1)) forwards;
      animation-delay: var(--d, 0ms);
    }
    @keyframes ksimTagPop {
      0% { opacity: 0; transform: scale(0.5) translateY(4px); }
      100% { opacity: 1; transform: scale(1) translateY(0); }
    }
    /* real .ag-card-greets section */
    #ksim .ksim-greets { padding: 12px 14px 4px; }
    #ksim .ksim-greetstop { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
    #ksim .ksim-greetcount { font-size: 11px; font-weight: 700; color: rgba(255,255,255,0.45); font-variant-numeric: tabular-nums; }
    #ksim .ksim-greet-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 2px; }
    #ksim .ksim-greeticon {
      width: 26px; height: 26px; border-radius: 7px;
      display: inline-flex; align-items: center; justify-content: center;
      color: rgba(255,255,255,0.42);
    }
    #ksim .ksim-greeticon svg { width: 14px; height: 14px; }
    /* real carousel: side arrows + clipped viewport + sliding track */
    #ksim .ksim-carousel { position: relative; display: flex; align-items: stretch; gap: 2px; }
    #ksim .ksim-carr {
      flex: 0 0 auto; width: 24px;
      display: flex; align-items: center; justify-content: center;
      color: rgba(255,255,255,0.35);
    }
    #ksim .ksim-carr svg { width: 14px; height: 14px; }
    #ksim .ksim-viewport { flex: 1; min-width: 0; overflow: hidden; border-radius: 10px; }
    /* align-items:flex-start — otherwise every slide stretches to the tallest
       one and the green hunk paints a huge empty block under short greetings */
    #ksim .ksim-track { display: flex; width: 100%; align-items: flex-start; transition: transform 0.5s cubic-bezier(0.22,1,0.36,1); }
    #ksim .ksim-slide { flex: 0 0 100%; min-width: 0; padding: 0 2px 4px; box-sizing: border-box; }
    #ksim .ksim-greetview { font-size: 13px; line-height: 1.62; color: rgba(255,255,255,0.9); }
    #ksim .ksim-greetview p { margin: 0 0 9px; }
    #ksim .ksim-greetview p:last-child { margin-bottom: 0; }
    #ksim .ksim-nar { color: rgba(255,255,255,0.55); font-style: italic; }
    /* real .ag-card-stream-imgchip: the inline ref chip while streaming */
    /* In flow from the start, revealed by opacity only: display-toggling it
       added a ~20px line between the quote and the image on every greeting. */
    #ksim .ksim-imgchip {
      display: inline-block;
      visibility: hidden; opacity: 0;
      transition: opacity 0.18s ease;
      font-size: 10px; color: rgba(255,255,255,0.5);
      background: rgba(255,255,255,0.08);
      border-radius: 5px; padding: 1px 6px; margin: 0 2px;
      vertical-align: middle; font-family: var(--font-sf);
    }
    #ksim .ksim-imgchip.is-on { visibility: visible; opacity: 1; }
    /* real .ag-card-greet-img — the image does not exist until the ref resolves,
       so it must not reserve space before it lands */
    /* The slot holds its layout space from the moment the slide exists —
       toggling display flushed a ~200px image into the flow in one frame and
       threw the pager dots down the card. Only the pixels arrive on .is-in. */
    #ksim .ksim-greet-img { margin: 9px 0 4px; opacity: 0; }
    #ksim .ksim-greet-img img { max-width: 100%; max-height: 200px; border-radius: 10px; display: block; }
    #ksim .ksim-greet-img.is-in { animation: ksimGreetDrop 0.7s var(--ease-out-quint) forwards; }
    @keyframes ksimGreetDrop {
      from { opacity: 0; transform: translateY(-14px) scale(0.92); filter: blur(6px); }
      to   { opacity: 1; transform: none; filter: blur(0); }
    }
    /* real .ag-card-dots */
    #ksim .ksim-gdots { display: flex; justify-content: center; gap: 6px; margin-top: 10px; }
    #ksim .ksim-gdot {
      width: 6px; height: 6px; border-radius: 999px;
      background: rgba(255,255,255,0.2);
      transition: background 0.18s ease, transform 0.18s ease;
    }
    #ksim .ksim-gdot.active { background: rgba(255,255,255,0.9); transform: scale(1.2); }
    /* real .ag-card-foot + .ag-card-gallerylink */
    #ksim .ksim-cc-foot {
      display: flex; align-items: center; justify-content: space-between; gap: 10px;
      min-height: 30px; padding: 4px 14px 12px;
    }
    #ksim .ksim-cc-status { font-size: 11px; color: rgba(255,255,255,0.5); opacity: 0; transition: opacity 0.2s ease; }
    #ksim .ksim-cc-status.visible { opacity: 1; }
    #ksim .ksim-gallerylink {
      font-size: 11px; font-weight: 700; color: rgba(255,255,255,0.6);
      border-bottom: 1px solid rgba(255,255,255,0.2);
      margin-left: auto;
    }

    /* tail room below the last step so the sticky device stays fully in view
       while the last step sits at the pivot (spacer is outside the step, so it does
       not skew the step's center for the stage computation) */
    #ksim .fsim-steps::after { content: ""; display: block; height: 34vh; }

    /* ---- stage 6: parallel runs ---- */
    /* two stacked run cards must share the log height: shorter tiles */
    #ksim .fsim-layer[data-stage="5"] .ksim-tile { aspect-ratio: 3 / 4; }
    #ksim .ksim-run.is-queued { opacity: 0.7; }
    #ksim .ksim-run.is-queued .ksim-tile::after { animation: none; }
    #ksim .ksim-run.is-started { opacity: 1; transition: opacity 0.4s ease; }
    /* A queued run has not been dispatched yet, so its results must stay dark and
       its --r reveal must not start counting until the run actually begins. Both
       animations are therefore re-declared on .is-started, which restarts them
       from the moment the queue releases the run -- so --r on a queued run's tile
       is measured from that run's own start, not from stage entry. */
    #ksim .ksim-live .ksim-run.is-queued .ksim-tile[style*="--r"] img { animation: none; opacity: 0; }
    #ksim .ksim-live .ksim-run.is-started .ksim-tile[style*="--r"] img {
      animation: ksimTileIn 0.65s var(--ease-out-quint) forwards;
      animation-delay: var(--r);
    }
    #ksim .ksim-live .ksim-run.is-started .ksim-tile[style*="--r"]::after {
      animation: ksimShimmer 1.1s linear infinite, ksimSkelOut 0.32s var(--ease-glide) forwards;
      animation-delay: 0s, var(--r);
    }
    /* placeholder tiles with no result keep shimmering for as long as the run runs */
    #ksim .ksim-live .ksim-run.is-started .ksim-tile.ksim-shimmer:not([style*="--r"])::after { animation: ksimShimmer 1.1s linear infinite; }

    /* ---- responsive ---- */
    @media (max-width: 700px) {
      #ksim .ksim-hamburger { display: inline-flex; }
      #ksim .fsim-layer { padding: 10px 12px; }
      #ksim .ksim-composer { margin: 6px 10px 10px; }
      /* on mobile the real composer has no effort pill — the reasoning-effort
         picker moves inside the agent model menu (see ag-agent-model-effort-toggle) */
      #ksim .ksim-effort { display: none; }
      #ksim .ksim-sg { padding: 16px; }
      #ksim .ksim-size-opt { padding: 10px 8px; }
      #ksim .ksim-credits { display: none; }
      #ksim .ksim-cc-avatar { width: 58px; height: 58px; }
      #ksim .ksim-cc-headbtns { display: none; }
      #ksim .ksim-answer .ksim-p2 { display: none; }
      #ksim .ksim-greet-img img { max-height: 180px; }
      /* Three across survives phone width: it is ~100px per image here, wider
         than the old four-across strip, so the batch stays on one row and stays
         big enough to actually judge. No orphan row either, which is what
         dropping to two columns would produce with three tiles. */
      #ksim .ksim-grid3 { grid-template-columns: repeat(3, 1fr); gap: 7px; }
      /* Stage 6 is about two runs going at once, so both cards have to stay
         visible: square tiles keep each run card short enough to fit. */
      #ksim .fsim-layer[data-stage="5"] .ksim-tile { aspect-ratio: 1 / 1; }
    }

    /* Phone: the shared .fsim-screen falls back to its 480px min-height here
       (every stage layer is absolutely positioned, so the screen has no
       natural height), which left the device floating above a tall band of
       empty page. Size it from the viewport instead and trim the side gutters
       so the K Agent UI inside is actually legible. */
    /* Screen height is viewport-derived in the shared .fsim-screen rules, so
       #fsim and #ksim stay in step. Only the gutters differ here. */
    /* Gutters and screen height now come from the shared .fsim-* rules so
       both simulators stay in step. */

    /* Below this the controls cannot sit beside the text even with the field
       empty, so `flex-flow: row wrap` already puts them on their own line and
       the first character would reflow the pill and shrink it by a few px.
       Pin the two-row form instead: nothing moves when typing starts. */
    @media (max-width: 360px) {
      #ksim .ksim-composer { align-items: flex-end; }
      #ksim .ksim-input-row { order: 1; flex-basis: 100%; padding: 4px 6px 2px; }
      #ksim .ksim-plus { order: 2; }
      #ksim .ksim-controls-right { order: 3; margin-left: auto; }
    }

    /* ---- reduced motion: everything lands settled ---- */
    @media (prefers-reduced-motion: reduce) {
      #ksim .ksim-in, #ksim .ksim-sg, #ksim .ksim-ccp, #ksim .ksim-cc-tag,
      #ksim .ksim-greet-img { opacity: 1 !important; animation: none !important; transform: none !important; filter: none !important; }
      #ksim .ksim-tile img { opacity: 1 !important; animation: none !important; }
      #ksim .ksim-tile::after { display: none !important; }
      #ksim .ksim-track { transition: none !important; }
      #ksim .ksim-mtrack { transition: none !important; }
      #ksim .ksim-chatflow { transition: none !important; }
      #ksim .ksim-composer, #ksim .ksim-plus, #ksim .ksim-controls-right,
      #ksim .ksim-input-row { transition: none !important; animation: none !important; }
      #ksim .ksim-label.is-gen { animation: none !important; }
      #ksim .ksim-imgchip { display: none !important; }
      #ksim .ksim-empty { display: none !important; }
    }
  

    /* ================================================================
       ONE SF TYPOGRAPHY SYSTEM
       Apple exposes SF Pro to websites through the platform system font.
       Every landing-page surface—including the product simulations—uses
       this same family. Hierarchy comes from optical size, weight, leading,
       tracking and color, never by changing typeface.
       ================================================================ */
    html,
    body,
    button,
    input,
    textarea,
    select,
    option {
      font-family: var(--font-sf);
      font-optical-sizing: auto;
      font-kerning: normal;
    }
    code,
    pre,
    kbd,
    samp {
      font-family: inherit;
    }
    body {
      font-size: var(--type-body);
      line-height: 1.47;
      letter-spacing: 0;
    }

    /* Marketing display hierarchy: fluid display type, stable body type. */
    .hero h1,
    .files-hero-title {
      font-size: var(--type-hero);
      font-weight: 700;
      line-height: 1.05;
      letter-spacing: var(--track-hero);
    }
    .sec h2,
    .final-cta h2,
    .files-payoff-title,
    #ksim .ksim-head h2 {
      font-size: var(--type-section);
      font-weight: 700;
      line-height: 1.08;
      letter-spacing: var(--track-section);
    }
    .ag-show-text h2,
    .fsim-step h2 {
      font-size: var(--type-feature);
      font-weight: 700;
      line-height: 1.1;
      letter-spacing: var(--track-feature);
    }
    .hero-sub,
    .files-hero-sub {
      font-size: var(--type-title);
      font-weight: 400;
      line-height: 1.47;
      letter-spacing: var(--track-title);
    }
    .sec-sub,
    .ag-show-text p,
    #ksim .ksim-head p,
    .fsim-step > p,
    .final-cta p {
      font-size: var(--type-body);
      font-weight: 400;
      line-height: 1.47;
      letter-spacing: 0;
    }

    /* Cards follow Apple's headline/body pairing instead of inventing a
       different miniature type scale for every component family. */
    .step h3,
    .feat h3,
    .featnum h3,
    .platform-card h3,
    .workflow-step h3,
    .usecase-card h3,
    .toolkit-card h3 {
      font-size: var(--type-body);
      font-weight: 600;
      line-height: 1.3;
      letter-spacing: var(--track-title);
    }
    .rp-card-head h3,
    .hq-card h3,
    .why-card h3 {
      font-size: var(--type-title);
      font-weight: 600;
      line-height: 1.25;
      letter-spacing: var(--track-title);
    }
    .step p,
    .feat p,
    .featnum p,
    .platform-card p,
    .workflow-step p,
    .usecase-card p,
    .toolkit-card-desc,
    .rp-card-sub,
    .why-card-sub {
      font-size: var(--type-subhead);
      font-weight: 400;
      line-height: 1.47;
      letter-spacing: 0;
    }
    .ag-feat-list li,
    .rp-card-list li,
    .hq-card-list li {
      font-size: var(--type-subhead);
      line-height: 1.47;
    }

    /* Actions and navigation use SF Text proportions and semibold emphasis. */
    .cta-primary,
    .cta-secondary {
      font-size: var(--type-body);
      font-weight: 600;
      line-height: 1.235;
      letter-spacing: 0;
    }
    /* The fill no longer ranks the two, so the label does. */
    .cta-primary {
      font-weight: 700;
    }
    .nav-links a {
      font-size: 14px;
      font-weight: 400;
      letter-spacing: 0;
    }
    .nav-cta,
    .svc-btn {
      font-weight: 600;
      letter-spacing: 0;
    }
    .faq-q {
      font-size: var(--type-body);
      font-weight: 600;
      line-height: 1.3;
      letter-spacing: var(--track-title);
    }
    .faq-a {
      font-size: var(--type-subhead);
      line-height: 1.47;
    }

    /* Pricing and quantitative claims: proportional SF numerals with
       confident weights—no thin display numerals or shouty all-caps names. */
    .stat .num,
    .odo,
    .featnum-n,
    .why-num,
    .price-cost .amount {
      font-weight: 700;
      letter-spacing: -0.025em;
    }
    .stat .lbl,
    .live-lbl {
      font-size: var(--type-caption);
      font-weight: 600;
      letter-spacing: 0.02em;
      text-transform: none;
    }
    .price-name {
      font-size: var(--type-subhead);
      font-weight: 600;
      letter-spacing: 0;
      text-transform: none;
    }
    .price.featured::before,
    .feat-tag {
      font-size: 11px;
      font-weight: 600;
      letter-spacing: 0.02em;
    }
    .price-gens {
      font-size: var(--type-subhead);
      font-weight: 600;
    }
    .price-worth,
    .price ul li {
      font-size: var(--type-footnote);
      line-height: 1.47;
    }
    .price-cta {
      font-size: var(--type-subhead);
      font-weight: 600;
      letter-spacing: 0;
    }

    .files-scroll-cue {
      font-size: var(--type-caption);
      font-weight: 600;
      letter-spacing: 0.04em;
    }
    .fsim-meta-copy {
      font-size: 11px;
      font-weight: 600;
    }
    footer {
      font-size: var(--type-caption);
      line-height: 1.4;
      letter-spacing: 0;
    }

    @media (max-width: 480px) {
      :root {
        --type-hero: 48px;
        --type-section: 40px;
        --type-feature: 32px;
      }
      .hero-sub,
      .files-hero-sub {
        font-size: var(--type-body);
        letter-spacing: 0;
      }
    }
  