/* ==========================================================================
   scrollTo — landing page, feature explorer and doc styles
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */

/* Root-scoped CSS custom properties. RGB triplets (space-separated, no commas)
   so Tailwind can wrap them with `rgb(var(--token) / <alpha-value>)` and apply
   opacity at the utility layer. Edit here to retheme globally. */
:root {
    --bg: 7 3 16;
    --bg-2: 12 7 22;
    --surface: 21 16 30;
    --surface-2: 29 23 38;
    --surface-3: 38 32 46;
    --border: 42 34 51;
    --border-2: 58 47 71;
    --ink: 255 247 251;
    --ink-2: 218 202 232;
    --ink-3: 205 192 222;
    --ink-4: 63 53 72;
    --bubblegum: 255 45 135;
    --bubblegum-soft: 255 184 217;
    --bubblegum-deep: 201 30 107;
    --bubblegum-ink: 58 7 28;
    --bubblegum-hot: 255 0 110;
    --lavender: 196 181 253;
    --mint: 94 234 212;
    --lemon: 253 224 71;
    --tangerine: 255 178 122;
    --electric: 163 255 18;
}

/* --------------------------------------------------------------------------
   2. Document base
   -------------------------------------------------------------------------- */

/* Enable native smooth-scroll for in-page anchor jumps (TOC, skip-link, etc). */
html {
    scroll-behavior: smooth;
}

/* Solid dark base color behind every gradient layer below. Prevents flash of
   white before background-image paints. */
html,
body {
    background-color: rgb(var(--bg));
}

/* Layered ambient atmosphere: three radial color washes (bubblegum top-left,
   lavender top-right, mint bottom-center) plus a faint cross-hatched grid.
   background-attachment: fixed keeps it locked while body scrolls. */
body {
    background-image: radial-gradient(
            1100px 600px at 8% -10%,
            rgb(var(--bubblegum) / 0.22),
            transparent 60%
        ),
        radial-gradient(800px 600px at 96% 6%, rgb(var(--lavender) / 0.16), transparent 65%),
        radial-gradient(600px 500px at 50% 110%, rgb(var(--mint) / 0.07), transparent 70%),
        repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.012) 0 1px, transparent 1px 90px),
        repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.012) 0 1px, transparent 1px 90px);
    background-attachment: fixed;
}

/* --------------------------------------------------------------------------
   3. Global overlays
   -------------------------------------------------------------------------- */

/* Film-grain noise overlay. Inline SVG turbulence filter painted via data URI,
   blended on top of every layer with overlay mode at low opacity. Lives in
   ::before so it never intercepts pointer events. */
.grain::before {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 60;
    opacity: 0.07;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* CRT-style horizontal scanline overlay. Paired with .grain to give the
   retro-monitor feel. Soft-light blend so it tints rather than overpowers. */
.scan::after {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 55;
    opacity: 0.18;
    mix-blend-mode: soft-light;
    background-image: repeating-linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.05) 0 1px,
        transparent 1px 3px
    );
}

/* Helper that lifts an element above the grain/scan overlays (which sit at
   z-index 55-60). Apply to sticky headers or anything that must stay crisp. */
.above {
    position: relative;
    z-index: 10;
}

/* --------------------------------------------------------------------------
   4. Typography utilities
   -------------------------------------------------------------------------- */

/* Vertical white-to-bubblegum gradient clipped to text glyphs. Used for hero
   display headlines. Requires `-webkit-background-clip` for Safari support. */
