/* API Studio product drawer: fixed-viewport story layout. */

body.products-open .signal-drawer-tab,
body.products-open .side-rail {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

/* The flyout is sized by its CONTENT, not by the viewport.

   It used to span top:80px → bottom:60px and centre one card inside that, which
   left a column of empty gradient above and below the only product. It now
   hangs off the Products rail item like a menu off its trigger: height grows
   with the list, capped so a long list scrolls inside instead of running off
   the screen.

   `top` is the fallback only — positionProductsFlyout() in app.js measures the
   rail item on open and lines the panel up with it, because the rail is
   centred on the viewport and its item offsets move with its own height. */
.products-flyout {
    position: fixed;
    top: 96px;
    right: 108px;
    z-index: 155;
    display: flex;
    width: min(304px, calc(100% - 144px));
    max-height: min(600px, calc(100vh - 128px));
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateX(14px);
    transition: opacity 180ms ease, transform 260ms cubic-bezier(0.16, 1, 0.3, 1), visibility 180ms ease;
}

.products-flyout.open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateX(0);
}

/* Frosted brand glass — the same material as the side rail it hangs off
   (.rail-body in home.css), so the popover reads as an extension of the rail
   rather than a second, unrelated surface.

   What made the previous ramp too bright was that it was OPAQUE: it painted its
   own saturated indigo→teal light instead of borrowing the page's. This one is
   translucent, so the dimming comes from letting the page's wash through under
   a heavy blur/saturate pass rather than from adding darkness. The brand hues
   stay as low-alpha tint and corner glows — light, not dark, and no longer a
   lit block against the hero. */
.products-flyout-panel {
    box-sizing: border-box;
    width: 100%;
    min-height: 0;
    padding: 16px 16px 14px;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    color: var(--white);
    text-align: left;
    border: 1px solid rgba(255, 255, 255, 0.24);
    border-radius: 20px;
    background:
        radial-gradient(120% 86% at 0% 0%, rgba(167, 139, 250, 0.3), transparent 60%),
        radial-gradient(118% 92% at 100% 104%, rgba(94, 234, 212, 0.24), transparent 62%),
        linear-gradient(168deg, rgba(124, 58, 237, 0.26) 0%, rgba(56, 105, 159, 0.2) 52%, rgba(13, 148, 136, 0.22) 100%);
    backdrop-filter: blur(24px) saturate(160%);
    -webkit-backdrop-filter: blur(24px) saturate(160%);
    box-shadow: 0 30px 72px rgba(6, 10, 40, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.26);
    overflow: hidden;
}

/* Rows size to their card. The old fixed 204px row was what clipped the CTA
   off the bottom of the only product on the list. */
.products-flyout-list {
    min-height: 0;
    padding: 12px 2px 2px 0;
    display: grid;
    grid-auto-rows: auto;
    align-content: start;
    gap: 10px;
    overflow-y: auto;
    overscroll-behavior: contain;
    scroll-padding-block: 2px;
    scroll-snap-type: y proximity;
    scrollbar-color: rgba(157, 246, 226, 0.46) transparent;
    scrollbar-width: thin;
}

.products-flyout-list::-webkit-scrollbar { width: 5px; }
.products-flyout-list::-webkit-scrollbar-track { background: transparent; }
.products-flyout-list::-webkit-scrollbar-thumb { border-radius: 999px; background: rgba(157, 246, 226, 0.42); }

.products-flyout-item {
    min-height: 0;
    scroll-snap-align: start;
}

/* .block-caselet's geometry with its fill INVERTED — deep instead of white.
   The design system's white glass is written for cards sitting inline on the
   page; inside a lit panel it just bleaches it, and panel and tile converge
   until the type sits at ~3.7:1. A deep translucent navy lets the brand tint
   stay vivid AROUND the tile while the tile itself goes quiet enough for white
   type to ring (~7:1). The bright hairline and the accent spine keep it reading
   as glass rather than a hole. */
.products-flyout-card {
    position: relative;
    box-sizing: border-box;
    width: 100%;
    /* Extra left pad clears the accent spine below. */
    padding: 16px 16px 15px 20px;
    display: block;
    overflow: hidden;
    color: var(--white);
    border: 1px solid rgba(255, 255, 255, 0.26);
    border-radius: 16px;
    background: linear-gradient(180deg, rgba(10, 24, 62, 0.28), rgba(8, 20, 52, 0.22));
    box-shadow: 0 16px 38px rgba(4, 8, 30, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.18);
    cursor: pointer;
    font: inherit;
    text-align: left;
    transition: transform 180ms cubic-bezier(0.16, 1, 0.3, 1), border-color 180ms ease, background 180ms ease, box-shadow 180ms ease;
}

/* Light stops, not --purple/--teal: the dark ones vanish against the gradient. */
.products-flyout-card::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: linear-gradient(180deg, var(--purple-light), var(--teal-light));
}

/* Hover LIFTS by letting the lit panel back through the tile, not by adding
   white — the mint edge picks up the CTA's colour. */
.products-flyout-card:hover,
.products-flyout-card:focus-visible {
    border-color: rgba(157, 246, 226, 0.66);
    background: linear-gradient(180deg, rgba(10, 24, 62, 0.18), rgba(8, 20, 52, 0.13));
    box-shadow: 0 22px 50px rgba(4, 8, 30, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.24);
    outline: none;
    transform: translateY(-2px);
}

.products-flyout-top,
.products-flyout-body,
.products-flyout-head,
.products-flyout-pills { display: flex; }

.products-flyout-top {
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding-bottom: 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}

/* An eyebrow, not a heading — the design system's label hierarchy: lavender so
   it reads as a label by HUE rather than by being dimmed into invisibility. */
.products-flyout-title {
    color: rgba(199, 182, 255, 0.9);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

/* The design system's .close-btn, at the size this compact header can carry:
   white-glass circle, hover fills and rotates 90°. */
.products-flyout-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 28px;
    height: 28px;
    padding: 0;
    color: var(--white);
    border: 1px solid rgba(255, 255, 255, 0.24);
    border-radius: 99px;
    background: rgba(255, 255, 255, 0.14);
    font: inherit;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: background var(--transition), transform var(--transition);
}

.products-flyout-close:hover,
.products-flyout-close:focus-visible {
    background: rgba(255, 255, 255, 0.24);
    outline: none;
    transform: rotate(90deg);
}

.products-flyout-body {
    flex-direction: column;
    gap: 10px;
}

/* Name and availability share the top line; the chip drops below it only if
   the name is long enough to need the whole width. */