.display-grad {
    background: linear-gradient(
        180deg,
        #ffffff 0%,
        rgb(var(--bubblegum-soft)) 60%,
        rgb(var(--bubblegum)) 100%
    );
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

/* Editorial Fraunces italic with variable-font axes pushed to display sizing
   (opsz 144) and softer weight. Pull-quote / accent treatment. */
.editorial-italic {
    font-family: "Fraunces", Georgia, serif;
    font-style: italic;
    font-variation-settings:
        "opsz" 144,
        "SOFT" 100,
        "wght" 400;
}

/* Outlined-only text (hot-pink stroke, transparent fill). Used for poster-style
   accent words inside otherwise filled headlines. */
.stroke-text {
    -webkit-text-stroke: 1.2px rgb(var(--bubblegum));
    color: transparent;
}

/* Marker-pen highlight underline. linear-gradient renders a flat bubblegum bar
   across the bottom 14% of the text's background box. */
.pink-underline {
    background-image: linear-gradient(transparent 86%, rgb(var(--bubblegum)) 86% 100%);
    background-repeat: no-repeat;
    background-size: 100% 100%;
}

/* Section divider container: holds centered content with horizontal rule lines
   stretching out to each side via flex children below. */
.star-rule {
    display: flex;
    align-items: center;
    gap: 1rem;
}

/* Decorative left/right hairline rules for .star-rule. Each grows to fill the
   remaining flex space and fades to transparent at the outer edges. */
.star-rule::before,
.star-rule::after {
    content: "";
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgb(var(--bubblegum) / 0.35), transparent);
}

/* --------------------------------------------------------------------------
   5. Global selection + scrollbar
   -------------------------------------------------------------------------- */

/* Branded text selection: bubblegum highlight with dark surface text for
   contrast. Applies anywhere the user drags-to-select. */
::selection {
    background: rgb(var(--bubblegum));
    color: rgb(var(--surface));
}

/* Firefox scrollbar styling (thin track, bubblegum thumb on dark track). */
html {
    scrollbar-color: rgb(var(--bubblegum)) rgb(var(--bg-2));
    scrollbar-width: thin;
}

/* WebKit/Chromium scrollbar dimensions (10px gutter, both axes). */
::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

/* WebKit scrollbar track: matches the secondary background token. */
::-webkit-scrollbar-track {
    background: rgb(var(--bg-2));
}

/* WebKit scrollbar thumb: vertical bubblegum gradient pill with a 2px track
   inset so the thumb floats inside the gutter. */
::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgb(var(--bubblegum)), rgb(var(--bubblegum-deep)));
    border-radius: 999px;
    border: 2px solid rgb(var(--bg-2));
}

/* Hover state shifts the gradient to hotter pink for tactile feedback. */
::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, rgb(var(--bubblegum-hot)), rgb(var(--bubblegum-deep)));
}

/* --------------------------------------------------------------------------
   6. Shared components
   -------------------------------------------------------------------------- */

/* Pill-style nav/CTA chip. Animates all chromatic + transform props for the
   hover lift defined below. */
.chip {
    transition:
        background 200ms,
        color 200ms,
        border-color 200ms,
        transform 200ms;
}

/* Chip hover lift: 1px upward nudge to suggest interactivity. */
.chip:hover {
    transform: translateY(-1px);
}

/* Keyboard-key indicator (kbd element). Compact pill with monospaced glyph
   and muted ink color so it reads as inline hint, not body text. */
kbd {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    height: 1.5rem;
    padding: 0 0.4rem;
    border-radius: 6px;
    border: 1px solid rgb(var(--border-2));
    background: rgb(var(--bg-2));
    font-family: "Geist Mono", ui-monospace;
    font-size: 11px;
    color: rgb(var(--ink-3));
}

/* --------------------------------------------------------------------------
   7. Reveal / stagger animations
   -------------------------------------------------------------------------- */

/* Off-state for scroll-triggered reveal elements: hidden + offset down 18px.
   JS adds `.in` class via IntersectionObserver to play the fade-up. */
.reveal {
    opacity: 0;
    transform: translateY(18px);
    transition:
        opacity 0.65s ease,
        transform 0.65s ease;
}

/* On-state added by JS when the element enters the viewport. */
.reveal.in {
    opacity: 1;
    transform: translateY(0);
}

/* Cascading delay modifiers — apply .d1..d5 on sibling reveals to stagger
   their entrance by ~80ms increments. */
.reveal.d1 {
    transition-delay: 0.08s;
}
.reveal.d2 {
    transition-delay: 0.16s;
}
.reveal.d3 {
    transition-delay: 0.24s;
}
.reveal.d4 {
    transition-delay: 0.32s;
}
.reveal.d5 {
    transition-delay: 0.4s;
}

/* Auto-staggered children: every direct child of .stagger runs the `rise`
   keyframe with progressively delayed start times defined below. */
.stagger > * {
    animation: rise 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

/* Per-child delays for .stagger. Tighter cadence early (40-50ms gaps),
   loosening to ~20ms as items get further down to keep long lists snappy. */
.stagger > *:nth-child(1) { animation-delay: 0.04s; }
.stagger > *:nth-child(2) { animation-delay: 0.09s; }
.stagger > *:nth-child(3) { animation-delay: 0.14s; }
.stagger > *:nth-child(4) { animation-delay: 0.19s; }
.stagger > *:nth-child(5) { animation-delay: 0.24s; }
.stagger > *:nth-child(6) { animation-delay: 0.29s; }
.stagger > *:nth-child(7) { animation-delay: 0.34s; }
.stagger > *:nth-child(8) { animation-delay: 0.38s; }
.stagger > *:nth-child(9) { animation-delay: 0.40s; }
.stagger > *:nth-child(10) { animation-delay: 0.42s; }
.stagger > *:nth-child(11) { animation-delay: 0.44s; }
.stagger > *:nth-child(12) { animation-delay: 0.46s; }
.stagger > *:nth-child(13) { animation-delay: 0.48s; }
.stagger > *:nth-child(14) { animation-delay: 0.50s; }
.stagger > *:nth-child(15) { animation-delay: 0.52s; }
.stagger > *:nth-child(16) { animation-delay: 0.54s; }
.stagger > *:nth-child(17) { animation-delay: 0.56s; }
.stagger > *:nth-child(18) { animation-delay: 0.58s; }
.stagger > *:nth-child(19) { animation-delay: 0.60s; }
.stagger > *:nth-child(20) { animation-delay: 0.62s; }
.stagger > *:nth-child(21) { animation-delay: 0.64s; }
.stagger > *:nth-child(22) { animation-delay: 0.66s; }
.stagger > *:nth-child(23) { animation-delay: 0.68s; }

/* --------------------------------------------------------------------------
   8. Ring-card (index)
   -------------------------------------------------------------------------- */

/* Register --ring-from as an animatable <angle>. Required for browsers to
   tween a conic-gradient `from` value (otherwise it would snap, not rotate). */
@property --ring-from {
    syntax: "<angle>";
    initial-value: 0deg;
    inherits: false;
}

/* Drives the conic gradient rotation on .ring-card::before. */
@keyframes ring-rot {
    to {
        --ring-from: 360deg;
    }
}

/* Card with a rotating conic-gradient border. The card itself is the
   positioning anchor; the border lives in ::before so it doesn't disturb
   layout or content. */
.ring-card {
    --ring-from: 0deg;
    animation: ring-rot 3.8s linear infinite;
    position: relative;
}

/* Offset the second ring-card so paired cards rotate out-of-phase for
   visual interest. */
.ring-card.delay-ring {
    animation-delay: -1.9s;
}

/* The rotating border itself. Conic gradient masked via mask-composite trick:
   two solid masks composited with `exclude` punches out the inner content
   area, leaving only the 1.5px ring visible. */
.ring-card::before {
    content: "";
    position: absolute;
    inset: -1.5px;
    border-radius: inherit;
    padding: 1.5px;
    background: conic-gradient(
        from var(--ring-from),
        rgb(var(--bubblegum-soft)),
        rgb(var(--bubblegum)),
        rgb(var(--bubblegum-hot)),
        rgb(var(--bubblegum-deep)),
        rgb(var(--bubblegum-soft))
    );
    -webkit-mask:
        linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    z-index: 0;
}

/* --------------------------------------------------------------------------
   9. Feature rows + swatches (index)
   -------------------------------------------------------------------------- */

/* Feature list row in resting state. Transitions chrome props for the hover
   "card pop" effect defined next. */
.feat-row {
    transition:
        background 200ms,
        padding 200ms,
        border-radius 200ms;
}

/* Hover state lifts the row into a soft surface "card", with negative outer
   margins so the visual width grows without disturbing the surrounding grid. */
.feat-row:hover {
    background: rgb(var(--surface));
    border-radius: 14px;
    padding-left: 20px;
    padding-right: 20px;
    margin-left: -20px;
    margin-right: -20px;
}

/* Feature row index number — base state, smooth color transition. */
.feat-num {
    transition: color 200ms;
}

/* When the parent .feat-row is hovered, the number tints bubblegum. */
.feat-row:hover .feat-num {
    color: rgb(var(--bubblegum));
}

/* Color swatch tile. Outline transparent in resting state so the swatch can
   "select" without jumping size when .active is added. */
.swatch {
    transition:
        transform 150ms,
        outline 150ms;
    border-radius: 10px;
    cursor: pointer;
    outline: 2px solid transparent;
}

/* Swatch hover: lift + slight scale-up for tactile feedback. */
.swatch:hover {
    transform: translateY(-4px) scale(1.08);
}

/* Selected swatch: ink-colored outline, smaller lift than hover so the active
   tile reads as "pressed in" relative to hovered neighbors. */
.swatch.active {
    outline-color: rgb(var(--ink));
    outline-offset: 2px;
    transform: translateY(-3px);
}

/* --------------------------------------------------------------------------
   10. Accordion + TOC + sidebar (features)
   -------------------------------------------------------------------------- */

/* Collapse wrapper using the grid-template-rows 0fr/1fr trick. Animating
   grid-template-rows lets us transition from height: 0 to height: auto,
   which is otherwise impossible. */
.acc-body-wrap {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Open state: row track expands to its natural content height. */
.accordion-card.is-open .acc-body-wrap {
    grid-template-rows: 1fr;
}

/* Inner wrapper for the grid trick. Must clip overflow + have min-height: 0
   or the 0fr collapse will not actually hide overflow. */
.acc-body-inner {
    overflow: hidden;
    min-height: 0;
}

/* Disclosure chevron icon — smooth rotation transition. */
.acc-chevron {
    transition: transform 0.25s ease;
}

/* Flip the chevron 180° to indicate the panel is expanded. */
.accordion-card.is-open .acc-chevron {
    transform: rotate(180deg);
}

/* Separator line between toggle header and expanded body, only shown when
   the accordion is open. */
.accordion-card.is-open .acc-toggle {
    border-bottom: 1px solid rgb(var(--border));
}

/* Inline highlight (used both for editorial emphasis and search hits).
   Bubblegum-tinted pill around the text. */
mark {
    background: rgb(var(--bubblegum) / 0.3);
    color: rgb(var(--ink));
    border-radius: 4px;
    padding: 0 3px;
    font-weight: 700;
}

/* Active TOC entry: pink fill + matching border to mark current scroll
   position. Toggled by the scrollspy script. */
.toc-link.active-toc {
    color: rgb(var(--bubblegum-soft));
    background: rgb(var(--bubblegum) / 0.12);
    border-color: rgb(var(--bubblegum) / 0.32);
}

/* The little leading accent bar fades in only on the active TOC item. */
.toc-link.active-toc .toc-bar {
    opacity: 1;
}

/* Resting state for the TOC accent bar (hidden until .active-toc). */
.toc-bar {
    opacity: 0;
    transition: opacity 0.2s;
}

/* Hide scrollbar visually while keeping scroll behavior — used for slim
   side rails that should not show OS scrollbar chrome. */
.sidebar-scroll {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

/* WebKit equivalent of the hidden-scrollbar declaration above. */
.sidebar-scroll::-webkit-scrollbar {
    width: 0;
    height: 0;
    display: none;
}

/* Give TOC anchors breathing room when scrolled-to so they don't snap
   flush against the sticky header. */
#toc-sidebar .toc-link {
    scroll-margin-top: 2.5rem;
}

/* Positioning context for the bottom fade overlay below. */
.sidebar-fade {
    position: relative;
}

/* Sticky bottom gradient fade that signals "more content below" in a
   scrollable sidebar. Negative margin lets the sibling content slide
   underneath it. */
.sidebar-fade::after {
    content: "";
    position: sticky;
    bottom: -1rem;
    left: 0;
    right: 0;
    display: block;
    height: 1.5rem;
    margin-top: -1.5rem;
    background: linear-gradient(to top, rgba(13, 13, 17, 0.95), transparent);
    pointer-events: none;
}

/* Giant ghost lettering used behind feature sections as decorative
   background. Non-selectable + ignores pointer events so it can't be
   interacted with by accident. */
.watermark {
    font-family: "Bricolage Grotesque", system-ui;
    font-weight: 900;
    letter-spacing: -0.06em;
    color: rgb(var(--bubblegum) / 0.07);
    pointer-events: none;
    user-select: none;
}

/* --------------------------------------------------------------------------
   11. Docs navigation + help sections (docs)
   -------------------------------------------------------------------------- */

/* Section label inside the docs left rail. Mono uppercase micro-header
   for visual grouping. */
.doc-nav-group {
    font-family: "Geist Mono", monospace;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgb(var(--ink-3));
    padding: 0.875rem 1rem 0.375rem;
}

/* Individual docs sidebar link. Left-border slot stays transparent until
   the link is active (see .active rule). */
.doc-nav-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 1rem;
    font-size: 0.78rem;
    color: rgb(var(--ink));
    text-decoration: none;
    border-radius: 0;
    transition:
        color 120ms,
        background 120ms;
    border-left: 2px solid transparent;
    cursor: pointer;
}

/* Hover state for docs nav links — softens background without shifting layout. */
.doc-nav-link:hover {
    color: rgb(var(--ink));
    background: rgb(var(--surface-2) / 0.5);
}

/* Active docs nav link: bubblegum left rail + tinted background to mark
   the currently viewed section. */
.doc-nav-link.active {
    color: rgb(var(--bubblegum-soft));
    border-left-color: rgb(var(--bubblegum));
    background: rgb(var(--bubblegum) / 0.06);
}

/* Inert state dot next to each docs nav link. */
.doc-nav-link .nav-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: rgb(var(--border-2));
    flex-shrink: 0;
    transition: background 120ms;
}