.products-flyout-head {
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

/* The system's display step: Inter 800 at -0.02em, with the soft shadow every
   headline on the gradient carries. */
.products-flyout-head h2 {
    margin: 0;
    color: var(--white);
    font-size: 22px;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1;
    text-shadow: 0 1px 2px rgba(15, 10, 30, 0.4);
}

/* Body sits at white 85% — the system's body tint on branded surfaces. */
.products-flyout-sub {
    margin: -2px 0 0;
    color: rgba(255, 255, 255, 0.85);
    font-size: 12px;
    font-weight: 400;
    line-height: 1.45;
}

.products-flyout-badge,
.product-status-pill {
    display: inline-flex;
    align-items: center;
    width: fit-content;
    padding: 4px 7px;
    color: #f4efff;
    border: 1px solid rgba(226, 212, 255, 0.42);
    border-radius: 999px;
    background: rgba(124, 58, 237, 0.48);
    font-size: 9px;
    font-weight: 900;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* Availability is a status, so it takes the luminous mint the design system
   reserves for vocabulary — purple here would collide with the panel head. */
.products-flyout-badge {
    gap: 5px;
    color: #b6fced;
    border-color: rgba(157, 246, 226, 0.55);
    background: rgba(13, 148, 136, 0.5);
}

/* A lit dot makes "available" a state you can see before you read it. Scoped to
   the flyout badge only — .product-status-pill shares the rule above but sits
   in the overlay beside a kicker, where a second mark would just be noise. */
.products-flyout-badge::before {
    content: '';
    flex: none;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #6ee7d5;
    box-shadow: 0 0 0 2px rgba(110, 231, 213, 0.2), 0 0 6px rgba(110, 231, 213, 0.55);
}

/* The promise is two states and the move between them, so it is drawn as two
   pills with the arrow in the gap — not as a bordered box containing three
   things. Dropping the container also removes a rectangle that was competing
   with the tile's own edge one step outside it.

   wrap is the safety net, not the layout: both pills fit the tile's width at
   this size, but a longer product name should stack rather than overflow. */
.products-flyout-flow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 0;
    border: 0;
    background: none;
}

/* The two ends of the flow are vocabulary, so they take the luminous mint the
   design system gives terms — and they carry a tinted fill, which is what
   separates them from the plain attribute pills below. */
.products-flyout-flow span {
    padding: 6px 11px;
    border: 1px solid rgba(157, 246, 226, 0.38);
    border-radius: 999px;
    background: linear-gradient(180deg, rgba(45, 212, 191, 0.26), rgba(13, 148, 136, 0.14));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 4px 12px rgba(4, 8, 30, 0.22);
    color: #ccfbef;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1.2;
    white-space: nowrap;
}

/* The arrow travels on hover, the same idiom as the CTA's widening gap. */
.products-flyout-flow i {
    color: rgba(157, 246, 226, 0.82);
    font-size: 13px;
    font-style: normal;
    transition: transform 0.22s ease;
}

.products-flyout-card:hover .products-flyout-flow i,
.products-flyout-card:focus-visible .products-flyout-flow i { transform: translateX(2px); }

/* Attributes are the quiet tier: no fill tint, no mint — plain white glass, so
   the eye reads flow first and detail second.

   The extra top margin breaks the body's even 10px rhythm on purpose: at the
   even gap the four pills stacked into one undifferentiated block, and the
   flow stopped reading as its own statement. The pause is what separates the
   promise from the detail supporting it. */
.products-flyout-pills { flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.products-flyout-pills span { padding: 4px 9px; border: 1px solid rgba(255, 255, 255, 0.15); border-radius: 999px; background: rgba(255, 255, 255, 0.06); color: rgba(255, 255, 255, 0.72); font-size: 9px; font-weight: 600; letter-spacing: 0.03em; }

/* The gap grows on hover — the .btn-secondary arrow idiom. */
.products-flyout-cta {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 2px;
    color: #9df6e2;
    font-size: 12px;
    font-weight: 800;
    transition: gap 0.22s ease;
}

.products-flyout-cta i { font-style: normal; }
.products-flyout-card:hover .products-flyout-cta,
.products-flyout-card:focus-visible .products-flyout-cta { gap: 11px; }

/* This used to hide below 1664px so the flyout could never touch the hero. That
   gate was far too high: a 1920px screen at Windows' default 125% scaling is
   only ~1536 CSS px, so the panel silently never appeared on the most common
   desktop setup there is. It is a hover popover anchored to the rail — briefly
   overlapping the hero's right edge is what popovers do, and the panel is
   opaque with its own shadow, so it reads cleanly over whatever is beneath.

   It now hides only where the right rail itself gets cramped. Phones drop it
   together with .side-rail at 768px (home.css). */
@media (max-width: 1023px) {
    .products-flyout { display: none; }
}

/* ── PHONES: the same panel, driven as a bottom sheet ──────────────────────
   Below 768px there is no rail, so there is nothing for a popover to hang off
   — and jumping the drawer's "Products" straight into one product's full-screen
   story skipped the list entirely, so a second product would have had nowhere
   to appear. The panel comes back here as the sheet that list belongs in:
   full-width, anchored to the bottom edge where a thumb already is, over its
   own scrim, with the card inside it opening the story.

   The desktop geometry above (fixed 304px hanging top/right, `top` measured
   from the rail by app.js) is fully replaced; positionProductsFlyout() clears
   its inline `top` below this same breakpoint rather than fighting it here. */
@media (max-width: 768px) {
    .products-flyout {
        display: flex;
        align-items: flex-end;
        inset: 0;
        /* Beats the fallback top:96px; the inline one is cleared by app.js. */
        top: 0;
        width: auto;
        max-height: none;
        background: rgba(6, 8, 18, 0.62);
        backdrop-filter: blur(4px);
        -webkit-backdrop-filter: blur(4px);
        /* The scrim fades, the panel slides — so the transform below is the
           panel's own, not a leftover sideways nudge from the popover. */
        transform: none;
        transition: opacity 200ms ease, visibility 200ms ease;
    }

    .products-flyout.open {
        transform: none;
    }

    .products-flyout-panel {
        max-height: 86vh;
        /* Room for the grabber above the header row. */
        grid-template-rows: auto auto minmax(0, 1fr);
        padding: 10px 14px calc(16px + env(safe-area-inset-bottom, 0px));
        border-width: 1px 0 0;
        border-radius: 22px 22px 0 0;
        /* The desktop panel is deliberately thin glass — it hovers over the hero
           and is meant to borrow its light. A sheet sits ON the page, and at
           that alpha the hero's headline read straight through the eyebrow. The
           brand tint and corner glows are unchanged; only the base goes solid. */
        background:
            radial-gradient(120% 86% at 0% 0%, rgba(167, 139, 250, 0.34), transparent 60%),
            radial-gradient(118% 92% at 100% 104%, rgba(94, 234, 212, 0.26), transparent 62%),
            linear-gradient(168deg, rgba(45, 26, 92, 0.94) 0%, rgba(26, 44, 88, 0.93) 52%, rgba(10, 56, 62, 0.94) 100%);
        transform: translateY(101%);
        transition: transform 380ms cubic-bezier(0.22, 1, 0.36, 1);
    }

    .products-flyout.open .products-flyout-panel {
        transform: translateY(0);
    }

    /* The grabber: this reads as a sheet you pull up, not a box that appeared. */
    .products-flyout-panel::before {
        content: '';
        justify-self: center;
        width: 38px;
        height: 4px;
        margin-bottom: 12px;
        border-radius: 99px;
        background: rgba(255, 255, 255, 0.36);
    }

    /* A thumb needs the bigger target the compact header could not carry. */
    .products-flyout-close {
        width: 34px;
        height: 34px;
        font-size: 20px;
    }

    .products-flyout-list {
        padding: 12px 0 2px;
    }

    /* One product fills the width, so the card can breathe rather than staying
       at popover density. */
    .products-flyout-card {
        padding: 18px 16px 17px 22px;
    }

    .products-flyout-head h2 {
        font-size: 24px;
    }

    .products-flyout-sub {
        font-size: 13px;
    }

    .products-flyout-flow {
        justify-content: flex-start;
    }

    .products-flyout-cta {
        margin-top: 6px;
        font-size: 13px;
    }
}

/* The sheet is modal, so the page behind it holds still (app.js sets this on
   phones only — on desktop the same panel opens on a passing hover). */
body.products-sheet-open {
    overflow: hidden;
}

/* ══════════════════════════════════════════════════════════════════════════
   API STUDIO OVERLAY

   The overlay is deliberately ONE LOCKED SCREEN — the stage never scrolls, so
   the whole product story is taken in at a glance. That constraint used to be
   paid for in type: the old scale bottomed out at 5-6px and hid body copy
   outright below 720px, which is unreadable on any device.

   It is paid for in DENSITY here instead. One fluid unit (--api-u) is keyed to
   whichever axis is scarcer, so a short or narrow window scales the entire
   composition down together rather than letting one band crush the rest; every
   type step is a clamp off that unit with a legible FLOOR (11px body, 10px
   uppercase eyebrows — nothing on this surface is allowed below that). Where
   the floor plus the content genuinely cannot fit, the individual panel scrolls
   inside its own card — the page stays locked, but nothing is ever clipped.
   ══════════════════════════════════════════════════════════════════════════ */

.products-overlay {
    --api-line: rgba(255, 255, 255, 0.16);
    --api-line-strong: rgba(196, 253, 243, 0.42);
    --api-surface: rgba(255, 255, 255, 0.075);
    --api-surface-strong: rgba(255, 255, 255, 0.14);
    --api-copy: rgba(255, 255, 255, 0.84);
    --api-muted: rgba(255, 255, 255, 0.6);
    --api-accent: #9df6e2;
    --api-violet: #b586ff;
    --api-problem: #fecaca;
    --api-shadow: rgba(4, 8, 28, 0.26);

    /* min(), not a single axis: 1vw alone lets a 1440x620 laptop overflow, and
       1vh alone starves a wide-but-short window of horizontal type. */
    --api-u: min(1vw, 1.72vh);

    --api-gap: clamp(8px, calc(var(--api-u) * 0.95), 16px);
    --api-pad: clamp(12px, calc(var(--api-u) * 1.3), 24px);
    --api-radius: clamp(12px, calc(var(--api-u) * 1.3), 20px);
    --api-radius-sm: clamp(8px, calc(var(--api-u) * 0.85), 13px);

    --api-fs-eyebrow: clamp(10px, calc(var(--api-u) * 0.72), 12px);
    --api-fs-micro: clamp(11px, calc(var(--api-u) * 0.82), 13px);
    --api-fs-body: clamp(11px, calc(var(--api-u) * 0.93), 14px);
    --api-fs-lead: clamp(12px, calc(var(--api-u) * 1.06), 17px);
    --api-fs-title: clamp(15px, calc(var(--api-u) * 1.5), 24px);
    --api-fs-display: clamp(18px, calc(var(--api-u) * 1.9), 30px);

    z-index: 205;
    color: var(--white);
}

/* [hidden] companions — see test/lane1-logic/hidden-attribute.test.js. An
   author `display` beats the user agent's `[hidden] { display: none }`, so every
   container here that declares one needs its own guard or the attribute
   silently stops working.
   This is exactly what made three of the four explorer tabs look dead:
   .capabilities, .impact and .audience each carried a guard, .workflow did not.
   Its `display: grid` won, so it never hid — and the panel the visitor asked
   for rendered underneath it, out of sight inside an overflow:hidden stage.
   Kept as one list rather than scattered next to each rule, so adding a panel
   means adding a line here. */
.workflow[hidden],
.capabilities[hidden],
.impact[hidden],
.audience[hidden],
.product-feedback-card[hidden],
.product-feedback-form[hidden],
.product-actions[hidden],
.product-perspective[hidden],
.product-known-note[hidden],
.product-field[hidden],
.product-held-email[hidden],
.product-success[hidden] { display: none; }

.products-overlay .products-panel {
    position: absolute;
    inset: 0;
    overflow: hidden;
    border-radius: 0;
    background:
        radial-gradient(circle at 8% 0, rgba(182, 148, 255, 0.3), transparent 28%),
        radial-gradient(circle at 92% 12%, rgba(65, 231, 208, 0.22), transparent 28%),
        linear-gradient(135deg, #3f248e 0%, #1d4d77 50%, #087a75 100%);
    box-shadow: -20px 0 60px rgba(4, 7, 25, 0.48);
}

/* Position and ground only — the material is the design system's close button
   (docs/design-system.html .close-btn, live as .caselet-story-close): white
   glass at .14 over a .24 hairline, inherited from .about-close in home.css.

   It used to override that with a near-opaque navy fill so it would survive the
   stage scrolling under it below 900px, which made it the one dark control on a
   panel whose whole vocabulary is light-on-dark. The blur does that job without
   painting over the light: it grounds the button against whatever passes behind
   instead of hiding it. Declaring no background here also leaves
   `.about-close:hover` — same specificity, earlier file — free to win, so the
   hover fill works again rather than only the rotation. */
.products-overlay .about-close {
    top: 16px;
    right: 18px;
    z-index: 4;
    width: 38px;
    height: 38px;
    box-shadow: 0 10px 28px rgba(4, 7, 25, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.26);
    backdrop-filter: blur(14px) saturate(150%);
    -webkit-backdrop-filter: blur(14px) saturate(150%);
}

.products-overlay .products-stage {
    position: relative;
    z-index: 1;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
    overscroll-behavior: contain;
}

/* Slim glass scrollbars for the panels that fall back to scrolling when the
   legible floor stops fitting. Declared once; every scrollable API Studio
   surface opts in by class. */
.api-scroll {
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: rgba(157, 246, 226, 0.4) transparent;
}

.api-scroll::-webkit-scrollbar { width: 5px; }
.api-scroll::-webkit-scrollbar-track { background: transparent; }
.api-scroll::-webkit-scrollbar-thumb { border-radius: 999px; background: rgba(157, 246, 226, 0.36); }

/* ── Two columns, not four cells ──
   claim    | proof
   ─────────| explorer
   lead card|

   The left column says the thing and then asks; the right column shows the
   product and lets the visitor explore it.

   Neither left card stretches. The claim is exactly as tall as its own content
   and the lead card ends where its button ends, both of them at the top of the
   column, with whatever is left over sitting empty underneath. That is the
   whole point: the claim is the same height on a first visit as it is three
   verdicts later, so nothing on this surface moves except what the visitor just
   changed. Row 2 still takes the slack as a TRACK — the right column spans both
   rows as one flex stack, and the explorer has to keep reaching the bottom of
   the window whatever the left column is doing. */
.api-studio-shell {
    box-sizing: border-box;
    width: min(1280px, calc(100% - clamp(16px, 3vw, 56px)));
    height: 100vh;
    height: 100dvh;
    max-height: 100dvh;
    min-height: 0;
    margin: 0 auto;
    /* Top padding is only here to clear the floating close button (16px down,
       38px tall). It was set well above that, and every pixel of it comes
       straight off the lead card at the bottom of the left column. */
    padding: clamp(44px, 5.4vh, 64px) 0 clamp(12px, 2.2vh, 22px);
    display: grid;
    grid-template-columns: minmax(0, 0.84fr) minmax(0, 1.16fr);
    grid-template-rows: auto minmax(0, 1fr);
    gap: var(--api-gap);
    overflow: hidden;
}

.api-studio-col-proof {
    grid-column: 2;
    grid-row: 1 / -1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: var(--api-gap);
}

.api-studio-copy,
.api-studio-preview,
.product-feedback-inner,
.explorer {
    box-sizing: border-box;
    min-width: 0;
    min-height: 0;
    border: 1px solid var(--api-line);
    border-radius: var(--api-radius);
    background: var(--api-surface);
    box-shadow: 0 14px 30px var(--api-shadow), inset 0 1px 0 var(--api-surface-strong);
}

/* ── Hero claim ──
   Its own padding and rhythm rather than the shared --api-pad: this is the one
   card on the surface with nothing to fit into, so it can afford the room, and
   the extra air is what makes the product name read as a product name. */
.api-studio-copy {
    grid-column: 1;
    grid-row: 1;
    position: relative;
    padding: clamp(18px, calc(var(--api-u) * 1.85), 34px) clamp(16px, calc(var(--api-u) * 1.6), 30px);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: clamp(9px, calc(var(--api-u) * 0.95), 17px);
    overflow: hidden;
}

.api-studio-copy::before {
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    content: "";
    background: linear-gradient(180deg, var(--api-violet), var(--api-accent));
}

.api-studio-kicker-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.api-studio-kicker { color: var(--api-copy); font-size: var(--api-fs-eyebrow); font-weight: 800; letter-spacing: 0.04em; }
.products-overlay .product-status-pill { padding: 5px 9px; font-size: var(--api-fs-eyebrow); }

.api-studio-copy h2 {
    display: flex;
    align-items: center;
    gap: 0.22em;
    margin: 0;
    color: var(--white);
    font-size: clamp(26px, calc(var(--api-u) * 4.2), 66px);
    line-height: 0.95;
    letter-spacing: -0.03em;
    overflow-wrap: anywhere;
}

.api-studio-title-bolt {
    width: 0.56em;
    height: 0.56em;
    flex: 0 0 auto;
    color: var(--api-accent);
    filter: drop-shadow(0 0 8px rgba(157, 246, 226, 0.42));
}

.api-studio-summary {
    margin: 0;
    max-width: 34ch;
    color: var(--api-copy);
    font-size: var(--api-fs-lead);
    font-weight: 500;
    line-height: 1.4;
}

.api-studio-chips {
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    list-style: none;
}

.api-studio-chips li {
    padding: 5px 10px;
    color: rgba(255, 255, 255, 0.9);
    border: 1px solid rgba(255, 255, 255, 0.16);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.07);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
    font-size: var(--api-fs-eyebrow);
    font-weight: 700;
    letter-spacing: 0.03em;
    white-space: nowrap;
}

/* ── The left column's two lit buttons ──
   "Try live demo" on the claim and the submit on the lead card are the only two
   filled controls on this surface, so they are one object with two labels. The
   SKIN is the house primary, value for value, from buttons.css / the
   design-system page: 135deg #8b5cf6 → #14b8a6, a 1px light edge, a 14px
   rounded rectangle, and the three-part glossy shadow (ground, violet throw,
   inset top highlight). What is local to this overlay is only the SIZE, which
   scales off --api-u like everything else here; at a typical desktop it lands
   on the system's own 26px side padding.
   The demo CTA used to be a 9px pill in the corner of the screenshot: the most
   important control on the surface, rendered at the smallest size on it. */
.api-studio-demo-cta,
.products-overlay .product-actions .btn-primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: clamp(8px, calc(var(--api-u) * 0.75), 12px);
    min-height: clamp(40px, calc(var(--api-u) * 3.4), 50px);
    padding: 0 clamp(22px, calc(var(--api-u) * 1.9), 30px);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.32);
    border-radius: 14px;
    background: linear-gradient(135deg, #8b5cf6 0%, #14b8a6 100%);
    box-shadow:
        0 10px 28px rgba(0, 0, 0, 0.3),
        0 3px 14px rgba(124, 58, 237, 0.45),
        inset 0 1px 0 rgba(255, 255, 255, 0.35);
    font-size: var(--api-fs-lead);
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    transition: filter 0.22s ease, transform 0.22s ease, box-shadow 0.22s ease;
}

.api-studio-demo-cta {
    align-self: flex-start;
    margin-top: clamp(4px, calc(var(--api-u) * 0.5), 9px);
}

.api-studio-demo-cta svg { width: 1em; height: 1em; flex: 0 0 auto; }

.api-studio-demo-cta:hover,
.api-studio-demo-cta:focus-visible,
.products-overlay .product-actions .btn-primary:hover:not(:disabled),
.products-overlay .product-actions .btn-primary:focus-visible {
    filter: brightness(1.06);
    outline: none;
    transform: translateY(-2px);
    box-shadow:
        0 16px 36px rgba(0, 0, 0, 0.34),
        0 4px 18px rgba(124, 58, 237, 0.5),
        inset 0 1px 0 rgba(255, 255, 255, 0.4);
}

.api-studio-demo-cta:active,
.products-overlay .product-actions .btn-primary:active:not(:disabled) {
    transform: translateY(0);
    filter: brightness(0.98);
}

/* ── Product proof ── */
.api-studio-preview {
    flex: 0 1 38%;
    position: relative;
    isolation: isolate;
    margin: 0;
    padding: clamp(4px, calc(var(--api-u) * 0.5), 8px);
    overflow: hidden;
}

.api-studio-preview img {
    position: relative;
    z-index: 0;
    display: block;
    width: 100%;
    height: 100%;
    min-height: 0;
    object-fit: cover;
    object-position: center top;
    border-radius: calc(var(--api-radius) - 6px);
}

/* Faceted light stays on the preview edge so the product proof remains legible. */
.api-studio-preview::before,
.api-studio-preview::after {
    position: absolute;
    z-index: 1;
    content: "";
    pointer-events: none;
}

.api-studio-preview::before {
    inset: 5px;
    border: 1px solid rgba(224, 255, 251, 0.34);
    border-radius: calc(var(--api-radius) - 5px);
    background:
        linear-gradient(136deg, rgba(255, 255, 255, 0.3), transparent 16%, transparent 78%, rgba(157, 246, 226, 0.2)),
        linear-gradient(312deg, transparent 0 58%, rgba(181, 134, 255, 0.15) 58% 68%, transparent 68%);
    opacity: 0.46;
    box-shadow: inset 0 0 22px rgba(208, 255, 247, 0.12), 0 0 20px rgba(157, 246, 226, 0.12);
    clip-path: polygon(0 0, 36% 0, 20% 10%, 100% 0, 100% 68%, 91% 84%, 100% 100%, 62% 100%, 79% 89%, 0 100%);
    transition: opacity 220ms ease, border-color 220ms ease, box-shadow 220ms ease;
}

.api-studio-preview::after {
    top: -38%;
    right: 12%;
    width: 34%;
    height: 176%;
    background: linear-gradient(112deg, transparent 35%, rgba(255, 255, 255, 0.2) 48%, rgba(157, 246, 226, 0.12) 53%, transparent 64%);
    mix-blend-mode: screen;
    opacity: 0;
    transform: skewX(-18deg) translateX(48%);
    transition: opacity 180ms ease;
}

.api-studio-preview figcaption {
    position: absolute;
    z-index: 3;
    right: clamp(8px, calc(var(--api-u) * 1), 16px);
    bottom: clamp(8px, calc(var(--api-u) * 1), 16px);
    margin: 0;
}

.api-studio-preview-cta {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-height: clamp(30px, calc(var(--api-u) * 2.7), 38px);
    padding: 0 clamp(11px, calc(var(--api-u) * 1.1), 16px);
    color: var(--white);
    border: 1px solid rgba(196, 253, 243, 0.5);
    border-radius: 999px;
    background: rgba(8, 20, 66, 0.82);
    box-shadow: 0 8px 22px rgba(4, 8, 28, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.16);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    font-size: var(--api-fs-micro);
    font-weight: 800;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color 160ms ease, border-color 160ms ease, transform 160ms ease;
}

.api-studio-preview-cta svg { width: 1em; height: 1em; flex: 0 0 auto; }

.api-studio-preview-cta:hover,
.api-studio-preview-cta:focus-visible {
    border-color: var(--white);
    background: rgba(124, 58, 237, 0.8);
    outline: none;
    transform: translateY(-1px);
}

@media (hover: hover) and (pointer: fine) {
    .api-studio-preview:hover::before,
    .api-studio-preview:focus-within::before {
        opacity: 0.94;
        border-color: rgba(224, 255, 251, 0.56);
        box-shadow: inset 0 0 26px rgba(208, 255, 247, 0.2), 0 0 28px rgba(157, 246, 226, 0.22);
    }

    .api-studio-preview:hover::after,
    .api-studio-preview:focus-within::after {
        opacity: 0.78;
        animation: api-crystal-sheen 1.4s ease-out both;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   FEEDBACK / LEAD CARD

   Same language as the journey-termination card in blocks.css — one raised
   glass surface with a tapered brand top-edge, verdict pills that carry their
   own accent and fill their icon when picked, fields that read as wells cut
   into the card, and one lit gradient submit. Two stacked boxes became one
   card: the question, the verdict, and whatever the verdict opens are a single
   act, so they live on a single surface.
   ══════════════════════════════════════════════════════════════════════════ */

.api-studio-feedback {
    grid-column: 1;
    grid-row: 2;
    min-width: 0;
    min-height: 0;
    display: grid;
    /* This element is only the slot; .product-feedback-inner is the card the
       visitor sees. So the slot fills the row — which gives it a DEFINITE
       height — and the card inside it hugs its content at the top of that slot,
       ending where its button ends, with the rest of the row left empty.
       Doing it the other way round (slot shrunk to the card, capped with
       max-height) looked identical until the window got short: the cap sized
       the slot but never reached the panel inside it, which kept its full
       content height and spilled out past both edges into the clipped shell.
       At 1280x720 that sliced the submit button in half. With the slot definite,
       the card's own `max-height: 100%` finally resolves and it scrolls. */
    grid-template-rows: minmax(0, auto);
    align-content: start;
}

.product-feedback-inner {
    position: relative;
    max-height: 100%;
    padding: var(--api-pad);
    display: grid;
    align-content: start;
    gap: clamp(8px, calc(var(--api-u) * 0.85), 15px);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: rgba(157, 246, 226, 0.4) transparent;
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.13);
    box-shadow:
        0 1px 2px rgba(12, 10, 30, 0.16),
        0 18px 44px -12px rgba(12, 10, 30, 0.42),
        0 6px 20px -8px rgba(124, 58, 237, 0.34);
}

/* Tapered so it reads as light falling across the top edge, not as an applied
   stripe butting into the corner radii. */
.product-feedback-inner::before {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    content: "";
    background: linear-gradient(90deg,
        transparent 0%,
        var(--purple-light) 16%,
        var(--teal-light) 84%,
        transparent 100%);
}

.product-feedback-head { min-width: 0; }
.product-kicker {
    display: block;
    margin-bottom: 4px;
    color: rgba(255, 255, 255, 0.52);
    font-size: var(--api-fs-eyebrow);
    font-weight: 700;
    letter-spacing: 0.13em;
    text-transform: uppercase;
}

.product-feedback-intro p {
    margin: 0;
    color: var(--white);
    font-size: var(--api-fs-lead);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.01em;
}

.product-verdict-bar {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(5px, calc(var(--api-u) * 0.6), 9px);
}

.product-verdict {
    --fb-accent: var(--purple-bright);
    flex: 1 1 auto;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: clamp(34px, calc(var(--api-u) * 3), 44px);
    padding: 6px clamp(8px, calc(var(--api-u) * 1), 14px);
    color: rgba(255, 255, 255, 0.9);
    border: 1px solid color-mix(in srgb, var(--fb-accent) 34%, transparent);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.07);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
    cursor: pointer;
    font: inherit;
    font-size: var(--api-fs-body);
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    transition: background var(--transition), border-color var(--transition),
        color var(--transition), transform var(--transition), box-shadow var(--transition);
}

.product-verdict[data-verdict="makes_sense"] { --fb-accent: var(--teal-light); --fb-picked: var(--green); }
.product-verdict[data-verdict="partially"] { --fb-accent: var(--purple-bright); --fb-picked: var(--fsa); }
.product-verdict[data-verdict="not_quite"] { --fb-accent: var(--pink-light); --fb-picked: var(--pink); }

.product-verdict-icon {
    display: inline-flex;
    width: clamp(13px, calc(var(--api-u) * 1.1), 16px);
    height: clamp(13px, calc(var(--api-u) * 1.1), 16px);
    flex: 0 0 auto;
    color: var(--fb-accent);
}

.product-verdict-icon svg { width: 100%; height: 100%; display: block; }

.product-verdict:hover:not(.is-active),
.product-verdict:focus-visible {
    color: #fff;
    border-color: color-mix(in srgb, var(--fb-accent) 70%, transparent);
    background: color-mix(in srgb, var(--fb-accent) 18%, rgba(255, 255, 255, 0.07));
    outline: none;
    transform: translateY(-1px);
    box-shadow:
        0 6px 18px -4px color-mix(in srgb, var(--fb-accent) 34%, transparent),
        inset 0 1px 0 rgba(255, 255, 255, 0.16);
}

/* Picked: the pill keeps its glass and lights its accent ring; the
   confirmation lands in the ICON, which fills solid with the verdict's colour
   and pops once as it arrives. */
.product-verdict.is-active {
    color: #fff;
    border-color: var(--fb-accent);
    background: color-mix(in srgb, var(--fb-accent) 26%, rgba(255, 255, 255, 0.08));
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--fb-accent) 18%, transparent);
    animation: api-verdict-pop 0.34s cubic-bezier(0.2, 0.9, 0.3, 1.35);
}