/* Light up the dot when the nav link is active. */
.doc-nav-link.active .nav-dot {
    background: rgb(var(--bubblegum));
}

/* Spacing between adjacent help articles on the docs page. */
.scroll-help-section {
    margin-bottom: 2.5rem;
}

/* H2 inside docs help section — display-weight headline with variable-font
   axes pushed to large optical size. */
.scroll-help-section > h2 {
    font-family: "Bricolage Grotesque", system-ui;
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: -0.03em;
    color: rgb(var(--ink));
    margin-bottom: 0.5rem;
    font-variation-settings:
        "opsz" 72,
        "wght" 800;
    line-height: 1.15;
}

/* H3 inside docs help section — mid-tier subsection header. */
.scroll-help-section > h3 {
    font-family: "Bricolage Grotesque", system-ui;
    font-size: 1.05rem;
    font-weight: 700;
    color: rgb(var(--ink));
    margin: 1.75rem 0 0.5rem;
    font-variation-settings:
        "opsz" 48,
        "wght" 700;
}

/* H4 inside docs help section — small uppercase eyebrow above grouped
   fields/notes. */
.scroll-help-section > h4 {
    font-family: "Bricolage Grotesque", system-ui;
    font-size: 0.9rem;
    font-weight: 700;
    color: rgb(var(--ink));
    margin: 1.25rem 0 0.4rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-variation-settings:
        "opsz" 32,
        "wght" 700;
}