.product-verdict.is-active .product-verdict-icon path { fill: var(--fb-picked); stroke: var(--fb-picked); }
.product-verdict.is-active[data-verdict="partially"] .product-verdict-icon circle { fill: var(--fb-picked); stroke: var(--fb-picked); }
/* The disc fills; the question-mark strokes flip to dark ink, or the glyph
   dissolves into its own disc. */
.product-verdict.is-active[data-verdict="partially"] .product-verdict-icon path { fill: none; stroke: #0e1026; stroke-width: 2.2; }

.product-feedback-card {
    min-width: 0;
    display: grid;
    gap: clamp(7px, calc(var(--api-u) * 0.75), 12px);
    animation: api-field-in 0.3s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.product-feedback-copy { display: grid; gap: 3px; min-width: 0; }
.product-feedback-copy strong { color: var(--white); font-size: var(--api-fs-body); font-weight: 700; line-height: 1.3; }
.product-feedback-copy span { color: var(--api-copy); font-size: var(--api-fs-body); font-weight: 400; line-height: 1.45; }

.product-known-note,
.product-success {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: clamp(9px, calc(var(--api-u) * 0.9), 14px);
    border-radius: var(--api-radius-sm);
    font-size: var(--api-fs-body);
    line-height: 1.45;
}

.product-known-note {
    color: rgba(255, 255, 255, 0.8);
    border: 1px solid rgba(255, 255, 255, 0.14);
    background: rgba(255, 255, 255, 0.06);
}

.product-known-note::before {
    flex: none;
    content: "✓";
    color: var(--green-light);
    font-size: 1.05em;
    font-weight: 900;
    line-height: 1.35;
}

/* Confirmation, same language as the chat's lead-capture success: a gradient
   mark on a lifted panel, sized to sit inside a card rather than take a page. */
.product-success {
    align-items: center;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.24);
    background:
        radial-gradient(120% 160% at 0% 0%, rgba(159, 103, 245, 0.3), transparent 62%),
        rgba(255, 255, 255, 0.1);
    box-shadow: 0 12px 32px rgba(5, 3, 20, 0.26), inset 0 1px 0 rgba(255, 255, 255, 0.18);
    font-weight: 600;
    animation: api-success-in 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.product-success::before {
    flex: none;
    display: grid;
    width: clamp(28px, calc(var(--api-u) * 2.6), 36px);
    height: clamp(28px, calc(var(--api-u) * 2.6), 36px);
    place-items: center;
    content: "✓";
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.42);
    border-radius: 50%;
    background: linear-gradient(135deg, #8b5cf6 0%, #14b8a6 100%);
    box-shadow: 0 6px 18px rgba(124, 58, 237, 0.42), inset 0 1px 0 rgba(255, 255, 255, 0.4);
    font-size: 0.95em;
    font-weight: 900;
}

.product-feedback-form { display: grid; gap: clamp(7px, calc(var(--api-u) * 0.75), 12px); }
.product-perspective { animation: api-field-in 0.28s ease both; }
.product-perspective label,
.product-field-grid label { display: block; min-width: 0; }

.product-feedback-form label span {
    display: block;
    margin-bottom: 5px;
    color: rgba(255, 255, 255, 0.85);
    font-size: var(--api-fs-micro);
    font-weight: 600;
}

.product-field-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(6px, calc(var(--api-u) * 0.7), 11px); }

/* We hold their address but not their name, so only one field is asked for. A
   two-column track would leave it stranded at half width beside a gap where a
   field the visitor already gave us used to be. */
.product-field-grid.is-single { grid-template-columns: minmax(0, 1fr); }

/* Which address we matched, under the one field we still need. Quiet — it is a
   reassurance, not an instruction. */
.product-held-email {
    margin: 6px 0 0;
    color: rgba(255, 255, 255, 0.62);
    font-size: var(--api-fs-micro);
}

/* Fields read as wells cut into the card. The cue is the inset top shadow, not
   a dark fill — darkening the surface muddies it against the gradient behind. */
.product-feedback-form input,
.product-feedback-form textarea {
    box-sizing: border-box;
    width: 100%;
    min-height: clamp(36px, calc(var(--api-u) * 3.2), 46px);
    padding: clamp(8px, calc(var(--api-u) * 0.85), 13px) clamp(10px, calc(var(--api-u) * 1), 15px);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.06);
    box-shadow: inset 0 1px 2px rgba(12, 10, 30, 0.12);
    font: inherit;
    font-size: var(--api-fs-body);
    outline: none;
    transition: border-color var(--transition), background var(--transition), box-shadow var(--transition);
}