/* Body paragraph inside docs help section. Looser line-height for
   long-form readability. */
.scroll-help-section > p {
    font-size: 0.9rem;
    color: rgb(var(--ink));
    line-height: 1.75;
    margin-bottom: 1rem;
}

/* Inline code spans inside docs body copy. Pill-shaped mono with bubblegum
   text on a slightly raised surface. */
.scroll-help-section code {
    font-family: "Geist Mono", monospace;
    font-size: 0.8em;
    background: rgb(var(--surface-3));
    border: 1px solid rgb(var(--border));
    color: rgb(var(--bubblegum-soft));
    padding: 1px 5px;
    border-radius: 4px;
}

/* Links inside docs body copy. Subtle underline that becomes solid pink
   on hover. */
.scroll-help-section a {
    color: rgb(var(--bubblegum-soft));
    text-decoration: underline;
    text-decoration-color: rgb(var(--bubblegum) / 0.4);
    text-underline-offset: 3px;
}

/* Hover state for docs links — saturates to full bubblegum. */
.scroll-help-section a:hover {
    color: rgb(var(--bubblegum));
}

/* Lead paragraph for docs sections — denoted by a pink left-rail and looser
   text. !important used because the parent selector `> p` already styles
   regular paragraphs and we need this to win without restructuring markup. */