.product-feedback-form textarea {
    min-height: clamp(52px, calc(var(--api-u) * 5), 76px);
    line-height: 1.45;
    resize: none;
}

.product-feedback-form input::placeholder,
.product-feedback-form textarea::placeholder { color: rgba(255, 255, 255, 0.45); }

.product-feedback-form input:hover:not(:focus),
.product-feedback-form textarea:hover:not(:focus) { border-color: rgba(255, 255, 255, 0.28); }

.product-feedback-form input:focus,
.product-feedback-form textarea:focus {
    border-color: rgba(159, 103, 245, 0.85);
    background: rgba(255, 255, 255, 0.1);
    box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.18), inset 0 1px 2px rgba(12, 10, 30, 0.1);
}

/* Room around the pair, so the button reads as the end of the card rather than
   as the last field in it. The submit itself is styled with the demo CTA
   further up — one control in two places. */
.product-actions {
    margin-top: clamp(3px, calc(var(--api-u) * 0.4), 7px);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: clamp(10px, calc(var(--api-u) * 1.15), 18px);
}

/* Zero basis, so the note is never measured at its full line length and pushed
   onto a row of its own under the button — it takes whatever is left beside it
   and wraps inside that. */
.product-actions .product-note { flex: 1 1 0; }

.products-overlay .product-actions .btn-primary:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
    filter: none;
}

.product-note,
.product-status {
    margin: 0;
    min-width: 0;
    color: var(--api-muted);
    font-size: var(--api-fs-micro);
    line-height: 1.35;
}

.product-status:empty { display: none; }
.product-status.product-error { color: #fca5a5; }

/* ══════════════════════════════════════════════════════════════════════════
   EXPLORER — the four-tab one-pager
   ══════════════════════════════════════════════════════════════════════════ */

.explorer {
    flex: 1 1 auto;
    padding: var(--api-pad);
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    gap: var(--api-gap);
    overflow: hidden;
    background:
        radial-gradient(circle at 0 0, rgba(159, 103, 245, 0.3), transparent 42%),
        radial-gradient(circle at 100% 100%, rgba(20, 184, 166, 0.27), transparent 42%),
        rgba(255, 255, 255, 0.065);
}

.explorer-head {
    min-width: 0;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: clamp(10px, calc(var(--api-u) * 1.2), 20px);
}

.eyebrow,
.output-label {
    color: var(--api-accent);
    font-size: var(--api-fs-eyebrow);
    font-weight: 800;
    letter-spacing: 0.12em;
}

.explorer-head h3 {
    margin: 0;
    color: var(--white);
    font-size: var(--api-fs-title);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.02em;
}

/* A single segmented control, not four loose outline pills: the four views are
   one choice, and the track makes that legible at a glance. */
.tabs {
    flex: 0 0 auto;
    display: flex;
    gap: 3px;
    padding: 3px;
    border: 1px solid var(--api-line);
    border-radius: 999px;
    background: rgba(8, 20, 66, 0.28);
    box-shadow: inset 0 1px 2px rgba(12, 10, 30, 0.16);
}

.tabs button {
    min-height: clamp(28px, calc(var(--api-u) * 2.5), 36px);
    padding: 0 clamp(9px, calc(var(--api-u) * 1.05), 16px);
    color: var(--api-copy);
    border: 0;
    border-radius: 999px;
    background: transparent;
    cursor: pointer;
    font: inherit;
    font-size: var(--api-fs-micro);
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    transition: background var(--transition), color var(--transition), box-shadow var(--transition);
}

.tabs button:hover:not(.active) { color: var(--white); background: rgba(255, 255, 255, 0.08); }
.tabs button:focus-visible { outline: 2px solid var(--api-line-strong); outline-offset: 1px; }

.tabs button.active {
    color: var(--white);
    background: linear-gradient(135deg, rgba(124, 58, 237, 0.85), rgba(20, 184, 166, 0.7));
    box-shadow: 0 6px 16px -6px rgba(124, 58, 237, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

.stage { min-width: 0; min-height: 0; height: 100%; overflow: hidden; }
.panel { min-width: 0; min-height: 0; height: 100%; }

/* ── How it works ── */
.workflow {
    display: grid;
    /* Two things here, both about the step card next to the rail being too
       narrow to hold its own art column.
       The rail's share is unchanged, but it now has a floor that tracks the
       type scale, so its labels stop ellipsising on a wide window; and the card
       side is a whole `1fr` rather than the 0.7 that used to pair with it,
       because flex factors summing to 1 hand out only that fraction of the free
       space. The moment the rail is frozen at its floor instead of its share,
       0.7 of what remains is all the card can claim — which left ~110px of the
       stage belonging to nobody at 1920px and crushed the step copy to 78px. */
    grid-template-columns: minmax(clamp(112px, calc(var(--api-u) * 8.6), 160px), 0.3fr) minmax(0, 1fr);
    gap: var(--api-gap);
}

.steps {
    min-width: 0;
    display: grid;
    grid-template-rows: repeat(5, minmax(0, 1fr));
    gap: clamp(4px, calc(var(--api-u) * 0.45), 8px);
}

.steps button {
    position: relative;
    min-width: 0;
    min-height: 0;
    padding: clamp(5px, calc(var(--api-u) * 0.6), 10px) clamp(7px, calc(var(--api-u) * 0.85), 13px);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: clamp(5px, calc(var(--api-u) * 0.6), 9px);
    color: var(--api-copy);
    border: 1px solid var(--api-line);
    border-radius: var(--api-radius-sm);
    background: rgba(255, 255, 255, 0.045);
    cursor: pointer;
    font: inherit;
    text-align: left;
    overflow: hidden;
    transition: background var(--transition), border-color var(--transition), color var(--transition);
}

.steps button b {
    color: rgba(199, 182, 255, 0.9);
    font-size: var(--api-fs-eyebrow);
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.steps button span {
    overflow: hidden;
    font-size: var(--api-fs-micro);
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.steps button:hover:not(.active) { color: var(--white); border-color: rgba(255, 255, 255, 0.26); background: rgba(255, 255, 255, 0.08); }
.steps button:focus-visible { outline: 2px solid var(--api-line-strong); outline-offset: 1px; }

.steps button.active {
    color: var(--white);
    border-color: rgba(45, 212, 191, 0.44);
    background: linear-gradient(110deg, rgba(124, 58, 237, 0.4), rgba(20, 184, 166, 0.26));
}

.steps button.active b { color: #fff; }

/* Lit rail on the active step, so the selection is readable even where the
   gradient wash is subtle. */
.steps button.active::before {
    position: absolute;
    inset: 22% auto 22% 0;
    width: 3px;
    content: "";
    border-radius: 0 3px 3px 0;
    background: linear-gradient(180deg, var(--api-violet), var(--api-accent));
}

.step-card {
    min-width: 0;
    min-height: 0;
    padding: clamp(12px, calc(var(--api-u) * 1.5), 26px);
    position: relative;
    display: grid;
    /* 118px could not hold a "1 openapi.yaml" row, let alone the label under
       it — which is why the art's whole stack hung out over the card's right
       edge. The extra comes out of the step rail, not out of the copy. */
    grid-template-columns: auto minmax(0, 1fr) minmax(clamp(140px, calc(var(--api-u) * 10.2), 158px), 0.4fr);
    align-items: center;
    gap: clamp(10px, calc(var(--api-u) * 1.3), 22px);
    overflow: hidden;
    border: 1px solid var(--api-line);
    border-radius: var(--api-radius);
    background: rgba(10, 10, 20, 0.3);
}

.step-card::after {
    position: absolute;
    right: -70px;
    bottom: -78px;
    width: 180px;
    height: 180px;
    content: "";
    border: 1px dashed rgba(45, 212, 191, 0.22);
    border-radius: 50%;
    box-shadow: 0 0 0 26px rgba(124, 58, 237, 0.04), 0 0 0 52px rgba(20, 184, 166, 0.03);
    pointer-events: none;
}

.step-no {
    width: clamp(40px, calc(var(--api-u) * 3.9), 62px);
    height: clamp(40px, calc(var(--api-u) * 3.9), 62px);
    display: grid;
    position: relative;
    z-index: 1;
    place-items: center;
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: var(--api-radius-sm);
    background: linear-gradient(135deg, #7c3aed, #0d9488);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.25);
    color: var(--white);
    font-size: var(--api-fs-lead);
    font-weight: 900;
    font-variant-numeric: tabular-nums;
}

.step-copy,
.workflow-art { position: relative; z-index: 1; min-width: 0; }

.step-copy h4 {
    margin: 6px 0 4px;
    color: var(--white);
    font-size: var(--api-fs-display);
    font-weight: 700;
    line-height: 1.04;
    letter-spacing: -0.025em;
    overflow-wrap: anywhere;
}

.step-sub { color: #c7b6ff; font-size: var(--api-fs-body); font-weight: 700; }
.step-copy p { margin: clamp(6px, calc(var(--api-u) * 0.7), 12px) 0; color: var(--api-copy); font-size: var(--api-fs-body); line-height: 1.45; }
.output { display: block; margin-top: 3px; color: var(--white); font-size: var(--api-fs-lead); font-weight: 600; }

.workflow-art {
    min-height: 0;
    padding: clamp(7px, calc(var(--api-u) * 0.8), 12px);
    display: grid;
    /* One column that cannot be pushed. Without it the widest nowrap child set
       the track width: "LIVE SIMULATION" is ~15px wider than this 118px cell, so
       the whole stack — tag rows included — hung out over the step card's right
       edge and was clipped there. */
    grid-template-columns: minmax(0, 1fr);
    align-content: center;
    gap: clamp(6px, calc(var(--api-u) * 0.7), 11px);
    border: 1px solid var(--api-line);
    border-radius: var(--api-radius-sm);
    background: linear-gradient(150deg, rgba(124, 58, 237, 0.23), rgba(20, 184, 166, 0.16));
}

.core {
    width: clamp(40px, calc(var(--api-u) * 3.6), 58px);
    height: clamp(40px, calc(var(--api-u) * 3.6), 58px);
    margin: 0 auto;
    display: grid;
    position: relative;
    place-items: center;
    color: var(--white);
    border: 1px solid rgba(125, 242, 220, 0.48);
    border-radius: var(--api-radius-sm);
    background: radial-gradient(circle, rgba(20, 184, 166, 0.34), rgba(124, 58, 237, 0.22));
    font-size: var(--api-fs-micro);
    font-weight: 900;
}

.core i { position: absolute; width: 5px; height: 5px; border: 1px solid var(--api-accent); border-radius: 50%; background: #172337; box-shadow: 0 0 7px rgba(45, 212, 191, 0.75); }
.core i:nth-child(1) { top: 22%; left: -3px; }
.core i:nth-child(2) { top: 24%; right: -3px; }
.core i:nth-child(3) { bottom: -3px; left: calc(50% - 3px); }

.visual-list { display: grid; gap: clamp(4px, calc(var(--api-u) * 0.45), 7px); }

.visual-list span {
    min-width: 0;
    min-height: clamp(22px, calc(var(--api-u) * 2), 30px);
    padding: 3px clamp(4px, calc(var(--api-u) * 0.5), 8px);
    display: flex;
    align-items: center;
    gap: 6px;
    overflow: hidden;
    color: var(--api-copy);
    border: 1px solid var(--api-line);
    border-radius: 7px;
    background: rgba(255, 255, 255, 0.055);
    font-size: var(--api-fs-eyebrow);
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.visual-list i {
    width: clamp(13px, calc(var(--api-u) * 1.15), 17px);
    height: clamp(13px, calc(var(--api-u) * 1.15), 17px);
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    color: var(--api-accent);
    border-radius: 5px;
    background: rgba(20, 184, 166, 0.16);
    font-size: 0.82em;
    font-style: normal;
    font-weight: 800;
}

/* The label breaks over two lines rather than holding one: widening the column
   to keep it on one line would have taken 36px off the step copy beside it, and
   that copy is the panel's actual content. */
.live { min-width: 0; display: flex; align-items: center; justify-content: center; gap: 6px; color: var(--api-accent); font-size: var(--api-fs-eyebrow); font-weight: 800; letter-spacing: 0.08em; text-align: center; }
.live i { width: 6px; height: 6px; border-radius: 50%; background: var(--teal-light); box-shadow: 0 0 8px var(--teal-light); animation: api-studio-pulse 1.8s ease-in-out infinite; }

/* ── Capabilities ── */
/* `minmax(0, 1fr)` let a row end up shorter than the card standing in it, and
   .cap-card clips — so on a 1512x860 window every card had its tag row sliced
   in half. `min-content` as the floor means a row is never shorter than what it
   holds; past that floor the panel scrolls (see .api-scroll) rather than hiding
   copy, which is the rule the rest of this file already follows. */
.capabilities {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* The roadmap strip needs the same floor: `auto` alone resolves its minimum
       to ZERO, because a track's automatic minimum is waived for an item that
       is its own scroll container (.roadmap clips) — so once the rows above it
       stopped shrinking, the strip was the thing that got squeezed, and it lost
       6px off its only line of text. */
    grid-template-rows: repeat(3, minmax(min-content, 1fr)) minmax(min-content, auto);
    gap: clamp(5px, calc(var(--api-u) * 0.6), 10px);
}

.cap-card {
    min-width: 0;
    min-height: 0;
    padding: clamp(7px, calc(var(--api-u) * 0.78), 13px);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: clamp(7px, calc(var(--api-u) * 0.8), 12px);
    overflow: hidden;
    border: 1px solid var(--api-line);
    border-radius: var(--api-radius-sm);
    background: rgba(255, 255, 255, 0.05);
}

.cap-no {
    width: clamp(22px, calc(var(--api-u) * 2.1), 30px);
    height: clamp(22px, calc(var(--api-u) * 2.1), 30px);
    display: grid;
    place-items: center;
    color: var(--api-accent);
    border: 1px solid rgba(45, 212, 191, 0.26);
    border-radius: 8px;
    background: rgba(20, 184, 166, 0.11);
    font-size: var(--api-fs-eyebrow);
    font-weight: 900;
    font-variant-numeric: tabular-nums;
}

.cap-body { min-width: 0; display: flex; flex-direction: column; }
.cap-body h4 { margin: 0 0 3px; color: var(--white); font-size: var(--api-fs-body); font-weight: 700; line-height: 1.2; }
.cap-body p { margin: 0; color: var(--api-copy); font-size: var(--api-fs-micro); line-height: 1.3; }
.mini-tags { margin-top: auto; padding-top: clamp(4px, calc(var(--api-u) * 0.42), 7px); display: flex; flex-wrap: wrap; gap: 4px; }
.mini-tags i { padding: 2px 5px; color: var(--api-accent); border: 1px solid rgba(45, 212, 191, 0.2); border-radius: 5px; background: rgba(20, 184, 166, 0.09); font-size: var(--api-fs-eyebrow); font-style: normal; font-weight: 800; }

.roadmap {
    grid-column: 1 / -1;
    padding: clamp(6px, calc(var(--api-u) * 0.65), 10px) clamp(8px, calc(var(--api-u) * 0.9), 13px);
    display: flex;
    align-items: center;
    gap: 8px;
    overflow: hidden;
    border: 1px solid rgba(245, 158, 11, 0.24);
    border-radius: 8px;
    background: rgba(217, 119, 6, 0.08);
    font-size: var(--api-fs-eyebrow);
}

.roadmap b { flex: 0 0 auto; color: #fbbf24; letter-spacing: 0.06em; white-space: nowrap; }
.roadmap span { min-width: 0; overflow: hidden; color: var(--api-muted); text-overflow: ellipsis; white-space: nowrap; }

/* ── Why it matters ── */
.impact {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: minmax(min-content, 1fr) auto;
    gap: clamp(6px, calc(var(--api-u) * 0.7), 11px);
}

.impact-card {
    min-width: 0;
    min-height: 0;
    padding: clamp(10px, calc(var(--api-u) * 1.25), 20px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--api-line);
    border-radius: var(--api-radius-sm);
    background: rgba(255, 255, 255, 0.05);
}

.impact-card .pink { color: #f9a8d4; }
.impact-card h4 { margin: 8px 0 6px; color: var(--white); font-size: var(--api-fs-title); font-weight: 700; line-height: 1.15; letter-spacing: -0.02em; }
.impact-card > p { margin: 0; color: var(--api-copy); font-size: var(--api-fs-micro); line-height: 1.4; }

.impact-flow {
    min-height: 0;
    margin-top: auto;
    padding-top: clamp(8px, calc(var(--api-u) * 0.9), 14px);
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: 5px;
    align-items: center;
}

.impact-flow span {
    min-width: 0;
    min-height: clamp(30px, calc(var(--api-u) * 2.8), 42px);
    padding: 5px;
    display: grid;
    place-items: center;
    color: var(--api-copy);
    border: 1px solid var(--api-line);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.05);
    font-size: var(--api-fs-eyebrow);
    font-weight: 800;
    letter-spacing: 0.03em;
    text-align: center;
}

.impact-flow .focus { color: var(--white); border-color: transparent; background: linear-gradient(135deg, #7c3aed, #0d9488); }
.impact-flow .waiting { color: #f9a8d4; border-style: dashed; border-color: rgba(249, 168, 212, 0.38); background: rgba(244, 63, 94, 0.08); }

.unlock {
    grid-column: 1 / -1;
    padding: clamp(6px, calc(var(--api-u) * 0.7), 11px) clamp(8px, calc(var(--api-u) * 0.9), 13px);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--api-line);
    border-radius: 8px;
    background: rgba(10, 10, 20, 0.22);
}

.unlock b { margin-right: 4px; color: var(--api-accent); font-size: var(--api-fs-eyebrow); letter-spacing: 0.1em; }
.unlock span { padding: 4px 9px; color: var(--api-copy); border-radius: 999px; background: rgba(255, 255, 255, 0.07); font-size: var(--api-fs-eyebrow); }

/* ── Built for ── */
.audience {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(2, minmax(min-content, 1fr));
    gap: clamp(5px, calc(var(--api-u) * 0.6), 10px);
}

.aud-card {
    min-width: 0;
    min-height: 0;
    padding: clamp(8px, calc(var(--api-u) * 1.05), 17px);
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--api-line);
    border-radius: var(--api-radius-sm);
    background: linear-gradient(145deg, rgba(124, 58, 237, 0.16), rgba(20, 184, 166, 0.1));
}

.aud-index { position: absolute; top: 9px; right: 11px; color: rgba(199, 182, 255, 0.55); font-size: var(--api-fs-micro); font-weight: 800; font-variant-numeric: tabular-nums; }

.aud-mark {
    width: clamp(30px, calc(var(--api-u) * 2.9), 44px);
    height: clamp(30px, calc(var(--api-u) * 2.9), 44px);
    display: grid;
    place-items: center;
    color: var(--api-accent);
    border: 1px solid rgba(45, 212, 191, 0.26);
    border-radius: 9px;
    background: linear-gradient(135deg, rgba(124, 58, 237, 0.3), rgba(20, 184, 166, 0.22));
    font-size: var(--api-fs-body);
    font-weight: 900;
}

/* One step up the scale each: at body/micro the six cards read as captions in
   a lot of empty card, which is not what "Built for" is saying. */
.aud-card h4 { margin: clamp(7px, calc(var(--api-u) * 0.8), 13px) 0 4px; color: var(--white); font-size: var(--api-fs-lead); font-weight: 700; line-height: 1.15; }
.aud-card p { margin: 0; color: var(--api-copy); font-size: var(--api-fs-body); line-height: 1.35; }
.aud-line { margin-top: auto; padding-top: 8px; display: flex; gap: 3px; }
.aud-line i { height: 3px; flex: 1; border-radius: 999px; background: rgba(255, 255, 255, 0.08); }
.aud-line i:first-child { background: #8b5cf6; }
.aud-line i:nth-child(2) { background: #2dd4bf; opacity: 0.72; }

@keyframes api-studio-pulse {
    50% { opacity: 0.45; transform: scale(0.75); }
}

@keyframes api-crystal-sheen {
    0%, 18% { transform: skewX(-18deg) translateX(48%); }
    55%, 100% { transform: skewX(-18deg) translateX(-148%); }
}

@keyframes api-verdict-pop {
    0% { transform: scale(1); }
    45% { transform: scale(1.05); }
    100% { transform: scale(1); }
}

@keyframes api-field-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}

@keyframes api-success-in {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   RESPONSIVE — three tiers, each one a DENSITY decision, never a type cut.
   Body copy is never hidden; the floor set at the top of this file holds all
   the way down. What changes is how many columns the content sits in and how
   much decoration comes along.
   ══════════════════════════════════════════════════════════════════════════ */

/* Laptops and small desktops: the decorative workflow art is the first thing
   to go — it carries no information the step card does not already state. */
@media (max-width: 1180px) {
    .api-studio-shell { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
    .api-studio-preview { flex: 0 1 34%; }

    .workflow-art { display: none; }
    .step-card { grid-template-columns: auto minmax(0, 1fr); }
    .workflow { grid-template-columns: minmax(104px, 0.32fr) minmax(0, 0.68fr); }

    /* Heading and tabs stop sharing a row here: side by side, the heading gets
       squeezed until it breaks mid-word. The tabs keep their own row and scroll
       rather than wrap into two ranks, which would stop reading as one
       control. */
    .explorer-head { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
    .tabs { justify-self: start; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
    .tabs::-webkit-scrollbar { display: none; }
}

/* ── Tablet and below: the stage SCROLLS ──
   The one-locked-screen rule is a desktop rule. Below 900px it was the thing
   forcing every compromise — hiding the screenshot, slicing the step card
   mid-word, giving a five-field form 300px to live in. Here the overlay becomes
   what the rest of the site already does (see .about-stage: "read like a short
   page, not crammed into a single locked viewport"): one column, full content,
   real spacing, scrolled top to bottom.

   Nothing is capped, clipped or scrolled-within-a-scroll from here down — every
   panel sizes to its content and the page carries it. */
@media (max-width: 900px) {
    .products-overlay .products-stage {
        overflow-y: auto;
        scrollbar-width: thin;
        scrollbar-color: rgba(255, 255, 255, 0.34) transparent;
    }

    .products-overlay .products-stage::-webkit-scrollbar { width: 6px; }
    .products-overlay .products-stage::-webkit-scrollbar-thumb { border-radius: 999px; background: rgba(255, 255, 255, 0.3); }

    .api-studio-shell {
        width: min(100%, calc(100% - clamp(14px, 4vw, 32px)));
        height: auto;
        min-height: 100dvh;
        max-height: none;
        padding: clamp(58px, 8vh, 76px) 0 clamp(24px, 5vh, 48px);
        display: flex;
        flex-direction: column;
        gap: clamp(12px, 2.4vw, 20px);
        overflow: visible;
    }

    /* Flattened, the four surfaces fall into reading order on their own:
       claim, proof, explorer, lead card. */
    .api-studio-col-proof { display: contents; }

    .api-studio-copy,
    .api-studio-preview,
    .explorer,
    .api-studio-feedback,
    .product-feedback-inner,
    .stage,
    .panel {
        max-height: none;
        height: auto;
        overflow: visible;
    }


    .api-studio-copy { padding: clamp(18px, 4vw, 30px); gap: clamp(10px, 2vw, 16px); }
    .api-studio-copy h2 { font-size: clamp(30px, 7vw, 46px); }
    .api-studio-summary { max-width: none; }
    /* Uncropped here. A cover-crop into a fixed box cut the dashboard's left
       nav and top bar out, which reads as a mistake rather than a framing — and
       at this width nobody is reading the screenshot's text anyway, so what has
       to survive is the SHAPE of a real product. The figure takes the image's
       own 1600x721. */
    .api-studio-preview { flex: 0 0 auto; }
    .api-studio-preview img { height: auto; object-fit: contain; object-position: center; }
    .explorer { flex: 0 0 auto; padding: clamp(16px, 3.6vw, 26px); }
    .product-feedback-inner { overflow: visible; }

    /* Panel grids stop dividing a fixed height and start stacking. */
    .stage { display: block; }
    .capabilities,
    .impact { grid-template-rows: none; grid-auto-rows: auto; }
    .audience { grid-template-rows: none; grid-auto-rows: auto; }
    /* The rail keeps its own column while the width is there — stacked full
       width it pushes the step card most of a screen down for no gain. */
    .workflow { grid-template-rows: auto; }
    .steps { grid-template-rows: none; grid-auto-rows: auto; }
    .steps button { min-height: 44px; }
    .step-card { grid-template-columns: auto minmax(0, 1fr); align-items: start; }
    .step-copy p { margin: 8px 0; }
}

/* Phones: one card per row, and the step rail goes horizontal — five stops
   across a 360px column would either clip their labels or shrink them below the
   floor, and a scrolling rail does neither. */
@media (max-width: 620px) {
    .api-studio-copy h2 { font-size: clamp(30px, 9vw, 40px); }

    /* The screenshot is the first thing to go on a phone. At this width it is
       a 1600px dashboard shrunk to ~350: none of its own type survives, so it
       stops being proof of a real product and becomes a band of texture between
       the claim and the explorer. The "Try live demo" link in its caption goes
       with it — the one in .api-studio-copy carries the same
       data-api-studio-demo hook, so nothing is lost from the demo path. */
    .api-studio-preview { display: none; }

    /* Four tabs will not fit one 358px row, and a scrolling track ends on a
       half-cut "Built for", which reads as broken rather than as scrollable.
       Two by two keeps it one control and shows every label whole.

       Wrapped inside a 999px track, though, the stadium ends stopped matching
       the pills they were meant to hold: two rows deep, the corner radius is
       larger than the row, so the track read as a lozenge with rectangles
       loose inside it. At this width the whole control squares off into a
       rounded rectangle and the pills follow it, and a real grid replaces the
       flex-basis arithmetic so all four are exactly one column wide. */
    .tabs {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        width: 100%;
        gap: 4px;
        padding: 4px;
        border-radius: 16px;
        overflow: visible;
        justify-self: stretch;
        background: rgba(8, 20, 66, 0.34);
        box-shadow: inset 0 1px 3px rgba(12, 10, 30, 0.24), 0 1px 0 rgba(255, 255, 255, 0.06);
    }

    /* 44px is the touch floor, and the label gets a point of size back: at this
       width var(--api-fs-micro) bottoms out at its 11px floor, which is a
       caption size being asked to act as the primary control on the panel. */
    .tabs button {
        min-height: 44px;
        padding: 0 8px;
        border-radius: 12px;
        font-size: 12.5px;
        letter-spacing: -0.01em;
    }

    .tabs button.active {
        box-shadow: 0 8px 18px -8px rgba(124, 58, 237, 0.85), inset 0 1px 0 rgba(255, 255, 255, 0.26);
    }

    .workflow { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto; }
    .steps {
        /* Set by syncStepsRail() in products/api-studio.js, which only lights an
           edge while there is rail left on that side — a permanent fade would
           claim there is more to scroll to at the ends, where there is not. */
        --steps-fade-start: 0px;
        --steps-fade-end: 0px;
        grid-auto-flow: column;
        grid-auto-columns: minmax(148px, 1fr);
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scrollbar-width: none;
        padding-bottom: 2px;
        scroll-snap-type: x proximity;
        scroll-padding-left: 2px;
        -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--steps-fade-start), #000 calc(100% - var(--steps-fade-end)), transparent 100%);
        mask-image: linear-gradient(90deg, transparent 0, #000 var(--steps-fade-start), #000 calc(100% - var(--steps-fade-end)), transparent 100%);
    }
    .steps.has-rail-start { --steps-fade-start: 26px; }
    .steps.has-rail-end { --steps-fade-end: 26px; }
    .steps button { scroll-snap-align: start; }
    .steps::-webkit-scrollbar { display: none; }

    .capabilities,
    .impact { grid-template-columns: minmax(0, 1fr); }

    /* ── Built for ──
       These six cards are a two-word label and a four-word line each, not six
       paragraphs. One card per row gave each of them a full-width band to sit
       in and turned the panel into a long scroll of mostly empty card, with the
       last two audiences off the bottom of the screen entirely.

       Two columns fit every label whole at this width and put the whole
       audience on one screen — which is what the panel is claiming. The card
       gets its depth back at the smaller size: a deeper gradient, a brighter
       hairline and a lifted shadow, so six small tiles still read as crafted
       rather than as a cramped list. */
    .audience {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }

    .aud-card {
        padding: 11px 11px 10px;
        border-color: rgba(255, 255, 255, 0.2);
        border-radius: 14px;
        background: linear-gradient(155deg, rgba(124, 58, 237, 0.24), rgba(20, 184, 166, 0.13) 62%, rgba(10, 22, 60, 0.2));
        box-shadow: 0 10px 22px -14px rgba(4, 8, 30, 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.14);
    }

    .aud-index { top: 10px; right: 11px; font-size: 10px; }

    .aud-mark {
        width: 30px;
        height: 30px;
        border-radius: 9px;
        font-size: 12px;
    }

    .aud-card h4 { margin: 9px 0 2px; font-size: 13.5px; }
    .aud-card p { font-size: 11.5px; line-height: 1.3; }
    .aud-line { padding-top: 9px; gap: 2px; }
    .aud-line i { height: 2px; }

    .product-field-grid { grid-template-columns: minmax(0, 1fr); }
    .products-overlay .about-close { top: 12px; right: 12px; width: 36px; height: 36px; font-size: 22px; }
}

/* Touch keyboards zoom the page in when a focused field is under 16px. */
@media (pointer: coarse) {
    .product-feedback-form input,
    .product-feedback-form textarea { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
    .products-flyout,
    .products-flyout-card,
    .products-flyout-flow i,
    .api-studio-demo-cta,
    .products-overlay .product-actions .btn-primary,
    .product-verdict { transition: none; }
    .api-studio-preview::before,
    .api-studio-preview::after { transition: none; }
    .api-studio-preview::after { animation: none !important; }
    .live i,
    .product-verdict.is-active,
    .product-feedback-card,
    .product-perspective,
    .product-success { animation: none; }
}