.scroll-help-lead {
    font-size: 0.95rem !important;
    color: rgb(var(--ink-2)) !important;
    line-height: 1.7 !important;
    max-width: 60ch;
    border-left: 3px solid rgb(var(--bubblegum) / 0.45);
    padding-left: 0.85rem;
    margin-bottom: 1.25rem !important;
}

/* Bulleted + numbered lists inside docs. Shared spacing and font setup;
   list-style differs below. */
.scroll-help-bullets,
.scroll-help-steps {
    margin: 0 0 1.25rem;
    padding-left: 1.25rem;
    font-size: 0.88rem;
    color: rgb(var(--ink));
    line-height: 1.7;
}

/* List item gap for both bullet + step variants. */
.scroll-help-bullets li,
.scroll-help-steps li {
    margin-bottom: 0.4rem;
}

/* Bullet-style help list. */
.scroll-help-bullets {
    list-style: disc;
}

/* Numbered-step help list (procedural how-to). */
.scroll-help-steps {
    list-style: decimal;
}

/* Pink bullet marker for unordered help lists. */
.scroll-help-bullets li::marker {
    color: rgb(var(--bubblegum));
}

/* Numbered marker for help steps — softer pink, mono digits to match the
   utilitarian docs voice. */
.scroll-help-steps li::marker {
    color: rgb(var(--bubblegum-soft));
    font-family: "Geist Mono", monospace;
    font-weight: 600;
}

/* Field reference container (dl) — boxed list of named API/option fields. */
.scroll-help-fields {
    border: 1px solid rgb(var(--border));
    border-radius: 12px;
    background: rgb(var(--surface) / 0.6);
    margin: 0 0 1.5rem;
    overflow: hidden;
}

/* Field-name row (<dt>) inside .scroll-help-fields. Mono label with a faint
   divider above. Wraps so pills can sit beside the name. */
.scroll-help-fields dt {
    font-family: "Geist Mono", monospace;
    font-size: 0.78rem;
    font-weight: 600;
    color: rgb(var(--ink));
    padding: 0.7rem 0.95rem 0.25rem;
    background: rgb(var(--surface-2) / 0.4);
    border-top: 1px solid rgb(var(--border) / 0.5);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
}

/* Strip the top border on the first field so the container's own border
   doesn't double-up. */
.scroll-help-fields dt:first-child {
    border-top: 0;
}

/* Field-description row (<dd>) — body copy for each field name. */
.scroll-help-fields dd {
    margin: 0;
    padding: 0.25rem 0.95rem 0.85rem;
    background: rgb(var(--surface-2) / 0.4);
    font-size: 0.85rem;
    color: rgb(var(--ink));
    line-height: 1.6;
}

/* Tiny status pill used in field rows ("required" / "optional"). Color is
   set by the modifier classes below. */
.scroll-help-pill {
    display: inline-block;
    font-family: "Geist Mono", monospace;
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.1rem 0.45rem;
    border-radius: 99px;
    border: 1px solid transparent;
}

/* "Required" pill — bubblegum scheme to draw attention. */
.scroll-help-pill--req {
    background: rgb(var(--bubblegum) / 0.15);
    color: rgb(var(--bubblegum-soft));
    border-color: rgb(var(--bubblegum) / 0.4);
}

/* "Optional" pill — lavender scheme to read as secondary. */
.scroll-help-pill--opt {
    background: rgb(var(--lavender) / 0.1);
    color: rgb(var(--lavender));
    border-color: rgb(var(--lavender) / 0.35);
}

/* Anchor target padding so deep-linked sections don't collide with the
   sticky 80-96px tall header on scroll. */
.section-anchor {
    scroll-margin-top: 96px;
}

/* Utility hide for anchors filtered out by search. */
.section-anchor.hidden {
    display: none;
}

/* Search-hit highlight — same visual as <mark> but scoped to the JS-added
   class so it can be styled/cleared independently. */
mark.search-hit {
    background: rgb(var(--bubblegum) / 0.3);
    color: rgb(var(--ink));
    border-radius: 4px;
    padding: 0 3px;
    font-weight: 700;
}

/* Docs sidebar search input. Padding-left leaves room for the absolute
   search icon. */
.nav-search {
    width: 100%;
    background: rgb(var(--surface-2));
    border: 1px solid rgb(var(--border-2));
    border-radius: 8px;
    padding: 0.5rem 0.75rem 0.5rem 2rem;
    color: rgb(var(--ink));
    font-family: "Geist", system-ui;
    font-size: 0.78rem;
    outline: none;
    transition: border-color 180ms;
}

/* Placeholder color for the docs search input. */
.nav-search::placeholder {
    color: rgb(var(--ink-3));
}

/* Focus state tints the border bubblegum (outline already suppressed). */
.nav-search:focus {
    border-color: rgb(var(--bubblegum));
}

/* Make the docs sidebar sticky on lg+ screens. Height calc accounts for the
   81px sticky header so the rail itself can scroll internally. */
@media (min-width: 1024px) {
    .docs-sidebar {
        position: sticky;
        top: 81px;
        height: calc(100vh - 81px);
        overflow-y: auto;
    }
}

/* Slim 4px scrollbar specific to the docs sidebar (overrides global 10px). */
.docs-sidebar::-webkit-scrollbar {
    width: 4px;
}

/* Transparent track so only the thumb is visible inside the sidebar. */
.docs-sidebar::-webkit-scrollbar-track {
    background: transparent;
}

/* Muted thumb that blends with the sidebar rather than competing with content. */
.docs-sidebar::-webkit-scrollbar-thumb {
    background: rgb(var(--border));
    border-radius: 99px;
}

/* --------------------------------------------------------------------------
   12. Responsive + a11y
   -------------------------------------------------------------------------- */

/* Hide the decorative phone-frame hero on narrow viewports where it would
   crowd the copy. */
@media (max-width: 768px) {
    .phone-hero {
        display: none;
    }
}

/* Honor the user's reduced-motion preference. Squash all animations +
   transitions to near-zero and force reveals into their final state so
   nothing is left invisible. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
    .reveal {
        opacity: 1;
        transform: none;
    }
}
