/* Suede.Web page-specific styles (marketing funnel, account, search shell).
   Layered over the shared design system in _content/Suede.Web.Shared/app.css. */

/* Marketing header Priority+ layout. Utilities have ONE canonical DOM home inside the native disclosure;
   the coordinator promotes those actual nodes into the inline target only while measured space permits.
   No clones means one tab stop, one form, and one source of toggle state. flex-wrap:nowrap is intentional:
   this header must never consume a second handset row. Shared/admin headers retain their wrapping fallback. */
.header-nav { display:flex;align-items:center;flex-wrap:nowrap;gap:.5rem;min-width:0;justify-content:flex-end }
.marketing-header{
  flex-wrap:nowrap;justify-content:flex-start;gap:.5rem;min-inline-size:0
}
.marketing-header > .brand-mark{flex:none;margin-inline-end:auto}
.header-inline-target,.header-utility-home{
  display:flex;align-items:center;gap:.25rem;flex:none
}
.header-inline-target:empty{display:none}
.header-utility{display:inline-flex;flex:none}
.header-theme-form{display:inline-flex;margin:0}
.header-theme-enhanced{display:none}
.header-theme-native{border:0;margin:0;padding:0;min-inline-size:0;inline-size:100%}
.header-theme-native > legend{padding:0;margin-block-end:.35rem}
:root[data-appearance-js] .header-theme-enhanced{display:inline-flex}
:root[data-appearance-js] .header-theme-native{display:none}
.header-utility[hidden],.header-utility-home[hidden]{display:none!important}
.header-utility-label{display:none}

/* Native <details> remains the structural and no-JS fallback. On a wide page its content is exposed as
   one horizontal cluster; at the conservative breakpoint (or when measurement requests it) the summary
   becomes the invariant hamburger and the exact same content becomes a viewport-contained panel. */
.nav-disclosure{position:relative;display:flex;align-items:center;min-inline-size:0;flex:none}
.nav-disclosure-panel{display:flex;align-items:center;gap:.5rem;min-inline-size:0}
.nav-toggle {
    display: none;  /* desktop: hidden (nav is inline) */
    align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem;
    border-radius: var(--radius); background: var(--surface-2); border: 1px solid var(--border);
    color: var(--text); cursor: pointer; list-style: none;
}
.nav-toggle::-webkit-details-marker { display: none; }
.nav-toggle::marker { content: ""; }
.nav-toggle:hover { background: var(--surface); }
.nav-disclosure > summary:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
/* Hamburger icon: three bars that morph to an X when open. */
.nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after {
    content: ""; display: block; width: 1.15rem; height: 2px; background: currentColor; border-radius: 2px;
    transition: transform 0.2s ease, opacity 0.2s ease;
}
.nav-toggle-bars { position: relative; }
.nav-toggle-bars::before { position: absolute; top: -0.4rem; inset-inline-start: 0; }
.nav-toggle-bars::after { position: absolute; top: 0.4rem; inset-inline-start: 0; }
.nav-disclosure[open] .nav-toggle-bars { background: transparent; }
.nav-disclosure[open] .nav-toggle-bars::before { transform: translateY(0.4rem) rotate(45deg); }
.nav-disclosure[open] .nav-toggle-bars::after { transform: translateY(-0.4rem) rotate(-45deg); }

/* Chromium 131+ hides a closed <details>' content through the ::details-content pseudo (content-visibility),
   which author `display` on the CHILDREN no longer overrides — so the inline-on-desktop state of this disclosure
   silently collapsed there (the nav vanished from the desktop header). Force the slot visible as the default
   (author rules beat UA rules), and re-assert the UA hiding ONLY in the narrow/hamburger state below. Engines
   without ::details-content ignore both rules and keep working via the child display overrides. */
.nav-disclosure::details-content { content-visibility: visible; }

@media (max-width: 100em) {
    :root:not([data-header-priority-js]) .marketing-header .nav-toggle { display: inline-flex; }
    :root:not([data-header-priority-js]) .marketing-header .nav-disclosure:not([open])::details-content { content-visibility: hidden; }
    :root:not([data-header-priority-js]) .marketing-header .nav-disclosure > .nav-disclosure-panel {
        position:absolute;inset-block-start:calc(100% + .5rem);inset-inline-end:0;
        inline-size:min(19rem,calc(100vw - 1.5rem));min-inline-size:0;
        flex-direction:column;align-items:stretch;gap:.35rem;padding:.5rem;
        background: var(--bg-elevated); border: 1px solid var(--border);
        border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);z-index:var(--z-dropdown);
        max-block-size:calc(100vh - 6rem);max-block-size:calc(100dvh - 6rem);
        overflow-y:auto;overscroll-behavior:contain
    }
    :root:not([data-header-priority-js]) .marketing-header .nav-disclosure:not([open]) > .nav-disclosure-panel{display:none}
    :root:not([data-header-priority-js]) .marketing-header .nav-disclosure-panel > .header-utility-home{flex-direction:column;align-items:stretch;gap:.1rem;inline-size:100%;margin-block-start:.15rem;padding-block-start:.4rem;border-block-start:1px solid var(--border)}
    :root:not([data-header-priority-js]) .marketing-header .nav-disclosure-panel > .header-nav{flex-direction:column;align-items:stretch;gap:.25rem;inline-size:100%}
    :root:not([data-header-priority-js]) .marketing-header .nav-disclosure-panel > .header-nav .btn{inline-size:100%;justify-content:flex-start}
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home > .header-utility{inline-size:100%}
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .header-theme-form{inline-size:100%}
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .theme-cycle,
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .landing-motion-toggle,
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .lang-menu,
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .header-menu-btn{inline-size:100%}
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .theme-cycle,
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .landing-motion-toggle,
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .header-menu-btn{block-size:auto;min-block-size:2.75rem;padding:.55rem .65rem;justify-content:flex-start;gap:.55rem}
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .header-utility-label{display:inline;text-align:start}
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .lang-menu{display:block}
    :root:not([data-header-priority-js]) .marketing-header .header-utility-home .lang-menu > .header-menu-panel{position:static;inline-size:100%;min-inline-size:0;max-block-size:none;margin-block-start:.25rem;box-shadow:none;background:var(--surface-2)}
}

/* The measured compact state uses the same geometry above the conservative CSS breakpoint. */
.marketing-header[data-header-nav-collapsed] .nav-toggle{display:inline-flex}
.marketing-header[data-header-nav-collapsed] .nav-disclosure:not([open])::details-content{content-visibility:hidden}
.marketing-header[data-header-nav-collapsed] .nav-disclosure > .nav-disclosure-panel{
  position:absolute;inset-block-start:calc(100% + .5rem);inset-inline-end:0;
  inline-size:min(19rem,calc(100vw - 1.5rem));min-inline-size:0;
  flex-direction:column;align-items:stretch;gap:.35rem;padding:.5rem;
  background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);z-index:var(--z-dropdown);
  max-block-size:calc(100vh - 6rem);max-block-size:calc(100dvh - 6rem);
  overflow-y:auto;overscroll-behavior:contain
}
.marketing-header[data-header-nav-collapsed] .nav-disclosure:not([open]) > .nav-disclosure-panel{display:none}
.marketing-header[data-header-nav-collapsed] .nav-disclosure-panel > .header-utility-home{flex-direction:column;align-items:stretch;gap:.1rem;inline-size:100%;margin-block-start:.15rem;padding-block-start:.4rem;border-block-start:1px solid var(--border)}
.marketing-header[data-header-nav-collapsed] .nav-disclosure-panel > .header-nav{flex-direction:column;align-items:stretch;gap:.25rem;inline-size:100%}
.marketing-header[data-header-nav-collapsed] .nav-disclosure-panel > .header-nav .btn{inline-size:100%;justify-content:flex-start}
.marketing-header[data-header-nav-collapsed] .header-utility-home > .header-utility{inline-size:100%}
.marketing-header[data-header-nav-collapsed] .header-utility-home .header-theme-form{inline-size:100%}
.marketing-header[data-header-nav-collapsed] .header-utility-home .theme-cycle,
.marketing-header[data-header-nav-collapsed] .header-utility-home .landing-motion-toggle,
.marketing-header[data-header-nav-collapsed] .header-utility-home .lang-menu,
.marketing-header[data-header-nav-collapsed] .header-utility-home .header-menu-btn{inline-size:100%}
.marketing-header[data-header-nav-collapsed] .header-utility-home .theme-cycle,
.marketing-header[data-header-nav-collapsed] .header-utility-home .landing-motion-toggle,
.marketing-header[data-header-nav-collapsed] .header-utility-home .header-menu-btn{block-size:auto;min-block-size:2.75rem;padding:.55rem .65rem;justify-content:flex-start;gap:.55rem}
.marketing-header[data-header-nav-collapsed] .header-utility-home .header-utility-label{display:inline;text-align:start}
.marketing-header[data-header-nav-collapsed] .header-utility-home .lang-menu{display:block}
.marketing-header[data-header-nav-collapsed] .header-utility-home .lang-menu > .header-menu-panel{position:static;inline-size:100%;min-inline-size:0;max-block-size:none;margin-block-start:.25rem;box-shadow:none;background:var(--surface-2)}

/* Last-resort reflow protection below realistic handset widths. It preserves the brand's accessible name
   while allowing its decorative lockup word to yield before the invariant menu ever wraps or overflows. */
.marketing-header[data-header-tight]{padding-inline:.75rem;gap:.25rem}
.marketing-header[data-header-brand-compact] .brand-word{display:none}
@media (prefers-reduced-motion: reduce) {
    .nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after { transition: none; }
}

/* Landing motion control: one compact command beside the theme toggle in the sticky header remains
   reachable while every lower-page vignette is in view. JavaScript swaps its pause/play glyph and
   accessible name. The initial [hidden] state is deliberate: without JS the page is fail-static. */
.app-header .landing-motion-toggle{
  flex:none;width:2.75rem;height:2.75rem;min-width:2.75rem;padding:0;display:inline-flex;gap:.55rem;
  align-items:center;justify-content:center;border-radius:var(--radius);color:var(--text-muted)}
.app-header .landing-motion-toggle:hover{color:var(--text);background:var(--surface)}
.app-header .landing-motion-toggle[hidden],
.landing-motion-icon[hidden]{display:none}
.landing-motion-icon{width:1.1rem;height:1.1rem}
:root[data-motion="reduce"] .landing-motion-toggle{display:none!important}
@media (prefers-reduced-motion:reduce){.landing-motion-toggle{display:none!important}}

/* Breathing room between page content and the footer (footer-scoped so it never affects the
   footer-less search app; on short pages the flex layout makes the extra space invisible). */
:root { --marketing-footer-gap: clamp(2.5rem, 5vw, 4rem); }
.app-footer { margin-top: var(--marketing-footer-gap); }

.footer-grid { display: flex; flex-wrap: wrap; gap: 2rem; justify-content: space-between; align-items: start; }
/* Reflow safety at large OS text (WCAG 1.4.4 Resize Text / 1.4.10 Reflow): the footer columns are flex
   children whose default min-width:auto floors them at their content's min-content — and the support-email
   token (e.g. support@suede.io) is unbreakable, so at ~200% text on a narrow viewport it forced a
   sub-pixel horizontal overflow. min-width:0 lets each column shrink, and overflow-wrap:anywhere lets the
   email break across lines instead of pushing past the viewport. */
.footer-grid > * { min-width: 0; }
.app-footer address, .app-footer address a { overflow-wrap: anywhere; }


/* ------------------------------- Hero ----------------------------------- */
.hero {
    text-align: center;
    position: relative;
    overflow: hidden;
    /* generous bottom padding = the silk current's own stage below the copy */
    padding: clamp(3rem, 8vw, 6rem) 1.25rem clamp(11rem, 24vw, 15rem);
    /* Ultrawide floor: past ~3.3:1 the hero becomes a sliver whose bottom-left corner sits ABOVE the drawn
       current (viewBox y < ~430), where no crop of the static art can reach it. 30vw is a no-op at common
       widths (the content is taller through ~2560px wide) and only stretches the stage on ultrawide, keeping
       the corner inside the locus the ribbons are generated to hug (branding/tools/silk_current.py). min()
       against svh so the floor never exceeds the initially-visible viewport (100svh minus the 4rem header);
       the vh line is the fallback for engines without svh. */
    min-height: min(30vw, calc(100vh - 4rem));
    min-height: min(30vw, calc(100svh - 4rem));
    background:
        radial-gradient(60% 60% at 50% 0%, color-mix(in srgb, var(--brand) 12%, transparent), transparent 70%);
}
/* Short viewports (landscape phones, half-height windows): the fold cuts deep into the hero, which slides
   the display's bottom-left corner into the CROP'S INTERIOR (the xMaxYMin slice is computed from the box,
   not the visible part) — beyond what any edge-hugging geometry can reach. Shrinking the stage below the
   copy pulls the hero height toward the viewport, which walks the corner back onto the covered locus.
   em-based so OS text zoom shifts the breakpoint with the content. */
@media (max-height: 33em) {
    .hero { padding-block: 1.5rem clamp(3rem, 8vw, 5rem); }
}
/* Narrow (portrait-phone) viewports: a slightly shorter stage keeps the fold near the drawn field's bottom
   edge, where the hugger ribbons guarantee corner ink — and trims dead scroll below the copy. */
@media (max-width: 30em) {
    .hero { padding-bottom: clamp(7rem, 18vw, 9rem); }
}
.hero > :not(.hero-bands) { position: relative; z-index: 1; }
/* The copy pool: a soft elliptical well of background color painted behind and around the copy block. It sizes
   itself to the copy (any engine, locale, or text-zoom — no measurement), so the waves flow UNBROKEN behind it
   while the words float on quiet dark. */
/* The copy stack rides a quiet glass panel (owner: dark, mildly translucent, small padding; 2026-07-18:
   "slightly more translucent" — 58% → 46% ground) — the ribbons stay continuous behind it, dimmed just
   enough to read over. */
.hero-copy { position: relative; background: color-mix(in srgb, var(--bg) 46%, transparent);
    -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px);
    border: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
    border-radius: var(--radius-lg, 16px); padding: clamp(1.25rem, 3vw, 2rem);
    max-width: 54rem; margin-inline: auto; }
/* The silk current: one static SVG of 16 gradient-stroked ribbons behind the hero (geometry + corner
   invariants live in Home.razor / branding/tools/silk_current.py). One spectrum gradient strokes every
   ribbon; hue-rotating the group makes the color travel through the current — a single composited filter,
   zero JS. */
/* Bottom feather (owner's fourth disconnect catch, 2026-07-22): at wide viewports the slice
   crop's scale pushes the huggers' DIVE through the hero's bottom edge at full stroke weight,
   and the box clip CUT them — a shallow-angle slice that reads as a tapered tip floating at the
   boundary. The field was designed to resolve at its own viewBox bottom, not at every crop's
   clip line — so the strand layer now dissolves toward the hero's bottom edge instead of
   cutting. Nothing can end hard at the boundary at ANY width, and the page tail rises through
   the same wash. Mask sits on .hero-bands only — hero content is untouched. */
.hero-bands { position: absolute; inset: 0; z-index: 0; pointer-events: none;
    -webkit-mask-image: linear-gradient(to bottom, #000 78%, transparent 99%);
    mask-image: linear-gradient(to bottom, #000 78%, transparent 99%); }
.hero-bands svg { width: 100%; height: 100%; display: block;
    /* Soft entrance, owner-tuned (2026-07-18): the old 0.6s-hold + 0.35s fade read as absence-then-POP
       ("appears abruptly after the main content"). Now the field starts blooming almost immediately and
       breathes in over ~1.6s — long enough to feel like the page settling, never a pop. Opacity-only
       (compositor-friendly; reduced-motion reveals instantly via the media block below). */
    animation: hero-svg-reveal 1.6s cubic-bezier(0.22, 0.61, 0.36, 1) 0.15s backwards; }
/* Fit the portrait composition to the INITIALLY-VISIBLE area (100svh minus the header), not the full hero:
   large text stretches the hero to 2-3x the viewport, and a slice crop computed from that whole box goes so
   narrow that the entries and pinch fall off the LEFT edge — the opening view kept only the right-side climb.
   Capped to the first screen, the box aspect stays near the drawing's and the whole bend is in view at every
   text size. The drawing's lowest strands run parallel to its bottom edge, so the field simply ENDS there
   (no chopped strokes) and the stage below stays quiet. The vh line is the fallback for engines without svh. */
.hero-bands .flow-portrait { height: min(100%, calc(100vh - 4rem)); }
.hero-bands .flow-portrait { height: min(100%, calc(100svh - 4rem)); }
@keyframes hero-svg-reveal { from { opacity: 0; } to { opacity: 1; } }
/* Two fields, one current: the landscape field serves boxes wider than ~0.93:1, where its S/waist stays
   inside the top-right-anchored crop. A PORTRAIT box would crop that field to a bendless close-up of the
   straight climb, so narrow-and-tall viewports swap in the portrait-native field (720x1280) whose full
   quarter-bend composition lives inside every phone crop (geometry + corner proofs: silk_current.py).
   em width so OS text zoom moves the toggle with the content; the orientation guard (zoom-independent, unlike
   an em min-height, which 200% text would push past every phone) keeps short-wide windows (landscape phones)
   on the landscape field, whose own invariants cover them. */
.hero-bands .flow-portrait { display: none; }
@media (max-width: 44em) and (orientation: portrait) {
    .hero-bands .flow-land { display: none; }
    .hero-bands .flow-portrait { display: block; }
}
/* the silk current's life: the 40s hue crawl on the group + the FAN BREATH on each ribbon — every path
   rotates around its field's waist by its own --fan factor (outer ribbons swing most), so the whole current
   fans out and gathers back, subtly, forever. Zero-start keyframes (no first-frame jump). */
.hero-flow { animation: hero-pulse-hue 26s ease-in-out infinite alternate; will-change: filter; }
.hero-flow path { transform-box: view-box; transform-origin: 657px 672px;
    animation: hero-fan 15s ease-in-out infinite alternate; }
/* the portrait field breathes around ITS waist — keep in sync with data-waist / silk_current.py PORT_WAIST
   (same specificity as the rule above; source order makes this override win for the portrait field) */
.flow-portrait path { transform-origin: 400px 700px; }
/* Single-hue field: a full hue cycle would leave the brand family — breathe brightness instead. */
@keyframes hero-pulse-hue { from { filter: brightness(1) saturate(1); } to { filter: brightness(1.08) saturate(1.12); } }
@keyframes hero-fan { from { transform: rotate(0deg); } to { transform: rotate(calc(var(--fan, 0) * 2.6deg)); } }
@media (prefers-reduced-motion: reduce) { .hero-flow, .hero-flow path { animation: none; } .hero-bands svg { animation: none; } }
@media (forced-colors: active) { .hero-bands { display: none; } }
.hero-eyebrow {
    display: inline-flex; align-items: center; gap: 0.4rem;
    font-size: 0.8125rem; font-weight: 600; color: var(--brand-strong);
    background: var(--brand-soft); padding: 0.35rem 0.8rem; border-radius: var(--radius-pill);
    margin-bottom: 1.25rem;
}
.hero h1 {
    font-size: clamp(2.25rem, 6vw, 3.75rem); line-height: 1.05; letter-spacing: -0.03em;
    /* max-width in ch keeps a comfortable measure, but ch is the width of the "0" glyph — which differs
       between fonts, so `system-ui` resolving to different fonts (notably Firefox vs Chromium on Linux)
       makes the column compute to different widths and the heading wrap at different points. text-wrap
       balance evens the line lengths so it reads intentionally in either case. */
    max-width: 18ch; margin: 0 auto 1rem; text-wrap: balance;
}
.hero .lede {
    font-size: clamp(1.05rem, 2.5vw, 1.3rem); color: var(--text-muted);
    max-width: 56ch; margin: 0 auto 2rem; text-wrap: pretty; }
.hero-cta { display: flex; gap: 0.75rem; justify-content: center; flex-wrap: wrap; }
/* Let the CTA labels WRAP instead of overflowing: .btn is white-space:nowrap by default, so a long label
   ("Start searching privately") forces horizontal scroll at large text. Scoped to the hero so other buttons keep
   their single-line treatment. max-width:100% lets the button shrink to the viewport at ~200% text / ~360px. */
.hero-cta .btn { white-space: normal; max-width: 100%; line-height: 1.25; }
.hero-trust { margin-top: 1.5rem; font-size: 0.875rem; font-weight: 500; color: var(--text); }
.hero-nerd { margin-top: 0.45rem; font-size: 0.8125rem; color: var(--text-muted); letter-spacing: 0.01em; }

/* ------------------------- Why Suede principles ------------------------- */
/* Four quiet, equal cards. The containing chapter, rather than the viewport, chooses one of three
   deliberate compositions below: four across, two by two, or one column. An explicit state
   machine avoids the visually stranded 3+1 arrangement while em thresholds still reflow with
   enlarged text. */
.why-suede {
    container: why-suede / inline-size;
}
.value-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(0.75rem, 1.5vw, 1rem);
    max-inline-size: 72rem;
    margin: clamp(2rem, 4vw, 3rem) auto 0;
    padding: 0;
    list-style: none;
}
/* 4 × 15.5rem readable cards + 3 × 1rem maximum gaps = the four-up threshold. */
@container why-suede (min-width: 65em) {
    .value-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@container why-suede (max-width: 34em) {
    .value-grid { grid-template-columns: minmax(0, 1fr); }
}
.value-card {
    --value-accent: var(--brand);
    position: relative;
    overflow: hidden;
    min-inline-size: 0;
    padding: clamp(1.25rem, 2.25vw, 1.6rem);
    border: 1px solid color-mix(in srgb, var(--value-accent) 18%, var(--border));
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--surface) 97%, var(--value-accent));
}
/* A short top register identifies each principle without turning the card into an illustration. */
.value-card::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: clamp(1.25rem, 2.25vw, 1.6rem);
    inline-size: 3rem;
    block-size: 2px;
    pointer-events: none;
    border-radius: 0 0 999px 999px;
    background: var(--value-accent);
}
.value-card-head {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    min-inline-size: 0;
    margin-block-end: 0.9rem;
}
/* The existing folded-plane glyphs need only a quiet paper tile; no extra frame or ornament. */
.value-icon {
    display: grid;
    place-items: center;
    width: 58px;
    height: 58px;
    flex: none;
    margin: 0;
    border: 1px solid color-mix(in srgb, var(--value-accent) 20%, var(--border));
    border-radius: 0.85rem;
    background: color-mix(in srgb, var(--value-accent) 8%, var(--surface));
}
.value-icon .fi {
    width: 40px;
    height: 40px;
    display: block;
}
/* FLUX pencil+silk miniatures (owner, 2026-07-26 — the copy outgrew the old line glyphs):
   transparent-ground webps, light/dark via the standard data-ill-swap picture contract. */
.value-icon img {
    width: 44px;
    height: 44px;
    display: block;
}
.value-card h3 {
    min-inline-size: 0;
    margin: 0;
    font-size: clamp(1.05rem, 1rem + 0.22vw, 1.2rem);
    line-height: 1.2;
    letter-spacing: -0.012em;
    text-wrap: balance;
}
.value-card p {
    margin: 0;
    color: var(--text-muted);
    font-size: clamp(0.93rem, 0.9rem + 0.12vw, 1rem);
    line-height: 1.55;
}
:root[data-contrast="high"] .value-card {
    border-width: 2px;
    background: var(--surface);
    box-shadow: none;
}
:root[data-contrast="high"] .value-card::before { background: var(--text); }
:root[data-contrast="high"] .value-icon { border-color: var(--border); }
@media (forced-colors: active) {
    .value-card {
        border: 2px solid CanvasText;
        background: Canvas;
    }
    .value-card::before { display: none; }
    .value-icon { border-color: CanvasText; background: Canvas; }
}
.sc-point-ico .fi { width: 1.35rem; height: 1.35rem; display: block; margin-inline: auto; }

.appearance-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.75rem 0; flex-wrap: wrap; }
.appearance-row + .appearance-row { border-top: 1px solid var(--border); }
.appearance-row .label { font-weight: 600; }
.appearance-row .desc { font-size: 0.8125rem; color: var(--text-muted); }

.section { padding: clamp(2rem, 5vw, 4rem) 0; }
.section-title { text-align: center; font-size: clamp(1.5rem, 4vw, 2rem); margin-bottom: 0.5rem; text-wrap: balance; }
.section-sub { text-align: center; color: var(--text-muted); max-width: 52ch; margin: 0 auto 2rem; text-wrap: balance; }
/* One editorial hierarchy for the landing. Hero display type remains intentionally singular;
   every chapter beneath it uses this title → deck → body cadence, regardless of composition. */
.landing :where(.section-title) {
    margin-block: 0;
    margin-inline: auto;
    font-size: clamp(2rem, 1.55rem + 1.8vw, 3.25rem);
    font-weight: 700;
    line-height: 1.08;
    letter-spacing: -0.035em;
    text-align: center;
    text-wrap: balance;
    overflow-wrap: anywhere;
}
.landing :where(.section-sub) {
    max-inline-size: 52ch;
    margin: 0.85rem auto 2.25rem;
    color: var(--text-muted);
    font-size: clamp(1.05rem, 0.98rem + 0.3vw, 1.25rem);
    line-height: 1.6;
    text-align: center;
    text-wrap: balance;
    overflow-wrap: anywhere;
}
.landing :where(.section-body) {
    font-size: clamp(1rem, 0.97rem + 0.12vw, 1.1rem);
    line-height: 1.68;
    text-wrap: pretty;
    overflow-wrap: anywhere;
}
.chapter-head {
    inline-size: min(68rem, calc(100% - 2.5rem));
    margin-inline: auto;
    margin-block-end: clamp(1.5rem, 3vw, 2.75rem);
}
.chapter-head .section-eyebrow { text-align: center; }
/* No dangling single words (owner, 2026-07-18): `pretty` re-flows the last lines of running copy so a
   lone "top." never sits on its own line; centered subs/foots get `balance` above for even lines.
   Progressive enhancement — engines without support keep plain wrapping. */
.sc-points p, .sc-showcase-foot, .value-card p, .theater-copy,
.faq p { text-wrap: pretty; }

.section-eyebrow { display: block; text-transform: uppercase; letter-spacing: 0.12em; font-size: 0.75rem;
    font-weight: 700; color: var(--brand); margin-bottom: 0.6rem; }

/* Lead-image presentation used by the in-flow Signal, Found section. */
.section-lead { margin: 0 auto 2.25rem; max-width: 68rem; }
.section-lead img { display: block; width: 100%; height: auto; border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }

/* The drawn scenes (pencil illustrations; provenance + processing notes in SceneSealed.razor).
   FRAMELESS: the transparent drawing sits directly on the page — no card radius/shadow (owner
   direction across the illustration rounds). Declared AFTER the .editorial-media/.section-lead
   img frame rules so the equal-specificity tie breaks frameless. */
.ill-hand { display: block; }
.ill-hand img { display: block; width: 100%; height: auto; border-radius: 0; box-shadow: none; }

/* Industry-leading threat protection: one native-wide editorial composition. The full copy stack
   is superimposed over the Lighthouse's open middle field; a diffuse wash protects readability
   without introducing a card edge, radius, rule, or separate copy style. */
.safety-stage {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: grid;
    place-items: center;
    min-block-size: clamp(42rem, 50vw, 80rem);
    box-sizing: border-box;
    padding: clamp(4rem, 7vw, 7rem) clamp(1.25rem, 5vw, 4rem);
}
.safety-stage-media {
    position: absolute;
    inset-block: 0;
    inset-inline-start: 50%;
    z-index: 0;
    inline-size: min(100%, 160rem);
    margin: 0;
    transform: translateX(-50%);
}
.safety-stage-media .ill-lighthouse,
.safety-stage-media .ill-lighthouse img {
    inline-size: 100%;
    block-size: 100%;
}
.safety-stage-media .ill-lighthouse img {
    display: block;
    max-inline-size: none;
    object-fit: cover;
    object-position: 14% 0;
    -webkit-mask-image: none;
    mask-image: none;
}
/* The hero lede's emphasized pronoun ("you" — owner-directed): semantic <em> italics plus a touch of
   weight so the emphasis survives the lede's muted color. */
.lede .lede-you { font-weight: 600; }

.safety-stage-copy {
    --safety-field-core: color-mix(in srgb, var(--bg) 88%, transparent);
    --safety-field-mid: color-mix(in srgb, var(--bg) 70%, transparent);
    position: relative;
    z-index: 2;
    inline-size: min(68rem, 100%);
    margin-inline: auto;
    text-align: center;
    transform: translateY(clamp(-2rem, -1.5vw, -.75rem));
}
.safety-stage-copy .chapter-head {
    position: relative;
    isolation: isolate;
    /* fit-content, not the old min(52rem, 100%): since the sub paragraph moved out of the header, the head
       holds only the eyebrow + the 18ch title — a fixed 52rem left the ::before blur wash far wider than
       the content (owner-reported). The wash now hugs the header, bleeding only its designed −3rem inset. */
    inline-size: fit-content;
    max-inline-size: 100%;
    margin-inline: auto;
    margin-block-end: 0;
}
.safety-stage-copy .chapter-head::before,
.safety-stage-explanation > p::before {
    content: "";
    position: absolute;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(ellipse at center,
        var(--safety-field-core) 0 52%,
        var(--safety-field-mid) 74%,
        transparent 100%);
    /* Blur only the wash itself—not the artwork beneath it—so its finite element bounds never
       resolve as a pale rectangle while the Lighthouse linework remains pin-sharp. */
    filter: blur(10px);
}
.safety-stage-copy .chapter-head::before {
    inset-block: -1.5rem;
    inset-inline: -3rem;
}
.safety-stage-copy .section-eyebrow { text-align: center; }
.safety-stage-title {
    max-inline-size: 18ch;
    hyphens: auto;
}
.safety-stage-context {
    max-inline-size: 60ch;
    margin-block-end: 0;
}
.safety-stage-explanation {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(28rem, 100%), 1fr));
    align-items: start;
    gap: clamp(1.5rem, 5vw, 5rem);
    max-inline-size: 62rem;
    margin: clamp(2rem, 4vw, 3.5rem) auto 0;
    text-align: start;
}
.safety-stage-explanation p {
    position: relative;
    isolation: isolate;
    inline-size: fit-content;
    max-inline-size: 100%;
    justify-self: start;
    min-inline-size: 0;
    margin: 0;
}
.safety-stage-explanation > p::before {
    inset-block: -1rem;
    inset-inline: -2.25rem;
}
.safety-stage-action { color: var(--text); }
.landing-emphasis {
    display: block;
    font-size: clamp(1.05rem, 1rem + .2vw, 1.18rem);
    line-height: 1.4;
    letter-spacing: -.012em;
    text-wrap: balance;
    color: var(--text);
}
.safety-stage-closer { margin-block-start: .85rem; }
.safety-stage-choice { color: var(--text-muted); }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .safety-stage-copy {
        --safety-field-core: color-mix(in srgb, var(--bg) 92%, transparent);
        --safety-field-mid: color-mix(in srgb, var(--bg) 78%, transparent);
    }
}
:root[data-theme="dark"] .safety-stage-copy {
    --safety-field-core: color-mix(in srgb, var(--bg) 92%, transparent);
    --safety-field-mid: color-mix(in srgb, var(--bg) 78%, transparent);
}

@media (max-width: 52em) {
    .safety-stage {
        min-block-size: auto;
        padding-block: clamp(4rem, 14vw, 6rem);
    }
    .safety-stage-media .ill-lighthouse img { object-position: 8% 0; }
    .safety-stage-copy {
        --safety-field-core: color-mix(in srgb, var(--bg) 92%, transparent);
        --safety-field-mid: color-mix(in srgb, var(--bg) 78%, transparent);
    }
    .safety-stage-copy { transform: none; }
    .safety-stage-copy .chapter-head::before {
        inset-block: -1.15rem;
        inset-inline: -1.25rem;
    }
    .safety-stage-explanation {
        grid-template-columns: 1fr;
        gap: 1.25rem;
        max-inline-size: 42rem;
    }
    .safety-stage-explanation > p::before {
        inset-block: -0.8rem;
        inset-inline: -1.1rem;
    }
}

/* The custom high-contrast channel strengthens only the three local text fields. */
:root[data-contrast="high"] .safety-stage-copy {
    --safety-field-core: color-mix(in srgb, var(--bg) 97%, transparent);
    --safety-field-mid: color-mix(in srgb, var(--bg) 90%, transparent);
}

@media (forced-colors: active) {
    .safety-stage {
        min-block-size: auto;
        border-block: 1px solid CanvasText;
    }
    .safety-stage-media,
    .safety-stage-copy .chapter-head::before,
    .safety-stage-explanation > p::before { display: none; }
    .safety-stage-copy { transform: none; }
    .safety-stage :is(.section-eyebrow, .safety-stage-action, .safety-stage-choice) {
        color: CanvasText;
    }
}

/* Closing brand moment: the S mark at hero scale + a quiet caption. Mark enlarged ~1.5x (owner,
   2026-07-21: "substantially larger"). The selector must carry (0,2,1): app.css sizes
   `svg.brand-mark` at 1.15em (0,1,1), which silently out-specified the old lone-class width —
   the closing mark had regressed to header size without anyone noticing. */
.brand-moment { text-align: center; }
.brand-moment svg.brand-moment-mark { inline-size: clamp(9rem, 24vw, 14rem); block-size: auto;
    filter: drop-shadow(0 8px 24px color-mix(in srgb, var(--brand) 22%, transparent)); }
/* The tagline ("Folded to fly."), not a caption: upright, weighted, near-heading scale — it names
   the mark above it. Set in the standard stack (the Inter Brand subset carries only the five
   wordmark glyphs, so using it here would fall back mid-line). */
.brand-moment-caption { color: var(--text); font-weight: 600; font-size: clamp(1.2rem, 1.05rem + 0.8vw, 1.5rem); letter-spacing: -0.01em; margin: 0.6rem 0 1.9rem; }

.danger-zone { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }

/* ------------------------------ API keys -------------------------------- */
.keys-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.keys-table th, .keys-table td { text-align: start; padding: 0.65rem 0.6rem; border-bottom: 1px solid var(--border); }
.keys-table th { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); }
.keys-table code { font-family: var(--font-mono); font-size: 0.85em; }
.key-reveal { display: block; margin-top: 0.5rem; padding: 0.6rem 0.75rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); font-family: var(--font-mono); word-break: break-all; user-select: all; }
.danger { color: var(--danger); }

/* ------------------------------ Legal ----------------------------------- */
.legal h2 { font-size: 1.2rem; margin: 1.75rem 0 0.5rem; }
.legal p, .legal li { color: var(--text); }
.legal ul { margin: 0.5rem 0 0.5rem 1.25rem; display: flex; flex-direction: column; gap: 0.35rem; }
/* "English governs" notice on legal pages: shown for non-English UI, hidden for English. Follows the
   <html lang> the i18n switcher sets, so it toggles on the no-postback language change (no JS needed). */
.legal-lang-notice {
    margin: 0 0 1.5rem;
    padding: 0.7rem 0.9rem;
    border-inline-start: 3px solid var(--brand);
    background: rgba(79, 70, 229, 0.06);
    border-radius: 0.4rem;
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--text);
}
html[lang="en"] .legal-lang-notice { display: none; }

/* ------------------------------- FAQ ------------------------------------ */
/* Breathing room under the "Questions, answered" title (owner: the first card sat too close). */
.faq { max-width: 720px; margin: 1.75rem auto 0; display: flex; flex-direction: column; gap: 0.75rem; }
.faq details { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 0 1.1rem; }
.faq summary { cursor: pointer; font-weight: 600; padding: 1rem 0; list-style: none; display: flex; justify-content: space-between; align-items: center; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--text-muted); font-size: 1.25rem; }
.faq details[open] summary::after { content: "−"; }
.faq details p { padding-bottom: 1rem; color: var(--text-muted); }

/* ------------------------------ App shell ------------------------------- */
/* The search bar shares the marketing header's geometry contract (--header-height + the same
   block padding): navigating landing ⇄ search keeps the brand mark at the SAME pixel (owner,
   2026-08-01 — the bar used to be content-sized and sat a few px taller, so the logo hopped).
   min-height (not height) still lets text zoom / EA-badge wrap grow the bar; the :has() flex-fill
   below remains the exact-fit mechanism for those grown cases. */
.app-bar { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem 1rem;
    flex-wrap: wrap; min-height: var(--header-height); padding: 0.5rem 1.25rem;
    border-bottom: 1px solid var(--border); }
/* The outlet cell: empty (and collapsed) on non-results pages; on results it carries the compact box.
   Below 64em it wraps to its own full-width line (Google mobile's shape); at ≥64em the single row forms and
   the box's start edge lands EXACTLY on the results spine (inset minus the bar's own padding). */

/* Early-adopter badge on the logo: a small, understated star marker shown only for early-adopter members.
   In-flow (a flex child of .brand-mark, which provides the gap) so it contributes to width and never overflows
   the header on reflow; sized in em (scales with the wordmark + the OS font, no fixed px); RTL-safe via the
   logical margin (none here — the flex gap handles spacing in both directions). */
.ea-badge {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 1.15em; height: 1.15em; border-radius: 50%;
    /* early-adopter GOLD (owner: distinct from brand) + a pinch downward (owner-tuned optical seat) */
    color: #f5b942;
    background: color-mix(in srgb, #f5b942 16%, transparent);
    margin-block-start: 0.08em;
}
.ea-badge-icon { width: 0.8em; height: 0.8em; display: block; }
/* Inline nav-item glyph (Settings/Account/Sign out in the search header). em-sized so it scales with the
   OS/text-zoom font; flex:none keeps it from shrinking. The .btn parent already supplies inline-flex +
   align-items:center + a logical gap, so the icon sits beside the label and the pair flips correctly in RTL. */
.nav-ico { inline-size: 1.1em; block-size: 1.1em; flex: none; }
/* The signed-in start screen. It stages the shared <SilkCurrent /> ribbons (.hero-bands, absolute
   inset:0) behind the search box: position:relative anchors the layer and the :not() lift keeps
   the box + suggestions above it. NO overflow:hidden here — the silk SVGs self-clip (UA default
   svg overflow + the slice crop), so nothing escapes the stage, and clipping the stage would
   truncate the autosuggest dropdown. */
.search-home { min-height: calc(100vh - 4rem); min-height: calc(100svh - 4rem); position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.25rem; text-align: center; padding: 2rem 1.25rem clamp(4rem, 16vh, 12rem); }
/* Full-viewport WITHOUT assuming the bar's height: the bar now MEETS the 4rem token at normal
   zoom (shared --header-height contract), but text zoom or an EA-badge wrap can still grow it past
   the token, so the calc() above can over-shoot and leave a phantom scrollbar. When
   the layout holds the start screen, make the page the column instead: body fills the small viewport,
   main takes whatever the bar leaves, .search-home fills main — exact by construction. The calc()
   rule stays as the fallback for engines without :has(); min-height must yield to the flex fill or
   it would re-introduce the overshoot it exists to approximate. Under text zoom the content's own
   min-content height wins and the page scrolls, which is the correct reflow behavior. */
body:has(> main > .search-home) { min-height: 100svh; display: flex; flex-direction: column; }
body:has(> main > .search-home) > main { flex: 1; display: flex; flex-direction: column; min-height: 0; }
body:has(> main > .search-home) .search-home { flex: 1; min-height: 0; }
.search-home > :not(.hero-bands) { position: relative; z-index: 1; }

/* ------------------------------ Search pill ----------------------------- */
/* The form is a two-row STACK — the bar row (back affordance + pill) and, when a view is active,
   the under-row carrying the view chip. The FORM is the autosuggest anchor (position:relative +
   data-autosuggest-anchor), so the .sc-suggest panel opens below the WHOLE stack: the chip stays
   on-screen while autocomplete is open, by construction. */
.search-form { display: flex; flex-direction: column; gap: 0.4rem; width: 100%; max-width: 640px; margin: 0 auto; position: relative; }
.search-bar { display: flex; gap: 0.5rem; align-items: center; width: 100%; }
.search-pill {
    flex: 1; min-width: 0; display: flex; align-items: center; gap: 0.5rem;
    background: var(--input-bg); border: 1px solid var(--control-border); border-radius: var(--radius-pill);
    /* End + block padding are EQUAL on purpose: the Search button lives INSIDE the pill at its far
       end (flat start edge, pill-rounded outer edge) and stretches to the row, so the gap above,
       below and beside it reads as one even hairline. */
    padding: 0.25rem 0.25rem 0.25rem 0.4rem; transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.search-pill:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent); }
.search-pill-icon { color: var(--text-subtle); display: inline-flex; flex: none; }
/* "+" menu — replaces the magnifier on the left of the pill; a hover-darkening circle that opens a popup of
   search modes (verticals) + time filters. Native <details>; items are no-JS submit buttons. */
.search-plus { position: relative; display: inline-flex; flex: none; }
.search-plus-btn {
    display: inline-flex; align-items: center; justify-content: center; inline-size: 2rem; block-size: 2rem;
    border-radius: 50%; cursor: pointer; list-style: none; color: var(--text-subtle); background: transparent;
    border: 0; padding: 0; transition: background 0.12s ease, color 0.12s ease;
}
.search-plus-btn::-webkit-details-marker { display: none; }
.search-plus-btn::marker { content: ""; }
.search-plus-btn:hover, .search-plus[open] > .search-plus-btn { background: var(--surface-2); color: var(--text); }
.search-plus-btn:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }
/* SVG glyphs (one stroke family with the camera/magnifier): deterministic geometry, flex-centered
   — no font-baseline nudges, ever. */
.search-plus-ico { inline-size: 1.25rem; block-size: 1.25rem; display: block;
    fill: none; stroke: currentColor; stroke-width: 2.1; stroke-linecap: round; }
.search-clear-ico { inline-size: 1rem; block-size: 1rem; display: block;
    fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.search-plus-menu {
    /* min() caps the panel at the viewport: at 200% text a fixed 13rem (=416px) would force horizontal
       scroll — and Chromium keeps a CLOSED details' content BOX in layout (content-visibility:hidden),
       so an oversized panel phantom-overflows the page even while the menu is shut. */
    position: absolute; inset-block-start: calc(100% + 0.5rem); inset-inline-start: 0; z-index: 45;
    min-inline-size: min(13rem, calc(100vw - 1.5rem));
    background: var(--surface, #fff); color: var(--text, #19172a); border: 1px solid var(--border, #ddd); border-radius: var(--radius);
    box-shadow: var(--shadow-lg, 0 16px 48px rgba(16,12,40,.16)); padding: 0.35rem; display: flex; flex-direction: column; gap: 0.05rem;
    /* The menu grew (verticals + views + times + actions): scroll inside itself rather than clip on
       short handsets or at 200% text. vh fallback then dvh (dynamic-toolbar-aware) — house pattern. */
    max-block-size: calc(100vh - 6rem); max-block-size: calc(100dvh - 6rem); overflow-y: auto; overscroll-behavior: contain;
}
.search-plus-group { display: flex; flex-direction: column; gap: 0.05rem; }
/* The active view reads pressed (explicit-string aria-pressed — Blazor minimizes BOOL attribute
   values into invalid ARIA, so the markup binds literal "true"/"false"). */
.search-plus-item[aria-pressed="true"] { font-weight: 600; color: var(--brand-strong); }
.search-plus-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); padding: 0.3rem 0.55rem 0.2rem; }
.search-plus-item {
    display: flex; align-items: center; gap: 0.5rem; inline-size: 100%; text-align: start; background: transparent;
    border: 0; cursor: pointer; padding: 0.45rem 0.55rem; border-radius: var(--radius-sm, 6px); color: var(--text); font: inherit; text-decoration: none;
}
.search-plus-item:hover, .search-plus-item:focus { background: var(--surface-2); outline: none; }
.search-plus-item:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: -2px; }
.search-plus-divider { border: 0; border-block-start: 1px solid var(--border); margin: 0.3rem 0.1rem; }
.search-pill-input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; color: var(--text); font: inherit; padding: 0.5rem 0; }   /* min-width:0 — an input's implicit min-width:auto would refuse to shrink and force page overflow at 200% text */
.search-pill-input::placeholder { color: var(--text-subtle); }
/* The upgraded multiline field (20-search swaps the server's <input> for this textarea): visual
   wrapping only — no manual resize, no scrollbars. Height is owned EXCLUSIVELY by the JS autosize
   (deliberately NOT field-sizing:content — native growth lands before input handlers run, which
   made the reflow-free overlay's freeze-then-detach measurement impossible; one JS code path
   behaves identically in every engine). */
textarea.search-pill-input { resize: none; overflow: hidden;
    line-height: 1.5; display: block; }
/* HOME multiline (owner): the text owns the pill's full width and the controls drop to their own
   row pinned to the pill's BOTTOM edge — first overflow moves them down two visual positions
   (line 2 appears + the row forms beneath it). Grid keeps one DOM order for both states. */
.search-form:not(.compact)[data-multiline] .search-pill { display: grid;
    grid-template-columns: auto 1fr auto auto; border-radius: var(--radius-lg); }
.search-form:not(.compact)[data-multiline] .search-pill > textarea.search-pill-input {
    grid-row: 1; grid-column: 1 / -1; padding-inline: 0.5rem; }
.search-form:not(.compact)[data-multiline] .search-pill > .search-plus { grid-row: 2; grid-column: 1; }
.search-form:not(.compact)[data-multiline] .search-pill > .search-pill-clear { grid-row: 2; grid-column: 3; }
.search-form:not(.compact)[data-multiline] .search-pill > .search-pill-camera { grid-row: 2; grid-column: 4; }
/* RESULTS multiline (owner): controls NEVER move — they pin to the first line's band while the
   text wraps beside them; the expanded pill is an OVERLAY painting over the results rather than
   reflowing them (the wrapper reserves the one-line height; z 42 sits above the suggest panel's
   40 and the chip row's 41, below the 45 menus and the sticky header's 50). Collapsed (blurred or
   keyboard-focused) the field is forced back to a single line. */
.results-search { position: relative; }
.results-search .search-form.compact { position: relative; z-index: 42; }
.search-form.compact[data-multiline] .search-pill { align-items: flex-start; }
.search-form.compact:not([data-expanded]) textarea.search-pill-input {
    height: 2.5rem; white-space: nowrap; }
/* The overlay mechanics: the BAR keeps its one-line flow height (so tabs/results never move) and
   the pill inside it goes absolute, growing DOWNWARD over the page. The exact height is measured
   at expansion time by 20-search (--pill-bar-reserve) — a hand-derived constant was 1-2px off the
   tallest child (the seat button) and nudged the tabs. */
.search-form.compact[data-expanded][data-multiline] .search-bar {
    position: relative; block-size: var(--pill-bar-reserve, calc(2.8rem + 2px)); }
.search-form.compact[data-expanded][data-multiline] .search-pill {
    position: absolute; inset-inline: 0; inset-block-start: 0; z-index: 1;
    box-shadow: var(--shadow-lg); border-radius: var(--radius-lg); }

.search-pill-clear { inline-size:2rem; block-size:2rem; align-items:center; justify-content:center;
    border: none; background: transparent; color: var(--text-subtle); cursor: pointer; font-size: 1rem; padding: 0; border-radius: 50%; display: none; }
.search-pill-clear.visible { display: inline-flex; }
/* Signed-in chrome: collapse the header's right-side controls into a top-right hamburger + vertical panel. */
.header-menu { position: relative; display: inline-flex; }
.header-menu-btn {
    display: inline-flex; align-items: center; justify-content: center; inline-size: 2.75rem; block-size: 2.75rem;
    border-radius: var(--radius); background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
    cursor: pointer; list-style: none; padding: 0;
}
.header-menu-btn::-webkit-details-marker { display: none; }
.header-menu-btn::marker { content: ""; }
.header-menu-btn:hover { background: var(--surface); }
.header-menu-btn:focus-visible { outline: 2px solid var(--ring, var(--brand-strong)); outline-offset: 2px; }
.header-menu[open] .nav-toggle-bars { background: transparent; }
.header-menu[open] .nav-toggle-bars::before { transform: translateY(0.4rem) rotate(45deg); }
.header-menu[open] .nav-toggle-bars::after { transform: translateY(-0.4rem) rotate(-45deg); }
.header-menu-panel {
    /* min() caps the panel at the viewport: at 200% text a fixed 13rem (=416px) would force horizontal
       scroll — and Chromium keeps a CLOSED details' content BOX in layout (content-visibility:hidden),
       so an oversized panel phantom-overflows the page even while the menu is shut. Same treatment as
       .search-plus-menu; the block cap makes the grown menu scroll inside itself on short handsets. */
    position: absolute; inset-block-start: calc(100% + 0.4rem); inset-inline-end: 0; z-index: 50;
    min-inline-size: min(13rem, calc(100vw - 1.5rem));
    background: var(--surface, #fff); color: var(--text, #19172a); border: 1px solid var(--border, #ddd); border-radius: var(--radius);
    box-shadow: var(--shadow-lg, 0 16px 48px rgba(16,12,40,.16)); padding: 0.4rem; display: flex; flex-direction: column; gap: 0.1rem;
    max-block-size: calc(100vh - 6rem); max-block-size: calc(100dvh - 6rem); overflow-y: auto; overscroll-behavior: contain;
}
.header-menu-panel .btn { inline-size: 100%; justify-content: flex-start; gap: 0.55rem; }
.header-menu-panel form { inline-size: 100%; margin: 0; }
.header-menu-section { padding: 0.15rem 0.4rem 0.4rem; }
.header-menu-label { display: block; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); padding: 0.15rem 0.15rem 0.35rem; }
/* Theme segmented in the header dropdown: three EQUAL options that fill the panel and stay on ONE line at
   normal font. The base 0.8rem option padding is a razor-tight fit for "System" in a 13rem panel (~196px of
   buttons in ~195px of panel) — Firefox's wider text metrics tip it into a wrap. flex:1 1 0 = equal thirds;
   tighter side padding buys slack; nowrap keeps the single word intact; overflow-x lets it scroll (never
   wrap/clip) when the OS font is enlarged. */
.header-menu-seg { inline-size: 100%; overflow-x: auto; }
.header-menu-seg .segmented-option { flex: 1 1 0; padding-inline: 0.4rem; white-space: nowrap; }
.header-menu-divider { border: 0; border-block-start: 1px solid var(--border); margin: 0.3rem 0.1rem; }
.header-menu-switch {
    display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; inline-size: 100%;
    background: transparent; border: 0; cursor: pointer; padding: 0.45rem 0.5rem; border-radius: var(--radius-sm, 6px);
    color: var(--text); font: inherit; text-align: start;
}
.header-menu-switch:hover { background: var(--surface-2, #f3efe4); }
.header-menu-switch:focus-visible { outline: 2px solid var(--ring, var(--brand-strong)); outline-offset: -2px; }
/* Scoped to .header-menu-switch: the view/settings switch (.switch + .switch-thumb, app.css) shares the
   .switch-thumb class, so an UNSCOPED .switch-thumb here would bleed onto it (wrong size + a leftover
   translateY(-50%) made the thumb straddle the track). Keep these track/thumb styles to the header menu only. */
.header-menu-switch .switch-track {
    flex: none; inline-size: 2.2rem; block-size: 1.25rem; border-radius: 999px; background: var(--border-strong, #c4bca7);
    position: relative; transition: background 0.15s ease;
}
.header-menu-switch .switch-thumb {
    position: absolute; inset-block-start: 0.15rem; inset-inline-start: 0.15rem; inline-size: 0.95rem; block-size: 0.95rem;
    border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.3); transition: inset-inline-start 0.15s ease;
}
.header-menu-switch[aria-checked="true"] .switch-track { background: var(--brand); }
.header-menu-switch[aria-checked="true"] .switch-thumb { inset-inline-start: 1.1rem; }
@media (prefers-reduced-motion: reduce) { .header-menu-switch .switch-track, .header-menu-switch .switch-thumb { transition: none; } }
.search-pill-clear:hover { background: var(--surface-2); color: var(--text); }
/* The Search button lives OUTSIDE the pill (owner, 2026-08-01: pill width belongs to the query).
   TWO SEATS for the one server-rendered button, chosen per surface:
   — HOME (non-compact): its own centered flow row under the bar (pill-round, icon + visible label).
   — RESULTS (compact): absolutely seated back on the pill's inside end (icon-only, the historic
     asymmetric radii), with the pill reserving its width so the input never runs beneath it.
   While the autosuggest panel is open the seat hides entirely and the panel's own footer submit
   (rendered by 32-autosuggest for [data-suggest-submit] forms) takes over — the Google pattern:
   the panel can never cover the button because the button is IN the panel. */
.search-submit { display: inline-flex; align-items: center; gap: 0.5rem;
    position: absolute; inset-block-start: 100%; inset-inline-start: 50%;
    translate: -50% 0; margin-block-start: 1.1rem;
    border-radius: 0.5rem; padding: 0.5rem 1.35rem; }
html[dir="rtl"] .search-submit { translate: 50% 0; }
.search-submit-label { font-size: 0.92rem; font-weight: 600; }
/* Compact (results) submit is a GHOST icon button (owner, 2026-08-01: the filled background's
   flattened-edge radii could never track the pill's expanded corner radius without growing the
   button down the field — Google's SERP magnifier is backgroundless for the same reason). EVERY
   property of the home seat's floating geometry stays neutralized (translate included — it
   applies to static elements too; the leaked -50% was the earlier regression). Expansion moves
   no in-pill control by a pixel: the multiline margins equal each control's centered offset in
   the resting one-line pill. */
.search-form.compact .search-submit { position: static; margin: 0; flex: none;
    inset: auto; translate: none; align-self: center;
    inline-size: 2.4rem; block-size: 2.4rem; padding: 0; border: 0; border-radius: 50%;
    background: transparent; color: var(--text-muted);
    display: inline-flex; align-items: center; justify-content: center; }
.search-form.compact .search-submit:hover { background: color-mix(in srgb, var(--brand-strong) 16%, transparent); color: var(--text); }
html[dir="rtl"] .search-form.compact .search-submit { translate: none; }
/* Expansion must not move ANY in-pill control by a pixel (owner): flex-start pins them to the
   top band, and 20-search stamps each control's MEASURED resting offset as an inline margin at
   the same synchronous pre-flip beat as the bar freeze (hand-derived constants missed by a few
   px — the true offsets depend on which controls are present). */
.search-form.compact[data-multiline] .search-submit { align-self: flex-start; block-size: 2.4rem; }
/* STABILITY (owner, 2026-08-01): the pill's TOP EDGE never moves — not when the panel opens, not
   as the multiline field grows. Two mechanisms:
   (1) the seat keeps its BOX while the panel is open (visibility, not display — display:none
       shrank the form and flex-centering re-centered it, dropping the pill ~28px);
   (2) the home form is TOP-ANCHORED absolutely (below) instead of flex-centered, so any height
       change — panel, seat, line growth — extends strictly DOWNWARD. The offset approximates the
       old centered resting position at common viewport heights; the anchored handset takeover is
       excluded (its fixed-position rules own that geometry). */
.search-form:not(.compact)[data-suggest-open] .search-submit { visibility: hidden; pointer-events: none; }
.search-home .search-form:not(.compact):not(.is-anchored) {
    position: absolute; inset-block-start: clamp(9rem, 34svh, 22rem);
    inset-inline: 0; margin-inline: auto; }
.search-submit-ico { display: block; width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }

/* The active view's chip — rides the UNDER-ROW below the field (the pill's horizontal space is for
   the query); its ✕ re-runs the search without the view. Long names ellipsize. The under-row is
   part of the form stack, so the autosuggest panel (anchored to the form) opens BELOW it and the
   chip stays visible while suggestions are up. */
/* The under-row has a FIXED rem block-size: the suggest panel pulls up by exactly this amount when a chip
   exists (below), so the chip's vertical position is IDENTICAL whether the panel is open or closed — the
   panel wraps the row rather than pushing it. Single-line rem-sized content fits at every text zoom. */
.search-under { display: flex; align-items: center; gap: 0.4rem; padding-inline-start: 0.4rem; block-size: 2.1rem; position: relative; z-index: 41; }
/* The lead-in shown only while the panel is open ("Searching in · <chip>") — the allowed horizontal shift. */
.search-under-prefix { display: none; font-size: 0.8rem; color: var(--text-muted); white-space: nowrap; }
.search-form[data-suggest-open] .search-under-prefix { display: inline; }
.search-form[data-suggest-open] .search-under { padding-inline-start: 0.75rem; }   /* align with the panel's items */
/* Integrate the chip row INTO the open panel: the panel rises by the under-row's exact height and pads its
   top by the same amount, so its first band IS the chip row (which, being z-raised and absolutely untouched,
   keeps its exact Y and a live ✕). No chip ⇒ the base geometry below the form applies unchanged. */
.search-form[data-suggest-open]:has(.search-under) .sc-suggest {
    inset-block-start: calc(100% - 2.5rem);
    padding-block-start: 2.5rem;
}
.search-form.is-anchored[data-suggest-open]:has(.search-under) .sc-suggest {
    max-block-size: calc(var(--search-vvh, 100dvh) - var(--search-anchor-bottom, 5.25rem) - 0.25rem + 2.1rem);
}
.search-view-chip {
    flex: none; display: inline-flex; align-items: center; gap: 0.15rem;
    padding: 0.15rem 0.25rem 0.15rem 0.65rem;
    background: var(--brand-soft); color: var(--brand-strong);
    border-radius: var(--radius-pill); font-size: 0.8rem; font-weight: 600; max-width: 10rem;
}
[dir="rtl"] .search-view-chip { padding: 0.15rem 0.65rem 0.15rem 0.25rem; }
.search-view-chip-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-view-chip-x {
    flex: none; display:inline-flex; align-items:center; justify-content:center;
    inline-size:1.75rem; block-size:1.75rem; border: 0; background: transparent; color: inherit; cursor: pointer;
    font-size: 0.72rem; line-height: 1; padding: 0; border-radius: 50%;
}
.search-view-chip-x:hover { background: color-mix(in srgb, var(--brand-strong) 18%, transparent); }
.search-view-chip-x:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }

/* Post-navigation result focus is always QUIET (owner, 2026-07-31 — Google parity: a results page
   never LOOKS pre-selected). 20-search adds .focus-quiet to its own programmatic focus only; the
   accessible behavior is unchanged (screen readers announce the focused result; Tab continues from
   it), and a real Tab press moves focus onward where the browser paints its normal :focus-visible
   ring — so keyboard users reveal their position with one keystroke and user-driven focus is never
   suppressed (WCAG 2.4.7). Deliberately NOT a focus-visible-negation rule: engines classify late
   programmatic focus erratically, and that selector's failure mode silences the KEYBOARD ring on
   user-driven focus too. Scoped class + blur cleanup fails the safe way (a spurious ring). */
.focus-quiet:focus { outline: none; }

/* The site menu's appearance block hides under the account-synced preference (default on = attr absent). */
:root[data-menu-appearance="off"] .header-menu-appearance { display: none; }

/* ---- Reverse image search (camera button, capture sheet, results) ---- */
.search-pill-camera {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    inline-size: 2.75rem; block-size: 2.75rem; margin-inline-end: 0.15rem; border-radius: 50%;
    color: var(--text-muted); text-decoration: none; cursor: pointer;
}
.search-pill-camera:hover { color: var(--text); background: var(--surface-2); }
.search-pill-camera:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }
.search-camera-ico { inline-size: 1.15rem; block-size: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }

body.lens-sheet-open { overflow: hidden; }
dialog.lens-sheet {
    position: fixed; inset: 0; z-index: var(--z-modal, 10000); display: flex; align-items: center; justify-content: center;
    inline-size: 100%; block-size: 100%; max-inline-size: none; max-block-size: none; margin: 0;
    padding: 1rem; border: 0; background: transparent; color: var(--text);
}
dialog.lens-sheet::backdrop { background: color-mix(in srgb, #000 55%, transparent); }
.lens-sheet-panel {
    inline-size: min(30rem, 100%); max-block-size: min(90vh, 90dvh); overflow-y: auto;
    background: var(--surface); color: var(--text); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: 1rem;
    display: flex; flex-direction: column; gap: 0.75rem;
}
.lens-sheet.is-busy .lens-sheet-panel { opacity: 0.6; pointer-events: none; }
.lens-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.lens-sheet-head h2 { font-size: 1.05rem; margin: 0; }
.lens-sheet-close { display:inline-flex; align-items:center; justify-content:center; inline-size:2.75rem; block-size:2.75rem;
    border: 0; background: transparent; color: var(--text-muted); cursor: pointer; font-size: 1rem; padding: 0; border-radius: 50%; }
.lens-sheet-close:hover { color: var(--text); background: var(--surface-2); }
.lens-sheet-cam { display: flex; flex-direction: column; gap: 0.5rem; }
.lens-sheet-cam video { inline-size: 100%; border-radius: var(--radius-sm); background: #000; aspect-ratio: 4 / 3; object-fit: cover; }
.lens-sheet-btn { inline-size: 100%; white-space: normal; }
.lens-sheet-url { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.lens-sheet-url .field-input { flex: 1 1 12rem; min-inline-size: 0; }
.lens-sheet-status { font-size: 0.8125rem; margin: 0; min-block-size: 1.2rem; }
.lens-sheet-privacy { font-size: 0.75rem; margin: 0; border-block-start: 1px solid var(--border); padding-block-start: 0.6rem; }

.lens-page { padding: 1.25rem; max-inline-size: 72rem; }
.lens-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; margin-block-end: 1rem; }
.lens-head-text { min-inline-size: 0; }
.lens-h1 { font-size: 1.35rem; margin: 0; }
.lens-h1:focus { outline: none; }
.lens-sub { font-size: 0.85rem; margin: 0.15rem 0 0; }
.lens-thumb { flex: none; }
.lens-thumb img { max-inline-size: 8rem; max-block-size: 8rem; border-radius: var(--radius-sm); border: 1px solid var(--border); display: block; }
.lens-alert { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.lens-count { font-size: 0.85rem; margin-block-end: 0.75rem; display: flex; gap: 0.3rem; }
.lens-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 0.9rem; }
.lens-card {
    display: flex; flex-direction: column; gap: 0.5rem; text-decoration: none; color: inherit; min-inline-size: 0;
    border: 1px solid var(--border); border-radius: var(--radius); padding: 0.6rem; background: var(--surface);
}
.lens-card:hover { border-color: var(--border-strong); background: var(--surface-2); }
.lens-card:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 2px; }
.lens-card-thumb { aspect-ratio: 4 / 3; overflow: hidden; border-radius: var(--radius-sm); background: var(--surface-2); }
.lens-card-thumb img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
.lens-card-title { font-size: 0.9rem; font-weight: 600; overflow-wrap: anywhere; }
.lens-card-source { font-size: 0.78rem; color: var(--success); overflow-wrap: anywhere; }
.lens-card-price { font-size: 0.85rem; font-weight: 600; }
.lens-chooser { display: flex; flex-wrap: wrap; gap: 1rem; }
.lens-choice {
    flex: 1 1 18rem; min-inline-size: 0; display: flex; flex-direction: column; gap: 0.6rem; align-items: flex-start;
    border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem; background: var(--surface);
}
.lens-choice-h { font-size: 1rem; margin: 0; }
.lens-choice .field-input { inline-size: 100%; }
.lens-privacy { font-size: 0.8rem; margin-block-start: 1rem; }

/* compact variant for the results header */
.search-form.compact { max-width: none; margin: 0; }
.search-form.compact .search-pill { padding: 0.2rem 0.2rem 0.2rem 0.4rem; }

/* ------------------- Handset anchored search (21-search-anchor.ts) -------------------
   Google-style takeover on narrow viewports: focusing the input pins the whole form stack to the
   top of the screen, an opaque backdrop covers the page, and the suggestions get the remaining
   height. JS-only enhancement — without JS none of these classes ever appear. The 34em query in
   the module is the SAME em breakpoint as the nav hamburger (reflow mandate). */
html.search-anchored { overflow: hidden; }                       /* scroll lock — docs-cmdk precedent */
.search-anchor-back { display: none; }                           /* dormant outside anchored mode (and for no-JS) */
.search-anchor-backdrop { position: fixed; inset: 0; z-index: calc(var(--z-modal) - 1); background: var(--bg); }
.search-form.is-anchored {
    position: fixed; inset-block-start: 0; inset-inline: 0; z-index: var(--z-modal);
    max-width: none; margin: 0;
    padding: 0.5rem 0.75rem; padding-block-start: max(0.5rem, env(safe-area-inset-top));
    background: var(--bg-elevated);
    animation: search-anchor-in 0.16s ease-out;                  /* global reduced-motion kill-switch nulls this */
}
@keyframes search-anchor-in { from { opacity: 0; transform: translateY(-0.4rem); } }
.search-form.is-anchored .search-anchor-back {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    inline-size: 2.25rem; block-size: 2.25rem; border-radius: 50%;
    border: 0; padding: 0; background: transparent; color: var(--text-subtle); cursor: pointer;
}
.search-form.is-anchored .search-anchor-back:hover { background: var(--surface-2); color: var(--text); }
.search-anchor-back:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }
.search-anchor-back-ico { inline-size: 1.15rem; block-size: 1.15rem; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
[dir="rtl"] .search-anchor-back-ico { transform: scaleX(-1); }   /* .sc-back precedent */
/* Suggestions own the takeover surface: full bar width, room down toward the keyboard, full-bleed
   list (no card chrome). dvh tracks the Android WebView's adjustResize viewport; on iOS the keyboard
   OVERLAYS the layout viewport, so 21-search-anchor.ts mirrors visualViewport.height into
   --search-vvh while anchored — and the form's MEASURED bottom into --search-anchor-bottom — so the
   final declaration caps the panel EXACTLY flush against the keyboard (viewport minus the real
   header stack minus the 0.25rem panel gap) at any text size, with or without the chip row.
   Degradation chain: no JS ⇒ no anchored mode and no panel at all (plain GET form); JS but a var
   missing ⇒ falls back to 100dvh / the 5.25rem header estimate (≈ the old fixed 5.5rem cap);
   older engines without var() take the plain vh/dvh lines above. */
.search-form.is-anchored .sc-suggest {
    inset-inline: 0; max-width: none;
    max-block-size: calc(100vh - 5.5rem); max-block-size: calc(100dvh - 5.5rem);
    max-block-size: calc(var(--search-vvh, 100dvh) - var(--search-anchor-bottom, 5.25rem) - 0.25rem);
    overflow-y: auto; overscroll-behavior: contain;
    border-inline: 0; border-radius: 0; box-shadow: none;
}

/* ------------------------------ Results --------------------------------- */
.results-search { padding: 1rem 1.25rem; border-bottom: 1px solid var(--border); background: var(--bg-elevated); padding-inline-start: var(--results-inset); }
.results-search .search-form.compact { max-width: var(--results-measure); }
/* ═══ Results spine (Google/Kagi/Bing geometry): everything on ONE start-aligned vertical axis. ═══
   --results-inset is the start gutter shared by the header search box, tabs, filters, and results.
   Logical properties throughout — RTL mirrors automatically. Text verticals read at a 44rem measure;
   media verticals (.is-media: images/videos/shopping) earn 74rem. The freed end side stays clean
   (the future knowledge-rail slot). */
:root { --results-inset: 1.25rem; --results-measure: 44rem; --results-measure-wide: 74rem; }
@media (min-width: 48em) { :root { --results-inset: 2.5rem; } }
@media (min-width: 64em) { :root { --results-inset: clamp(8rem, 10vw, 10.5rem); } }

.results-wrap { max-width: none; margin: 0; padding: 1rem 1.25rem 4rem; padding-inline-start: var(--results-inset); }
.results-wrap > * { max-width: var(--results-measure); }
/* chrome rows span the wide line on every vertical, so the tab/filter axis never jumps between verticals;
   the square-layout tile grid is media-forward, so it earns the wide measure too */
.results-wrap > .search-tabs, .results-wrap > .results-controls,
.results-wrap > .active-filters, .results-wrap > .results-grid { max-width: var(--results-measure-wide); }
.results-wrap.is-media > * { max-width: var(--results-measure-wide); }

/* vertical tabs */
.search-tabs { display: flex; gap: 0.25rem; border-bottom: 1px solid var(--border); margin-bottom: 1.25rem; overflow-x: auto; }
.search-tab { padding: 0.6rem 0.9rem; font-weight: 600; font-size: 0.92rem; color: var(--text-muted); border-bottom: 2px solid transparent; white-space: nowrap; }
.search-tab:hover { color: var(--text); text-decoration: none; }
.search-tab.active { color: var(--brand); border-bottom-color: var(--brand); }
.search-tab.is-disabled { opacity: 0.45; cursor: not-allowed; }   /* kind with no live source (provider pivot) */

/* images grid */
.image-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.5rem; }
.image-cell { display: block; aspect-ratio: 3/2; border-radius: var(--radius); overflow: hidden; background: var(--surface-2); border: 1px solid var(--border); }
.image-cell img { width: 100%; height: 100%; object-fit: cover; }
.view-ico { width: 0.95rem; height: 0.95rem; flex: 0 0 auto; }

/* ===== Image VIEW MODES (Part C) — data-view-mode on #image-grid; each cell wrap carries --ar = width/height (fallback 1.5). GRID (default) = the rules above. ===== */
/* JUSTIFIED — Google-style variable-width rows filled to a shared height (flex-grow ∝ aspect). */
#image-grid[data-view-mode="justified"] { display: flex; flex-wrap: wrap; gap: 0.5rem; --rh: clamp(140px, 22vw, 200px); }
/* Flexbox-justified: basis = the image's NATURAL width at the row height (--ar × --rh) so a row fills then WRAPS;
   flex-grow ∝ aspect then justifies each row edge-to-edge (the last row stretches — standard). */
#image-grid[data-view-mode="justified"] > .image-cell-wrap { flex: calc(var(--ar, 1.5)) 1 calc(var(--ar, 1.5) * var(--rh)); height: var(--rh); min-width: 0; }
/* MASONRY — Pinterest columns, full tile aspect, no shape crop. */
#image-grid[data-view-mode="masonry"] { display: block; column-width: 190px; column-gap: 0.5rem; }
#image-grid[data-view-mode="masonry"] > .image-cell-wrap { break-inside: avoid; margin: 0 0 0.5rem; aspect-ratio: var(--ar, 1.5); width: 100%; }
/* Justified/masonry: the WRAP defines the cell's shape (uniform row height / the image's true aspect) —
   the inner .image-cell must FILL it, never impose the grid mode's fixed 3:2 (which left justified rows
   ragged and masonry columns gapped). This override shipped with Part C and was LOST when the filmstrip
   mode retired: the removal took the shared three-mode rule down with it. Mode-scoped; grid untouched. */
#image-grid[data-view-mode="justified"] .image-cell,
#image-grid[data-view-mode="masonry"] .image-cell { aspect-ratio: auto; width: 100%; height: 100%; }

/* video / shopping cards */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 1rem; }
.media-card { display: block; color: inherit; }
.media-card:hover { text-decoration: none; }
.media-card:hover .media-title { color: var(--brand); }
.media-thumb { position: relative; aspect-ratio: 16/9; border-radius: var(--radius); overflow: hidden; background: var(--surface-2); border: 1px solid var(--border); }
.media-thumb.shopping { aspect-ratio: 1/1; }
.media-thumb img { width: 100%; height: 100%; object-fit: cover; }
.media-badge { position: absolute; bottom: 6px; inset-inline-end: 6px; background: rgba(0,0,0,0.78); color: #fff; font-size: 0.72rem; font-weight: 600; padding: 0.1rem 0.35rem; border-radius: 4px; }
.media-title { font-weight: 600; font-size: 0.92rem; margin-top: 0.5rem; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.media-price { font-weight: 700; color: var(--text); margin-top: 0.2rem; }
.media-meta { color: var(--text-muted); font-size: 0.82rem; margin-top: 0.15rem; }
.media-body { min-width: 0; }

/* ═══ Results CONTROLS row — ONE line per vertical: re-search controls (time chips / filter selects) at the
   START, the presentation seg (view modes / Standard|Square layout) pushed to the END. The nav/form children
   keep their own internal behavior (incl. the 34em pills⇄menu collapse); this wrapper only owns the axis. ═══ */
.results-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; margin: 0.25rem 0 0.75rem; }
.results-controls > .view-seg { margin-inline-start: auto; }
/* When TWO presentation segs share the row (grouping + layout on web/news) only the FIRST takes the
   auto push — the sibling hugs it, keeping the pair together at the row's end. */
.results-controls > .view-seg ~ .view-seg { margin-inline-start: 0; }
.view-seg { display: inline-flex; flex-wrap: wrap; gap: 0.15rem; padding: 0.2rem; background: var(--surface-2); border: 1px solid var(--control-border); border-radius: var(--radius-pill); }
.view-opt { display: inline-flex; align-items: center; gap: 0.35rem; min-width: 0; min-block-size: 2rem; white-space: nowrap; cursor: pointer; font-size: 0.8125rem; color: var(--text-muted); background: transparent; border: 0; border-radius: var(--radius-pill); padding: 0.25rem 0.7rem; }
.view-opt:hover { color: var(--text); }
.view-opt.active { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); color: var(--text); box-shadow: inset 0 0 0 1px var(--accent); }
.view-opt:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }
.view-ico { width: 0.95rem; height: 0.95rem; flex: 0 0 auto; }
.view-ico rect { fill: currentColor; }

/* LIST mode — a dense horizontal row: thumbnail left, title/price/meta flowing right. Grid mode stays untouched. */
.card-grid[data-view-mode="list"] { grid-template-columns: 1fr; gap: 0.5rem; }
.card-grid[data-view-mode="list"] .media-card { display: flex; gap: 0.9rem; align-items: flex-start; }
.card-grid[data-view-mode="list"] .media-thumb { flex: 0 0 118px; }
.card-grid[data-view-mode="list"] .media-thumb.shopping { flex-basis: 84px; }
.card-grid[data-view-mode="list"] .media-body { flex: 1 1 auto; }
.card-grid[data-view-mode="list"] .media-body > :first-child { margin-top: 0; }

/* ═══ Square layout — a media-forward tile GRID (web + news render through it; the standard row list is the
   sibling layout). Column count derives from a rem minimum, so OS text zoom grows tiles into FEWER columns
   (reflow, never overflow) and phone widths converge on one column. Cards stretch per grid row; the meta line
   pins to the card FOOT so a row of sources reads level. ═══ */
.results-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr)); gap: 1.4rem 1.1rem; padding-block: 0.25rem 0.5rem; }
.sq-card { display: flex; flex-direction: column; min-width: 0; }
.sq-media { position: relative; aspect-ratio: 4 / 3; border-radius: var(--radius); overflow: hidden; background: var(--surface-2); border: 1px solid var(--border); }
.sq-media-link { display: block; block-size: 100%; line-height: 0; }
.sq-thumb { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
/* No thumbnail → a stable host-tinted monogram tile (--tile-hue is hashed from the host server-side; mixing
   against the theme's own surface/text keeps it legible in BOTH themes). */
.sq-fallback { display: flex; align-items: center; justify-content: center; block-size: 100%;
    background: color-mix(in oklab, hsl(var(--tile-hue) 65% 52%), var(--surface-2) 82%);
    color: color-mix(in oklab, hsl(var(--tile-hue) 65% 52%), var(--text) 40%);
    font-size: 2.4rem; font-weight: 700; user-select: none; }
.sq-body { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; padding-block-start: 0.55rem; }
.sq-card .result-title { font-size: 0.95rem; line-height: 1.35; margin-bottom: 0.2rem; }
.sq-card .result-desc { font-size: 0.85rem; }
/* Tiles bound their text so one verbose result can't stretch its whole grid row — DEFAULTS only: an explicit
   designer clamp (rt-clamp-*) wins. */
.sq-card .result-title:not([class*="rt-clamp"]), .sq-card .result-desc:not([class*="rt-clamp"]) {
    display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; -webkit-line-clamp: 3; }
.sq-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem; min-width: 0;
    margin-block-start: auto; padding-block-start: 0.5rem; color: var(--text-subtle); font-size: 0.8rem; }
.sq-meta-ico { inline-size: 1rem; block-size: 1rem; border-radius: 3px; flex: none; }
.sq-meta-src { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* The system tools overlay the MEDIA corner (the tools element is absolute at the CARD's top-end — the media
   block is the card's top, so they coincide) — never the text. Hover/focus-reveal like the image grid; a
   ranked card and touch devices keep them visible. */
.sq-card .result-card-tools { opacity: 0; transition: opacity 0.12s ease; }
.sq-card:hover .result-card-tools, .sq-card:focus-within .result-card-tools,
.sq-card .rank-control[open] { opacity: 1; }
.sq-card:has(.rank-chip-pinned, .rank-chip-raised, .rank-chip-lowered, .rank-chip-blocked) .result-card-tools { opacity: 1; }
@media (hover: none) { .sq-card .result-card-tools { opacity: 1; } }

/* flow-root: the rank-tools FLOAT (below) must never poke past a short row into the next result */
.result-item { padding: 1rem 0; border-bottom: 1px solid var(--border); position: relative; display: flow-root; }
.result-item:last-child { border-bottom: none; }

/* ═══ Site-grouped results (rank-faithful grouping) ═══
   The group header is deliberately NOT a result card: none of ITEM_SEL's classes, no rank chrome —
   every results-page module's sibling walk skips it. Members stay ordinary flat siblings; the tree
   is drawn purely with the per-member indent below. In a .results-grid the header spans the row. */
.result-group-head { display: flex; align-items: center; gap: 0.5rem; min-width: 0;
    padding: 0.85rem 0 0.35rem; font-size: 0.8125rem; color: var(--text-muted); }
.result-group-ico { width: 1rem; height: 1rem; flex: none; border-radius: 0.2rem; }
.result-group-host { font-weight: 700; color: var(--text); overflow-wrap: anywhere; min-width: 0; }
.result-group-count { flex: none; font-variant-numeric: tabular-nums; }
.results-grid > .result-group-head { grid-column: 1 / -1; padding-block: 0.25rem 0; }
/* Cluster members indent by tree depth (leader = 1). Logical margin → mirrors in RTL; rem-based →
   grows with text zoom; width shrinks with it, and the card's own reflow rules absorb the rest. */
.result-item[style*="--group-depth"] { margin-inline-start: calc((var(--group-depth) - 1) * 1.35rem);
    padding-inline-start: 0.9rem; border-inline-start: 2px solid var(--border); }
/* The SYSTEM rank badge (grouped mode): the member's true global rank, floated with the corner tools.
   Class of its own — renumberOrdinals targets .result-ordinal only and can never rewrite this. */
.result-rank { display: inline-block; margin-block-start: 0.35rem; vertical-align: top;
    font-size: 0.72rem; line-height: 1.5; color: var(--text-subtle);
    font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
    border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 0 0.45rem;
    margin-inline-end: 0.35rem; }
.result-rank::before { content: "#"; opacity: 0.6; }
/* The rank tools of a standard LIST row sit at the row's top-end as a FLOAT (kept position:relative so the
   ⋮ menu still anchors to the chips): floated, the title/summary LINE BOXES shorten beside the chips and
   wrap under them — text can NEVER render beneath the buttons, whatever rows the design template puts first
   and however far the user's text zoom grows them. (The old absolute overlay reserved only the FIRST row's
   end padding; any later row tall enough to reach the chips slid underneath — the reported overlap.) */
.result-item > .result-card-tools { position: relative; float: inline-end;
    inset-block-start: auto; inset-inline-end: auto; margin-inline-start: 0.75rem; margin-block-end: 0.25rem; }
/* "Number search results" pref (default OFF): a restrained, muted ABSOLUTE ordinal above each web result that
   continues across pages. In-flow + rem-based so it reflows and scales with OS text zoom (no fixed px); tabular
   numerals keep multi-digit numbers tidy. Decorative only (the markup marks it aria-hidden). */
.result-ordinal { font-size: 0.78rem; line-height: 1; color: var(--text-subtle); margin-bottom: 0.15rem;
    font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.result-ordinal::before { content: "#"; opacity: 0.6; margin-inline-end: 0.05rem; }
.result-url { font-size: 0.8rem; color: var(--success); margin-bottom: 0.15rem; word-break: break-all; }
.result-date { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 0.15rem; }
.result-sitelinks { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: 0.1rem 1rem; margin-top: 0.35rem; min-width: 0; max-width: 30rem; }
.result-sitelink { font-size: 0.9rem; color: var(--link-color, var(--brand)); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.result-sitelink:hover { text-decoration: underline; }
/* overflow-wrap:anywhere so a long unbreakable token (a very long word, or a URL used as the title/snippet) breaks
   instead of forcing horizontal scroll at 200% text / narrow viewports — keeps the numbered web result reflow-safe. */
.result-title { font-size: 1.1rem; font-weight: 600; margin-bottom: 0.25rem; overflow-wrap: anywhere; }
.result-title a { color: var(--link-color, var(--brand)); }
.result-desc { color: var(--text-muted); font-size: 0.92rem; overflow-wrap: anywhere; }

/* ===== Result Designer: the ONLY styles a user template can apply (a fixed whitelist → the row-slot sandbox; no raw
   CSS ever). An element with no styles keeps its semantic default, so the default template = today's look. Placed
   AFTER the semantic .result-* rules so an explicit rt-* override wins by source order. ===== */
.rt-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem; min-width: 0; margin-bottom: 0.15rem; }
.rt-row > * { margin-bottom: 0; min-width: 0; }
/* TEXT blocks sharing a row start ON the current line and grow into the remaining space (flex-basis:0 — with
   wrap enabled, an auto-basis text block whose natural width exceeds the line ALWAYS wrapped to its own flex
   line, so "favicon + excerpt in one row" never visually shared the first line). The min-width floor makes a
   genuinely-too-narrow line wrap gracefully instead of squeezing into a one-word column. Small atoms (favicon /
   date / number) keep their natural size. Designer chips mirror by content via :has(). */
.rt-row > .result-title, .rt-row > .result-desc, .rt-row > .result-url, .rt-row > .result-sitelinks,
.rt-row > .rd-chip:has(> .result-title), .rt-row > .rd-chip:has(> .result-desc),
.rt-row > .rd-chip:has(> .result-url), .rt-row > .rd-chip:has(> .result-sitelinks) {
    /* min() caps the floor at the row itself: a container narrower than 8rem (a depth-indented
       cluster member at 200% text on a phone) floors to its own width instead of overflowing. */
    flex: 1 1 0; min-width: min(8rem, 100%);
}
/* Small atoms beside a MULTILINE text block sit with its FIRST line (baseline through the chip wrapper resolves
   against the block's last line and sank the icon to line two). */
.rt-row > .result-favicon, .rt-row > .result-date, .rt-row > .result-ordinal,
.rt-row > .rd-chip:has(> .result-favicon), .rt-row > .rd-chip:has(> .result-date),
.rt-row > .rd-chip:has(> .result-ordinal) {
    align-self: flex-start; margin-top: 0.15em;
}
/* Favicons sit on a fixed LIGHT chip in every theme: many sites ship dark/transparent glyphs (GitHub's
   octocat, NYT's "T") that vanish on a dark surface — var(--surface-2) is near-black in dark mode, which made
   them look like MISSING icons (owner-reported via the designer preview). box-sizing keeps the box 16px. */
.result-favicon { width: 16px; height: 16px; border-radius: 3px; vertical-align: middle; margin-inline-end: 0.4rem; object-fit: contain; flex: 0 0 auto; background: #fff; padding: 2px; box-sizing: border-box; }
.rt-size-xs { font-size: 0.75rem; } .rt-size-s { font-size: 0.85rem; } .rt-size-m { font-size: 0.95rem; }
.rt-size-l { font-size: 1.15rem; } .rt-size-xl { font-size: 1.4rem; }
/* Size on the favicon = actual icon dimensions (an <img> ignores font-size; width/height CSS beats its attrs). */
.result-favicon.rt-size-xs { width: 12px; height: 12px; }
.result-favicon.rt-size-s { width: 14px; height: 14px; }
.result-favicon.rt-size-l { width: 20px; height: 20px; }
.result-favicon.rt-size-xl { width: 26px; height: 26px; }
.rt-weight-normal { font-weight: 400; } .rt-weight-medium { font-weight: 500; } .rt-weight-bold { font-weight: 700; }
.rt-color-default, .rt-color-default a { color: var(--text); }
.rt-color-muted, .rt-color-muted a { color: var(--text-muted); }
.rt-color-subtle, .rt-color-subtle a { color: var(--text-subtle); }
.rt-color-link, .rt-color-link a { color: var(--link-color, var(--brand)); }
.rt-color-success, .rt-color-success a { color: var(--success); }
.rt-color-brand, .rt-color-brand a { color: var(--brand-strong); }
.rt-color-danger, .rt-color-danger a { color: var(--danger); }
.rt-clamp-1, .rt-clamp-2, .rt-clamp-3 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.rt-clamp-1 { -webkit-line-clamp: 1; } .rt-clamp-2 { -webkit-line-clamp: 2; } .rt-clamp-3 { -webkit-line-clamp: 3; }
.rt-caps { text-transform: uppercase; letter-spacing: 0.03em; }
.results-loading { display: flex; align-items: center; gap: 0.6rem; color: var(--text-muted); padding: 1rem 0; }
.results-empty { text-align: start; color: var(--text-muted); padding: 2.5rem 0; }
.results-count { color: var(--text-subtle); font-size: 0.85rem; margin: 0 0 1rem; }
/* The results meta row: count · malicious notice · rules summary · translate note · personalize
   toggle share ONE wrapping line (previously four stacked blocks). Children keep their identity;
   the row owns the spacing (their block margins are neutralized) and the gap is the separator. */
.results-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 1.25rem;
  margin: 0 0 0.75rem; min-width: 0; }
.results-meta > * { margin: 0; min-width: 0; }

/* Numbered pager (web results). Logical properties + flex-wrap so it reflows + is RTL-ready. */
.pager { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; justify-content: flex-start; margin: 2.25rem 0 1rem; }
.pager-link { display: inline-flex; align-items: center; justify-content: center; min-width: 2.25rem; min-height: 2.25rem; padding-inline: 0.6rem; border: 1px solid var(--control-border); border-radius: var(--radius-pill, 999px); color: var(--text); text-decoration: none; font-size: 0.9rem; }
.pager-link:hover { border-color: var(--brand); color: var(--brand); }
.pager-link.active { background: var(--brand); border-color: var(--brand); color: var(--brand-contrast); font-weight: 600; }
.pager-edge { font-weight: 600; }
.pager-gap { color: var(--text-muted); padding-inline: 0.15rem; }

/* Slim top progress bar shown during an enhanced-nav page change (state-of-the-art transition feedback). */
.nav-progress { position: fixed; inset-block-start: 0; inset-inline-start: 0; height: 3px; width: 0; background: var(--brand); z-index: 9999; opacity: 0; pointer-events: none; }
.nav-progress.active { width: 88%; opacity: 1; transition: width 9s cubic-bezier(0.12, 0.78, 0.12, 1), opacity 0.15s ease; }
.nav-progress.done { width: 100%; opacity: 0; transition: width 0.18s ease, opacity 0.4s ease 0.12s; }

/* Subtle result fade-in (reduced-motion users get none). fill BACKWARDS, never `both`: a filled
   transform animation keeps the element a stacking context FOREVER, which made every result paint
   in DOM order — a later result's URL hit-tested ABOVE an earlier result's open Adjust panel. */
@media (prefers-reduced-motion: no-preference) {
    .result-item { animation: result-in 0.24s ease backwards; }
}
/* While a result's Adjust/kebab popup is open, that result outranks its siblings outright — no
   stacking experiment (entrance animation, future transforms) may ever paint over an open menu. */
.result-item:has(details[data-rank][open]) { z-index: 30; }
@keyframes result-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* Image infinite-scroll affordances. */
.image-status { display: flex; align-items: center; justify-content: center; gap: 0.5rem; color: var(--text-muted); padding: 1.5rem 0; }
#image-sentinel { block-size: 1px; }

/* ------------------------------ Pricing --------------------------------- */
/* Two-tier layout (owner, 2026-07-20): the interval radios live on .pricing-shell so ONE toggle
   drives both plan cards' price/CTA swaps through the ~ combinator (siblings' descendants are
   targetable: #p-year:checked ~ .pricing-grid .price-month). auto-fit minmax reflows the grid to
   one column on narrow / large-text viewports — same reflow-safe pattern as the value grid. */
.pricing-shell { min-inline-size:0; margin:0 0 3rem; padding:0; border:0; }
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: 1.5rem; align-items: stretch; max-width: 46rem; margin: 0 auto 1.25rem; }
.pricing-card { margin: 0; padding: clamp(1.25rem, 5vw, 2rem); text-align: center;
    display: flex; flex-direction: column; }
.pricing-card .feature-list { flex: 1 1 auto; }
.pricing-card--featured { border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent), var(--shadow-lg); }
.pricing-plan-name { font-size: 1.25rem; font-weight: 800; letter-spacing: -0.01em; margin: 0; }
.pricing-plan-tag { color: var(--text-muted); font-size: 0.875rem; margin: 0.15rem 0 1rem; }
.pricing-featured-tag { display: inline-block; margin: 0 auto 0.6rem; font-size: 0.7rem; font-weight: 700;
    letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent-contrast); background: var(--accent);
    padding: 0.15rem 0.6rem; border-radius: var(--radius-pill); }
.feature-list .feature-lead { font-weight: 600; color: var(--text); }
.pricing-switch-note { max-width: 34rem; margin-inline: auto; font-size: 0.9rem; }
/* Secure-checkout badge: the landing Lock glyph + short label, breathing room above. */
.pricing-secure{margin-top:1.6rem;display:flex;align-items:center;justify-content:center;gap:.5rem;
  color:var(--text-muted);font-size:.85rem;font-weight:600}
.pricing-secure .ps-icon{width:1.75rem;height:1.75rem;flex:none}

/* Full-width segmented control: the two segments share the width (flex:1, min-width:0) and grow TALLER
   rather than wider when text scales — the "save" badge stacks under "Annual" (column), so it can never
   push the control past the viewport. A rounded rect (not a pill) reads cleanly when segments are tall. */
.billing-toggle { display: flex; gap: 0.25rem; width: 100%; max-width: 24rem; margin: 0 auto 1.5rem; padding: 0.3rem; background: var(--surface-2); border: 1px solid var(--control-border); border-radius: var(--radius-lg); }
.billing-radio { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
.billing-toggle label { flex: 1 1 0; min-width: 0; cursor: pointer; text-align: center; line-height: 1.25;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.2rem;
    padding: 0.5rem 0.4rem; border-radius: var(--radius); font-weight: 600; font-size: 0.95rem; color: var(--text-muted); }
/* At large text (em → font-aware) the two segments can't sit side by side; stack them so each gets the
   full width. The threshold is low enough that normal-font phones keep the horizontal pill. */
@media (max-width: 18em) { .billing-toggle { flex-direction: column; } }
/* Radios are direct children of .pricing-shell (and, on /signup, of the interval fieldset); the toggle
   is a later sibling (~). The active segment gets an accent-tinted fill + a 1px inset accent ring so
   the selection is unmistakable, including in dark mode (the previous surface-only highlight was too
   subtle). The s-int-* pair is the signup instance of the same control. */
#p-month:checked ~ .billing-toggle label[for="p-month"],
#p-year:checked ~ .billing-toggle label[for="p-year"],
#s-int-month:checked ~ .billing-toggle label[for="s-int-month"],
#s-int-year:checked ~ .billing-toggle label[for="s-int-year"] { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); color: var(--text); box-shadow: inset 0 0 0 1px var(--accent), var(--shadow-sm); }
#p-month:focus-visible ~ .billing-toggle label[for="p-month"],
#p-year:focus-visible ~ .billing-toggle label[for="p-year"],
#s-int-month:focus-visible ~ .billing-toggle label[for="s-int-month"],
#s-int-year:focus-visible ~ .billing-toggle label[for="s-int-year"] { outline: 2px solid var(--ring); outline-offset: 2px; }
.save-badge { font-size: 0.7rem; font-weight: 700; color: var(--accent-contrast); background: var(--accent); padding: 0.05rem 0.45rem; border-radius: var(--radius-pill); white-space: nowrap; }

.price-display { margin-bottom: 1.5rem; }
/* Flex + wrap so the amount and "/month" can break onto separate lines under large text. There is no
   whitespace between the .amount and .per spans, so without flex-wrap they form one unbreakable token
   ("$12/month") that overflows the viewport when the font is scaled up. */
.price { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; column-gap: 0.25rem; }
/* The amount is a single unbreakable token (e.g. "$8.25"); clamp keeps it from overrunning a narrow
   viewport when scaled. The rem bounds still grow with the user's font, so text scaling is preserved —
   only the vw term limits it on small screens (it never falls below the 2rem floor). */
.price .amount { font-size: clamp(2rem, 13vw, 3rem); font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; }
.price .per { color: var(--text-muted); font-size: 1rem; }
.price-note { color: var(--text-muted); font-size: 0.85rem; margin-top: 0.25rem; }

/* Toggle visibility driven purely by the radios (no JS). The radios sit on .pricing-shell, so the
   rules reach through .pricing-grid into every card at once. */
.price-year, .cta-year { display: none; }
#p-year:checked ~ .pricing-grid .price-display .price-month { display: none; }
#p-year:checked ~ .pricing-grid .price-display .price-year { display: flex; }
#p-month:checked ~ .pricing-grid .price-display .price-year { display: none; }
#p-year:checked ~ .pricing-grid .cta-month { display: none; }
#p-year:checked ~ .pricing-grid .cta-year { display: block; }
.cta { margin: 0; }

.feature-list { list-style: none; text-align: start; margin: 0 auto 1.75rem; max-width: 330px; display: flex; flex-direction: column; gap: 0.6rem; }
.feature-list li { display: flex; gap: 0.6rem; align-items: flex-start; }
.feature-list .check { color: var(--brand); font-weight: 800; }

/* ------------------------------ Auth forms ------------------------------ */
/* Inline paddings are vw-capped: at 200% text on a phone the rem values double and three nesting
   levels (wrap+card+plan-card) would otherwise eat ~75% of a 360px viewport — the caps let the
   gutters yield so the CONTENT keeps its room. Desktop is unaffected (vw term exceeds the rem). */
.auth-wrap { display: flex; justify-content: center; padding: clamp(2rem, 6vw, 4rem) min(1.25rem, 4vw); }
.auth-card { width: 100%; max-width: 420px; padding: 2rem min(2rem, 7vw); }
.auth-card h1 { font-size: 1.5rem; margin-bottom: 0.25rem; }
.auth-card .sub { color: var(--text-muted); margin-bottom: 1.5rem; font-size: 0.9375rem; }
.auth-card form { display: flex; flex-direction: column; gap: 0.25rem; }
.auth-alt { margin-top: 1.25rem; font-size: 0.9375rem; color: var(--text-muted); text-align: center; }

/* Signup's "you're already signed in" panel (SSO-aware signup) */
.signedin-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; min-width: 0; }
.signedin-actions .btn { flex: 1 1 0; min-width: 8rem; }   /* the pair shares the panel's full width */
.signedin-switch .btn { width: 100%; }
.signedin-switch { margin-top: 0.9rem; }

/* ---- Plan picker (signup) — selectable plan cards ---- */
/* gap = plain rhythm between cards (the savings ribbon is in-flow, not floating) */
.plan-picker { border: 0; padding: 0; margin: 0.85rem 0 0.35rem; min-width: 0; display: flex; flex-direction: column; gap: 1.15rem; }
/* hyphens+anywhere: de compounds ("Abrechnungszeitraum" ≈ 19ch) are single words that outgrow a
   200%-text phone card — break them rather than clip. */
.plan-picker-legend { padding: 0; margin-bottom: 0.55rem; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted); hyphens: auto; overflow-wrap: anywhere; }

.plan-card {
    position: relative; display: flex; align-items: center; gap: 0.8rem;
    padding: 0.85rem min(1rem, 3.5vw); background: var(--surface);
    border: 1.5px solid var(--border); border-radius: var(--radius-lg);
    cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.plan-card:hover { border-color: var(--border-strong); }
.plan-card:active { transform: scale(0.995); }
/* The real radio stays in the DOM for a11y + form posting, but is visually replaced by .plan-card-check. */
.plan-card input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* Selected state — accent ring + tint + filled check. */
.plan-card:has(input:checked) {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 7%, var(--surface));
    box-shadow: 0 0 0 1px var(--accent);
}
/* Keyboard focus (the hidden radio receives focus). */
.plan-card:has(input:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; }

.plan-card-check {
    flex: none; width: 1.3rem; height: 1.3rem; border-radius: 50%;
    border: 2px solid var(--border-strong); position: relative;
    /* grid centering keeps the selection dot exact at ANY font size — the old margin-tuned dot
       sat 1.6px high (16.8px content box, 7.2px dot, 3.2px margin-top vs the centered 4.8px). */
    display: grid; place-items: center;
    transition: border-color 0.15s ease, background 0.15s ease;
}
/* ONE selection glyph for every card group: the radio dot (radios are dots; a checkmark reads
   as a checkbox). Symmetric, so RTL needs no mirroring. */
.plan-card:has(input:checked) .plan-card-check { border-color: var(--accent); background: var(--accent); }
.plan-card:has(input:checked) .plan-card-check::after {
    content: ""; width: 0.45rem; height: 0.45rem; border-radius: 50%;
    background: var(--accent-contrast);
}

/* Body holds the name/sub + price; it WRAPS so the price drops below the name (rather than overlapping it)
   when the text is scaled up — flex items never overlap, so reflow replaces the previous collision.
   It is also a size container: at 200% text on a phone the line is ~100px and two shrinkable flex
   children would crush each other to slivers instead of wrapping — the @container rule below restacks
   (main full-line, price beneath) and lets the numerals yield via cqw ONLY in that crush case. */
.plan-card-body { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.85rem; container-type: inline-size; }
@container (max-width: 200px) {
    .plan-card-main { flex-basis: 100%; }
    .plan-card-name { font-size: min(1rem, 15cqw); }
    .plan-card-sub { font-size: min(0.8125rem, 13cqw); }
    .plan-card-amount { font-size: min(1.3rem, 20cqw); }
}
.plan-card-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.plan-card-name { font-weight: 700; font-size: 1rem; color: var(--text); line-height: 1.2; }
.plan-card-sub { font-size: 0.8125rem; color: var(--text-muted); }

/* flex-wrap so the amount + "/mo" (no whitespace between the spans → one unbreakable token) can break onto
   two lines under large text instead of overflowing — same guard as .price above. flex 0 1 auto (NOT none):
   at 200% text the one-line max-content exceeds the card, and only a shrinkable item lets the internal
   wrap engage; flex-end keeps the wrapped lines right-aligned against the card edge. */
.plan-card-price { flex: 0 1 auto; min-width: 0; margin-inline-start: auto; display: flex; flex-wrap: wrap;
    justify-content: flex-end; align-items: baseline; gap: 0.1rem; }
.plan-card-amount { font-weight: 800; font-size: 1.3rem; letter-spacing: -0.02em; color: var(--text); }
.plan-card-per { font-size: 0.8125rem; font-weight: 600; color: var(--text-muted); }
/* Full-width last line of the price block ("Billed monthly" / "$99 billed yearly") — present in BOTH
   interval states so the card height never jumps on toggle. text-align:end tracks RTL. */
.plan-card-billnote { flex-basis: 100%; min-width: 0; text-align: end;
    font-size: 0.75rem; font-weight: 500; color: var(--text-muted); }
@media (prefers-reduced-motion: reduce) { .plan-card { transition: none; } .plan-card:active { transform: none; } }

/* ---- Tier picker (signup, two-tier pivot 2026-07-20) ---- */
/* The tier radios and their visual cards share one real fieldset. :has() keeps the selected tier
   reflected in both that card and the later interval prices without pulling radios out of their group. */
.tier-radio { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
.tier-picker:has(#s-plan-pro:checked) label[for="s-plan-pro"],
.tier-picker:has(#s-plan-ult:checked) label[for="s-plan-ult"] {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 7%, var(--surface));
    box-shadow: 0 0 0 1px var(--accent); }
.tier-picker:has(#s-plan-pro:checked) label[for="s-plan-pro"] .plan-card-check,
.tier-picker:has(#s-plan-ult:checked) label[for="s-plan-ult"] .plan-card-check { border-color: var(--accent); background: var(--accent); }
.tier-picker:has(#s-plan-pro:checked) label[for="s-plan-pro"] .plan-card-check::after,
.tier-picker:has(#s-plan-ult:checked) label[for="s-plan-ult"] .plan-card-check::after {
    content: ""; width: 0.45rem; height: 0.45rem; border-radius: 50%;
    background: var(--accent-contrast); }
.tier-picker:has(#s-plan-pro:focus-visible) label[for="s-plan-pro"],
.tier-picker:has(#s-plan-ult:focus-visible) label[for="s-plan-ult"] { outline: 2px solid var(--ring); outline-offset: 2px; }
/* ---- Interval toggle (signup) — /pricing's segmented control inside the form ---- */
/* Twin price lines in each tier card: the toggle picks one, so every amount renders exactly once. */
.signup-form .plan-card-price.price-year { display: none; }
.signup-form:has(#s-int-year:checked) .plan-card-price.price-month { display: none; }
.signup-form:has(#s-int-year:checked) .plan-card-price.price-year { display: flex; }
/* In the card the fieldset provides the rhythm — drop the pricing page's centering margin. The badge
   may wrap inside its flex-column segment at large text (fr "Économisez" is one ~10ch word; nowrap
   would poke past the segment — hyphenate, mid-word as last resort). */
.interval-toggle .billing-toggle { margin: 0; }
.interval-toggle .save-badge { white-space: normal; hyphens: auto; overflow-wrap: anywhere; }
/* Crush fallback with NO width threshold: each segment refuses to shrink below its longest WORD
   (min-width:min-content overrides the base min-width:0 — NOT max-content, which would also refuse
   to wrap the badge's multi-word text) and the row wraps, so a segment that cannot fit takes a full
   line instead of clipping. Self-adaptive per locale (en "Monthly", de "Monatlich", fr's badge word
   "économisez") and per font scale; at rest both segments share one line 50/50 as before. */
.interval-toggle .billing-toggle { flex-wrap: wrap; }
.interval-toggle .billing-toggle label { min-width: min-content; padding-inline: min(0.4rem, 1.5vw); }

/* ------------------------------ Account --------------------------------- */
.account-grid { display: grid; gap: 1.25rem; }
.account-row { display: flex; justify-content: space-between; gap: 1rem; padding: 0.85rem 0; border-bottom: 1px solid var(--border); }
.account-row:last-child { border-bottom: none; }
.account-row .k { color: var(--text-muted); }
.account-row .v { font-weight: 600; }
.page-head { padding: clamp(1.5rem, 4vw, 2.5rem) 0 0.5rem; }
.page-head h1 { font-size: clamp(1.6rem, 4vw, 2.1rem); }

/* ------------------------------ Credits --------------------------------- */
.credit-balance { display: flex; flex-direction: column; gap: 0.15rem; margin-bottom: 1rem; }
.credit-amount { font-size: clamp(2rem, 6vw, 2.6rem); font-weight: 800; line-height: 1.1; letter-spacing: -0.02em; }
.credit-presets { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 0.6rem; }
.credit-preset {
    position: relative; display: flex; flex-direction: column; gap: 0.1rem; cursor: pointer; text-align: center;
    padding: 0.7rem 0.5rem; border: 1px solid var(--border-strong); border-radius: var(--radius);
    background: var(--input-bg); transition: border-color 0.12s ease, background 0.12s ease;
}
.credit-preset:hover { border-color: var(--brand); }
.credit-preset input { position: absolute; opacity: 0; width: 0; height: 0; }
/* Selected highlight via :has() in modern browsers; the input stays visually hidden regardless. */
.credit-preset:has(input:checked) { border-color: var(--brand); background: var(--brand-soft); }
.credit-preset:focus-within { outline: 2px solid var(--ring); outline-offset: 2px; }
.credit-preset-amt { font-weight: 700; }
.credit-preset-req { font-size: 0.8rem; color: var(--text-muted); }
/* The custom-amount entry is a single dollar figure — don't let it stretch full-width like a normal field. */
.credit-custom .field-input { max-width: 12rem; }

/* "We ❤️ Ukraine" — a subtle landing-page ribbon. It holds hidden, then gently rises + fades in ~0.8s after
   paint. STICKY, not fixed (deliberately): a sticky element stays in normal flow, so it reserves its own height
   at the end of <main> and DOCKS just above the footer at the very bottom of the page instead of floating over
   the footer copy — clearing it with zero JavaScript and zero magic numbers (the reserved space is always
   exactly the panel's height, at any OS text size / however the sub-text wraps). While you scroll the page it
   stays pinned to the viewport bottom (bottom: 1.25rem); on reaching the end it settles into flow above the
   footer. If `position: sticky` is ever unsupported it degrades to `static` — still in flow, still no overlap.
   On desktop it right-aligns to the content area's inline-END: margin-inline-start:auto pushes it to the end and
   margin-inline-end matches the centred .container's inline-end edge (max-width 1120px + 1.25rem) so it lines up
   under the footer's Contact link; logical margins keep it tracking the footer in RTL. `100%` (not 100vw) is the
   scrollbar-excluded ICB, matching how .container centres; the max() clamps to a 1.25rem inset below 1120px. */
.ua-ribbon {
    position: sticky; bottom: 1.25rem; z-index: var(--z-fixed);
    margin-inline-start: auto; margin-inline-end: max(1.25rem, calc((100% - 1120px) / 2 + 1.25rem));
    display: flex; width: fit-content; align-items: center; gap: 0.5rem;
    max-width: min(21rem, calc(100vw - 1.75rem));
    padding: 0.6rem 0.65rem; background: var(--surface); color: var(--text); text-decoration: none;
    border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow);
    animation: ua-ribbon-in 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) 0.8s both;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.ua-ribbon:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); text-decoration: none; }
.ua-ribbon-flag { flex: none; height: 1.25rem; width: auto; border-radius: 3px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); }
/* min-width:0 lets the text column shrink/wrap inside the flex row instead of forcing overflow. */
.ua-ribbon-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.ua-ribbon-text strong { font-size: 0.95rem; font-weight: 700; }
/* Soft-damped size (min of rem and rem+vw): the sub keeps GROWING with the user's font, just a
   little slower on narrow screens, buying the one-line fit through moderate large-font settings
   (owner, 2026-08-01 — the wrap cost a full extra line of scarce handset height). Wrapping stays
   the graceful floor for extreme settings and the longest locales. */
.ua-ribbon-sub { font-size: clamp(0.62rem, 0.28rem + 2vw, 0.8rem); color: var(--text-muted); }

@keyframes ua-ribbon-in {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .ua-ribbon { animation: none; }            /* present immediately, no motion */
    .ua-ribbon:hover { transform: none; }
}
/* Narrow viewports (em-based so the switch fires earlier under OS text-zoom): centre the panel rather than
   tuck it right, and KEEP the sub-text — margin-inline:auto (overriding the base's start:auto/end:inset) centres
   the in-flow sticky panel without a transform, so it doesn't fight the entrance/hover translate. */
@media (max-width: 35em) {
    .ua-ribbon { margin-inline: auto; bottom: 0.75rem; max-width: min(22rem, calc(100vw - 0.875rem)); }
}

/* UK serving stack only: a quiet "Hosted in the UK" pill in the hero (reuses the gentle ua-ribbon-in entrance). */
.uk-hosted {
    display: flex; width: fit-content; margin: 0.6rem auto 0; align-items: center; gap: 0.45rem;
    padding: 0.3rem 0.75rem; font-size: 0.85rem; color: var(--text-muted);
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-pill);
    animation: ua-ribbon-in 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) 0.4s both;
}
.uk-hosted-flag { height: 0.95rem; width: auto; border-radius: 2px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); }
@media (prefers-reduced-motion: reduce) { .uk-hosted { animation: none; } }
.credit-neg { font-variant-numeric: tabular-nums; }
.credit-pos { color: var(--success); font-weight: 600; font-variant-numeric: tabular-nums; }

/* ===================== Settings hub ===================== */
.settings {
    /* ONE source of truth for the gap between the header and the top of both columns: the page's own padding-top
       AND the sidebar's sticky offset read this var. When they differed (padding up to 2rem vs a fixed 1.25rem
       sticky top), the sidebar visibly slid UP by the difference the moment it pinned — the owner-reported
       "master scrolls slightly when the detail scrolls". Same var ⇒ resting position == pinned position. */
    --settings-gap-top: clamp(1.25rem, 3vw, 2rem);
    display: grid;
    grid-template-columns: 240px minmax(0, 1fr);
    gap: 2rem;
    align-items: start;
    width: 100%;
    max-width: 1080px;
    margin-inline: auto;
    padding: var(--settings-gap-top) 1.25rem 3rem;
}
.settings-sidebar {
    /* Sticky on the WHOLE panel (the "Search settings" input AND the nav links). It sits BELOW the sticky
       .app-header so the input doesn't tuck up behind it; align-self:start keeps it from stretching to the grid
       row's height (so sticky has somewhere to travel); max-height + overflow-y let the panel scroll WITHIN
       itself when it genuinely exceeds the viewport (e.g. high text zoom) so every link stays reachable.
       The clip is EXACTLY the space below the pinned top (one shared var, so top and max-height can't drift):
       an extra reserved bottom gap here made the panel internally scrollable by that gap's height even when its
       content fit the viewport (owner-reported phantom scroll — harness-reproduced at 10px). dvh so mobile
       URL-bar collapse doesn't mis-size it; vh fallback first. padding gives the search field's focus ring room
       inside the scroll container. */
    --settings-sticky-top: calc(var(--header-height) + var(--settings-gap-top));
    position: sticky; top: var(--settings-sticky-top); align-self: start;
    max-height: calc(100vh - var(--settings-sticky-top));
    max-height: calc(100dvh - var(--settings-sticky-top));
    overflow-y: auto; overscroll-behavior: contain;
    padding: 0.25rem;
    display: flex; flex-direction: column; gap: 1rem;
}

/* Search box */
.settings-search { position: relative; }
.settings-search-input {
    font: inherit; width: 100%; color: var(--text); background: var(--input-bg);
    border: 1px solid var(--control-border); border-radius: var(--radius);
    padding: 0.6rem 2.75rem 0.6rem 0.75rem;
}
.settings-search-input:focus {
    outline: none; border-color: var(--brand);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 25%, transparent);
}
.settings-search-clear {
    position: absolute; inset-inline-end: 0.2rem; top: 50%; transform: translateY(-50%);
    display:inline-flex; align-items:center; justify-content:center; inline-size:2rem; block-size:2rem;
    border: none; background: transparent; color: var(--text-muted);
    cursor: pointer; font-size: 1rem; line-height: 1; padding: 0; border-radius: var(--radius-sm);
}
.settings-search-clear:hover { color: var(--text); background: var(--surface-2); }
/* Hide the clear affordance while the field is empty (placeholder showing). */
.settings-search-input:placeholder-shown + .settings-search-clear { display: none; }

/* Section navigation — a <details> disclosure: an INLINE rail on desktop, a DROPDOWN on handset (below the em
   breakpoint). Desktop keeps the rail inline by forcing the content visible regardless of the details' open
   state — with BOTH mechanisms, because Chromium ≥131 hides closed-<details> content through ::details-content
   (content-visibility:hidden) which author child-display alone can't override (see the details-content
   regression). The handset dropdown rules live in the em-breakpoint block below. */
.settings-nav-disclosure { display: block; }
.settings-nav-disclosure > summary { display: none; }                        /* desktop: no button; the rail is inline */
.settings-nav-disclosure::details-content { content-visibility: visible; }   /* Chromium 131+ (author beats UA) */
.settings-nav-disclosure > .settings-nav { display: flex; }                  /* pre-::details-content engines */

/* Sidebar nav */
.settings-nav { display: flex; flex-direction: column; gap: 0.15rem; }
.settings-nav-item {
    display: block; padding: 0.5rem 0.7rem; border-radius: var(--radius);
    color: var(--text-muted); font-weight: 600; font-size: 0.95rem; text-decoration: none;
    border-inline-start: 3px solid transparent;
}
/* The hidden attribute must always win: author display rules on .btn/.settings-nav-item/etc. otherwise
   override the UA `[hidden] { display:none }` and leave "hidden" elements visible. */
[hidden] { display: none !important; }
.settings-nav-item:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
/* Nested sections (the search verticals under "Search"): indented, slightly quieter — visual nesting only,
   the panes stay flat and always reachable. Logical inset ⇒ mirrors under RTL. */
.settings-nav-child { margin-inline-start: 1rem; font-size: 0.9rem; }
.settings-nav-item.active {
    background: var(--brand-soft); color: var(--brand-strong); border-inline-start-color: var(--brand);
}

/* Panes */
.settings-main { min-width: 0; }
.settings-pane-title { font-size: 1.4rem; margin-bottom: 1rem; }
.settings-pane-title:focus { outline: none; }
.settings-group { margin-bottom: 2rem; }
.settings-group-title {
    font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em;
    color: var(--text-muted); margin: 1.25rem 0 0.25rem;
}
/* An alert/panel directly under a group title (e.g. the verify-email banner under PROFILE) shouldn't sit flush. */
.settings-group-title + .alert { margin-block-start: 0.9rem; }
.settings-actions { margin-top: 1.5rem; }
/* A pane's posted form (…ending in its Save button) never crowds the standalone rows that follow it —
   the Search pane's Filtering form is trailed by the Custom Ranking / Views / Snaps run. */
.settings-form { margin-block-end: 1.25rem; }
.settings-inline-form { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }
.settings-inline-form .field-input { flex: 1 1 14rem; width: auto; }

/* A single setting row: stacks by default (works for tables/forms); simple single-control rows go inline. */
.setting-row {
    display: flex; flex-direction: column; gap: 0.6rem;
    padding: 1.5rem 0; border-bottom: 1px solid var(--border);
}
.setting-row:last-child { border-bottom: none; }
.setting-row-label { font-weight: 600; }
.setting-row-desc { font-size: 0.85rem; color: var(--text-muted); margin: 0.1rem 0 0; }
.setting-row-control { min-width: 0; }
/* A conditionally-shown row (e.g. the custom citation template, shown only for the Custom style). display:none so
   the control stays in the DOM — its value is preserved and still posts — while overriding the row's flex display. */
.setting-row.is-hidden { display: none; }
.setting-row:has(> .setting-row-control > .toggle:only-child),
.setting-row:has(> .setting-row-control > .field-select:only-child),
.setting-row:has(> .setting-row-control > .segmented:only-child),
.setting-row:has(> .setting-row-control > .v:only-child) {
    flex-direction: row; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.5rem 1.5rem;
}
.setting-row:has(> .setting-row-control > .toggle:only-child) .setting-row-info,
.setting-row:has(> .setting-row-control > .field-select:only-child) .setting-row-info,
.setting-row:has(> .setting-row-control > .segmented:only-child) .setting-row-info,
.setting-row:has(> .setting-row-control > .v:only-child) .setting-row-info { flex: 1 1 16rem; }
.setting-row .field-select { width: auto; min-width: 13rem; max-width: 100%; }
/* Compact variant for short numeric values (e.g. Results per page) — the full 13rem reads as empty space. */
.setting-row .field-select-narrow { min-width: 6.5rem; }

/* Display-language rotator: the ui-language row's description slot — the phrase "Display language" cycling through
   the non-current languages (LanguageNameRotator.razor + 61-ui-language-rotator.ts). Same voice as
   .setting-row-desc; items are STACKED absolutely inside a one-line-reserved box so the crossfade never reflows the
   row, and inset-inline keeps them start-aligned under RTL. Crossfade only when motion is allowed — under reduced
   motion (or no JS) exactly one phrase sits there statically. */
.lang-rotator {
    position: relative; min-height: 1.35em;
    font-size: 0.85rem; color: var(--text-muted); margin: 0.1rem 0 0;
}
.lang-rotator-item {
    position: absolute; inset-inline: 0; top: 0;
    opacity: 0; visibility: hidden;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    /* Align every phrase with the PAGE's reading direction, not the phrase's own: an RTL phrase (Arabic) keeps its
       correct internal shaping via dir="rtl" but must not drift to the far edge of an LTR page (and vice versa).
       Stated physically (match-parent renders inconsistently): LTR page → left, RTL page → right. */
    text-align: left;
}
html[dir="rtl"] .lang-rotator-item { text-align: right; }
.lang-rotator-item.is-active { opacity: 1; visibility: visible; }
.lang-rotator-item.is-current { display: none; }   /* the selected language never shows its own phrase */
@media (prefers-reduced-motion: no-preference) {
    .lang-rotator-item { transition: opacity 0.55s ease, visibility 0.55s; }
}

/* Citations: custom-template editor + token help. Full-width control that reflows; the help is muted and the
   token list / worked example are monospace and allowed to wrap. The whole row is shown only for the Custom style —
   server-rendered (SettingRow Hidden) and toggled live by 62-citations-settings.ts via .setting-row.is-hidden. */
.citation-template { display: flex; flex-direction: column; gap: 0.6rem; width: 100%; min-width: 0; }
.field-textarea {
    width: 100%; min-width: 0; box-sizing: border-box; min-height: 4.5rem; resize: vertical;
    padding: 0.55rem 0.7rem; border: 1px solid var(--control-border); border-radius: var(--radius);
    background: var(--surface); color: var(--text);
    font-family: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace; font-size: 0.9rem; line-height: 1.5;
}
.field-textarea:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-soft); }
.citation-template-help { font-size: 0.82rem; color: var(--text-muted); line-height: 1.55; }
.citation-template-help p { margin: 0 0 0.35rem; }
.citation-template-example { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: baseline; }
.citation-template-help code {
    font-family: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace; font-size: 0.82rem;
    background: var(--surface-2, var(--brand-soft)); padding: 0.05rem 0.35rem; border-radius: var(--radius);
    overflow-wrap: anywhere; word-break: break-word;
}

/* Brief highlight when a deep link / search result lands on a row. */
@keyframes setting-flash { from { background: var(--brand-soft); } to { background: transparent; } }
.setting-row-flash { animation: setting-flash 1.4s ease-out; border-radius: var(--radius); }

/* Auto-reload: a card-on-file row (with divider) above a clean, evenly-spaced vertical form. */
.autoreload { display: flex; flex-direction: column; gap: 1.25rem; }
.autoreload-card {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; padding-bottom: 1.1rem; border-bottom: 1px solid var(--border);
}
.autoreload-form { display: flex; flex-direction: column; align-items: flex-start; gap: 1.1rem; }
.autoreload-form .toggle { margin: 0; }
.autoreload-form .field { margin: 0; width: 100%; max-width: 22rem; }
.autoreload-form .field-select { width: 100%; min-width: 0; }

/* Developer-access pin (Billing): toggle + Save inline, with an active-state note below. */
.developer-access { display: flex; flex-direction: column; gap: 0.75rem; align-items: flex-start; }
.developer-toggle-form { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }

/* Search results (flat, grouped, highlighted) */
.settings-results { margin-bottom: 1.5rem; }
.settings-results-count { font-size: 0.85rem; color: var(--text-muted); margin: 0 0 0.75rem; }
.settings-result {
    display: block; padding: 0.6rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius);
    margin-bottom: 0.5rem; text-decoration: none; color: var(--text); background: var(--surface);
}
.settings-result:hover { border-color: var(--brand); text-decoration: none; }
.settings-result-breadcrumb { display: block; font-size: 0.75rem; color: var(--text-muted); }
.settings-result-label { display: block; font-weight: 600; }
.settings-results mark { background: var(--brand-soft); color: inherit; border-radius: 2px; padding: 0 1px; }

/* em breakpoint (≈760px at the default 16px root) per the OS-font reflow mandate: under Firefox-Android text-zoom
   the em threshold grows with the font, so the settings hub collapses to a single column + horizontal nav exactly
   when the enlarged text would otherwise need it (harmless on Chrome, which doesn't shift em breakpoints). */
@media (max-width: 47.5em) {
    .settings { grid-template-columns: 1fr; gap: 1rem; }
    /* Stacked single-column layout: drop the sticky pin + the viewport cap so the panel flows normally. */
    .settings-sidebar { position: static; max-height: none; overflow: visible; padding: 0; }

    /* The section rail becomes a DROPDOWN. The summary is the select-like button showing the current section;
       the nav collapses (both mechanisms) until opened, then drops down as a full-width, tappable list. This
       replaces the wrapping tab pile, which was unusable at large OS-font sizes on handset. */
    .settings-nav-disclosure > summary {
        display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; cursor: pointer;
        list-style: none; padding: 0.6rem 0.85rem; border: 1px solid var(--border-strong);
        border-radius: var(--radius); background: var(--input-bg); color: var(--text);
        font-weight: 600; font-size: 0.95rem;
    }
    .settings-nav-disclosure > summary::-webkit-details-marker { display: none; }
    .settings-nav-disclosure > summary::after { content: "▾"; color: var(--text-muted); font-size: 0.8em; flex: none; }
    .settings-nav-disclosure[open] > summary::after { content: "▴"; }
    .settings-nav-disclosure > summary:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }
    .settings-nav-summary-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

    /* Closed ⇒ collapse. Open ⇒ the dropdown panel. */
    .settings-nav-disclosure:not([open])::details-content { content-visibility: hidden; }
    .settings-nav-disclosure:not([open]) > .settings-nav { display: none; }
    .settings-nav-disclosure[open] > .settings-nav {
        display: flex; flex-direction: column; gap: 0.1rem; margin-block-start: 0.35rem;
        padding: 0.35rem; border: 1px solid var(--border); border-radius: var(--radius);
        background: var(--surface); box-shadow: var(--shadow-lg);
    }
    /* Full-width tappable rows; the active-state uses the fill (the inset border reads oddly in a menu). */
    .settings-nav-disclosure[open] > .settings-nav .settings-nav-item { border-inline-start: 0; padding: 0.65rem 0.7rem; }
    .settings-nav-disclosure[open] > .settings-nav .settings-nav-item.active { border-inline-start: 0; }
    .settings-nav-disclosure[open] > .settings-nav .settings-nav-child { margin-inline-start: 1.25rem; }

    /* Pane-content reflow at large OS-font: the select's desktop 13rem floor (= 390px at a 30px root) overflows
       a handset viewport — let selects fill the column instead. And let long-labeled action buttons wrap rather
       than force horizontal scroll (the reflow mandate). */
    .setting-row .field-select, .setting-row .field-select-narrow { min-width: 0; }
    .settings .btn { white-space: normal; max-inline-size: 100%; }

    /* A segmented control (theme / text-size) can't shrink its worded options, so at large OS-font its row
       STACKS (label above a full-width control) and the control scrolls horizontally within its OWN box rather
       than wrapping "System" off "Light/Dark" (owner-reported) or pushing the page. The options stay one line,
       together. */
    .setting-row:has(> .setting-row-control > .segmented:only-child) { flex-direction: column; align-items: stretch; }
    .setting-row .setting-row-control:has(> .segmented) { inline-size: 100%; }
    .setting-row .segmented { max-inline-size: 100%; overflow-x: auto; }
}
@media (prefers-reduced-motion: reduce) {
    .setting-row-flash { animation: none; }
}

/* Results-page time-range filter chips (wrap freely per the responsive/text-scaling guidance). */
.search-tools { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0; }   /* spacing owned by .results-controls */
.search-tool {
    font-size: 0.8125rem; color: var(--text-muted); text-decoration: none; white-space: nowrap;
    padding: 0.3rem 0.7rem; border-radius: var(--radius-pill); border: 1px solid transparent;
}
.search-tool:hover { background: var(--surface-2); color: var(--text); }
.search-tool.active { background: var(--brand-soft); color: var(--brand-strong); font-weight: 600; }
/* Handset: the time pills collapse into ONE dropdown (pills⇄menu swap at the same 34em breakpoint as
   the nav/anchored takeover). The items are the same links as the pills; the "N filters" pushbutton is
   NOT a time chip and stays in the row at every width. Hidden by default — desktop keeps the pills. */
.time-menu { display: none; position: relative; }
.time-menu-btn {
    display: inline-flex; align-items: center; gap: 0.3rem; cursor: pointer; list-style: none;
    background: var(--surface-2); color: var(--text);
}
.time-menu-btn::-webkit-details-marker { display: none; }
.time-menu-btn::marker { content: ""; }
.time-menu[open] > .time-menu-btn { background: var(--brand-soft); color: var(--brand-strong); }
.time-menu-btn:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }
.time-menu-caret { font-size: 0.7em; }
.time-menu-panel {
    position: absolute; inset-block-start: calc(100% + 0.35rem); inset-inline-start: 0; z-index: 45;
    min-inline-size: min(11rem, calc(100vw - 1.5rem));   /* viewport-capped — see .search-plus-menu */
    background: var(--surface, #fff); color: var(--text, #19172a);
    border: 1px solid var(--border, #ddd); border-radius: var(--radius);
    box-shadow: var(--shadow-lg, 0 16px 48px rgba(16,12,40,.16));
    padding: 0.35rem; display: flex; flex-direction: column; gap: 0.05rem;
}
.time-menu-item { padding: 0.45rem 0.55rem; border-radius: var(--radius-sm, 6px); color: var(--text); text-decoration: none; }
.time-menu-item:hover, .time-menu-item:focus { background: var(--surface-2); outline: none; }
.time-menu-item:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: -2px; }
.time-menu-item[aria-current="true"] { font-weight: 600; color: var(--brand-strong); }

/* ---- The "N filters" SPLIT-BUTTON + per-filter popup (?nf= toggles) ------------------------------------
   Anchor half = the existing personalize link (untouched markup — its class attribute is pinned by a source
   test); caret half = a details disclosure whose panel lists every counted filter as a checkbox row
   (checked = OFF for this search — unchecked boxes don't submit, so the URL carries exactly the OFF set).
   Panel recipe mirrors .time-menu-panel/.search-plus-menu (z-index 45, viewport-capped min(), the Chromium
   closed-details phantom-overflow rule). */
/* Cancel the .search-tools flex gap between the split halves — the two must read as ONE control. */
.filters-menu { position: relative; display: inline-flex; margin-inline-start: -0.4rem; }
.search-tool-filters:has(+ details.filters-menu) {
    border-start-end-radius: 0; border-end-end-radius: 0; border-inline-end-width: 0;
}
.filters-menu-btn {
    list-style: none; cursor: pointer; display: inline-flex; align-items: center;
    padding: 0.3rem 0.5rem; border: 1px solid var(--border-strong); border-radius: var(--radius-pill);
    border-start-start-radius: 0; border-end-start-radius: 0;
    font-size: 0.8125rem; color: var(--text-muted); white-space: nowrap;
}
.filters-menu-btn::-webkit-details-marker { display: none; }
.filters-menu-btn:hover, .filters-menu[open] > .filters-menu-btn { color: var(--text); background: var(--surface-2); }
.filters-menu-btn:focus-visible { outline: 2px solid var(--ring, var(--brand-strong)); outline-offset: -2px; }
.search-tool-filters[data-personalize="on"] + details.filters-menu > .filters-menu-btn { border-color: var(--brand-strong); }
.filters-menu-caret { font-size: 0.7em; }
.filters-menu-panel {
    position: absolute; inset-block-start: calc(100% + 0.35rem); inset-inline-end: 0; z-index: 45;
    min-inline-size: min(17rem, calc(100vw - 1.5rem));   /* viewport-capped — see .search-plus-menu */
    background: var(--surface, #fff); color: var(--text, #19172a);
    border: 1px solid var(--border, #ddd); border-radius: var(--radius);
    box-shadow: var(--shadow-lg, 0 16px 48px rgba(16,12,40,.16));
    padding: 0.5rem; display: flex; flex-direction: column; gap: 0.25rem;
    max-block-size: calc(100vh - 6rem); max-block-size: calc(100dvh - 6rem);
    overflow-y: auto; overscroll-behavior: contain;
}
.filters-menu-form { display: flex; flex-direction: column; gap: 0.05rem; margin: 0; }
.filters-menu-label {
    font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted);
    padding: 0.4rem 0.5rem 0.15rem;
}
.filters-menu-row {
    display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
    padding: 0.4rem 0.5rem; border-radius: var(--radius-sm, 6px); cursor: pointer;
    font-size: 0.8125rem; color: var(--text); min-block-size: 2.1rem;
}
.filters-menu-row:hover { background: var(--surface-2); }
.filters-menu-row:focus-within { outline: 2px solid var(--ring, var(--brand-strong)); outline-offset: -2px; }
.filters-menu-row-text { flex: 1 1 auto; min-inline-size: 0; overflow-wrap: anywhere; }
/* The native checkbox IS the control (real form state, real a11y); visually the track/thumb skin renders it.
   Scoped track/thumb (the .header-menu-switch precedent — an unscoped .switch-thumb bleeds onto app.css's). */
.filters-menu-row input[type="checkbox"] {
    position: absolute; opacity: 0; inline-size: 1px; block-size: 1px; pointer-events: none;
}
.filters-menu-row .switch-track {
    flex: none; inline-size: 2.2rem; block-size: 1.25rem; border-radius: 999px; background: var(--border-strong, #c4bca7);
    position: relative; transition: background 0.15s ease;
}
.filters-menu-row .switch-thumb {
    position: absolute; inset-block-start: 0.15rem; inset-inline-start: 0.15rem; inline-size: 0.95rem; block-size: 0.95rem;
    border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.3); transition: inset-inline-start 0.15s ease;
}
/* CHECKED = suppressed = OFF; the thumb sits ON (brand, travelled) when NOT checked. */
.filters-menu-row input[type="checkbox"]:not(:checked) ~ .switch-track { background: var(--brand); }
.filters-menu-row input[type="checkbox"]:not(:checked) ~ .switch-track .switch-thumb { inset-inline-start: 1.1rem; }
@media (prefers-reduced-motion: reduce) { .filters-menu-row .switch-track, .filters-menu-row .switch-thumb { transition: none; } }
.filters-menu-apply { align-self: flex-end; margin-block-start: 0.3rem; }
.filters-menu-bulk { display: flex; gap: 0.35rem; border-block-start: 1px solid var(--border); padding-block-start: 0.4rem; }
.filters-menu-bulk form { margin: 0; flex: 1 1 0; min-inline-size: 0; display: flex; }
.filters-menu-bulk .btn { flex: 1 1 0; min-inline-size: 0; white-space: nowrap; }
.filters-menu-manage {
    font-size: 0.8125rem; color: var(--text-muted); text-decoration: none; padding: 0.4rem 0.5rem;
    border-radius: var(--radius-sm, 6px);
}
.filters-menu-manage:hover, .filters-menu-manage:focus { background: var(--surface-2); color: var(--text); outline: none; }
.filters-menu-manage:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: -2px; }

@media (max-width: 34em) {
    .search-tools > .search-tool:not(.search-tool-filters) { display: none; }
    .time-menu { display: inline-flex; }
    .search-tool-filters { margin-inline-start: 0.85rem; }   /* the wide set-off reads odd next to one pill */
    /* The presentation seg drops its labels (icons + title/aria stay) so the whole controls row —
       time menu, filters chip, seg — fits one line at phone widths and large text. */
    .results-controls .view-opt > span { display: none; }
    .results-controls .view-opt { padding-inline: 0.45rem; }
    /* Inside the controls row the tools nav is a shrink-wrapped flex item, so it can no longer serve
       as the panel-spanning context — hoist that role one level: the CONTROLS ROW becomes the
       positioning context and the time-menu panel (inset-inline: 0, the trick above) spans the full
       row width whatever the flex line composition. */
    .results-controls { position: relative; }
    .results-controls > .search-tools { position: static; }
    /* Handset: dropdown panels SPAN their container instead of hugging their button — a left-anchored
       compact panel protrudes past the viewport at large text (and Chromium keeps a CLOSED details'
       content box in layout, so it phantom-overflows even shut). The row/pill is the positioning
       context; the panel inherits its width, which fits the viewport by construction at any zoom. */
    .search-tools { position: relative; }
    .time-menu { position: static; }
    .search-pill { position: relative; }
    .search-plus { position: static; }
    .filters-menu { position: static; }
    /* min-inline-size: 0 — the container span IS the size here; a min floor would override the
       pinned inset-inline edges and push the panel past the viewport at large text. */
    .time-menu-panel, .search-plus-menu, .filters-menu-panel { inset-inline: 0; min-inline-size: 0; }
}

/* Per-search vertical filter bar (Images/News/Videos results) — mirrors .search-tools; compact labelled
   `field-select` dropdowns + a "More filters" disclosure for the image long-tail. Reflows freely (text-scaling). */
.search-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin: 0; }   /* spacing owned by .results-controls */
.search-filter-field { display: inline-flex; min-width: 0; }
.search-filters .field-select { font-size: 0.8125rem; padding: 0.3rem 1.9rem 0.3rem 0.65rem; min-width: 0; }
.search-filters-more { display: inline-block; min-width: 0; }
.search-filters-more > summary {
    list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 0.3rem;
    font-size: 0.8125rem; color: var(--text-muted); white-space: nowrap;
    padding: 0.3rem 0.7rem; border-radius: var(--radius-pill); border: 1px solid var(--border-strong);
}
.search-filters-more > summary::-webkit-details-marker { display: none; }
.search-filters-more > summary::after { content: "▾"; font-size: 0.7em; }
.search-filters-more[open] > summary { color: var(--text); background: var(--surface-2); }
.search-filters-more-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.45rem; }
.search-filters-apply {
    font-size: 0.8125rem; white-space: nowrap; cursor: pointer; color: var(--text);
    padding: 0.3rem 0.8rem; border-radius: var(--radius-pill); border: 1px solid var(--border-strong); background: var(--surface-2);
}
.search-filters-clear { font-size: 0.8125rem; color: var(--text-muted); text-decoration: none; white-space: nowrap; padding: 0.3rem 0.5rem; }
.search-filters-clear:hover { color: var(--text); text-decoration: underline; }

/* ===== Search Control (domain ranking): per-result chip + popover, transparency bar, settings rules ===== */
.rank-control, .rank-adjust { position: relative; display: inline-block; margin-block-start: 0.35rem; }
.rank-control > summary, .rank-adjust > summary { list-style: none; }
.rank-control > summary::-webkit-details-marker, .rank-adjust > summary::-webkit-details-marker { display: none; }
.rank-chip {
    display: inline-flex; align-items: center; justify-content: center; font-size: 0.75rem; cursor: pointer;
    color: var(--text); background: transparent; border: 1px solid var(--border-strong); border-radius: var(--radius-pill);
    padding: 0.2rem 0.5rem; line-height: 1.4; min-inline-size: 2rem; min-block-size: 2rem;
}
.rank-chip:hover, .rank-adjust[open] > .rank-chip, .rank-control[open] > .rank-chip { background: var(--surface-2); }
.rank-chip-neutral:hover, .rank-kebab-chip:hover { color: var(--text); }
.rank-chip:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }
.rank-chip-kebab::before { content: "⋮"; font-weight: 900; font-size: 1.05rem; line-height: 1; }

/* Windows High Contrast / forced-colors: the mask-image state icons (background-color:currentColor) and the color-mix
   "active"/magnitude tints are neutralized by the forced palette — restore a visible marker (WCAG 1.4.11). */
@media (forced-colors: active) {
    .rank-state-ic { background-color: CanvasText; }
    .view-opt.active, .rd-seg-opt.active, .rd-toggle.active { outline: 2px solid Highlight; outline-offset: -2px; }
    .rd-toggle.mixed { outline: 2px dashed Highlight; outline-offset: -2px; }
}
/* Coarse pointers (touch): keep the compact chips + segmented controls ≥24px hittable (WCAG 2.5.8 AA), while staying
   visually tight on a fine pointer (mouse). */
@media (pointer: coarse) {
    .rank-chip { min-block-size: 1.55rem; padding-block: 0.3rem; }
    .view-opt, .adv-chip, .adv-conn button, .rd-seg-opt, .rd-move, .rd-toggle, .rank-unblock {
        min-block-size: 2.75rem;
    }
    .rd-close { width: 2.75rem; height: 2.75rem; }
    .result-sitelink { padding-block: 0.15rem; }
}

/* The rank-adjust INDICATOR (left of the ⋮ kebab) = "where you initiate ranking changes for this site". Its icon is a
   monochrome SVG mask tinted by the chip's `color`; each state sets the icon + colour, and for raised/lowered the
   colour interpolates faint→vivid across the stored weight magnitude (--w = 0..100, set inline from the rule weight). */
.rank-state-ic { display: inline-block; width: 1.05em; height: 1.05em; background-color: currentColor;
    -webkit-mask: var(--ic) center / contain no-repeat; mask: var(--ic) center / contain no-repeat; }
.rank-adjust-chip { color: var(--text-muted);   /* neutral: the tune-sliders "adjust" affordance */
    --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='4' y1='7' x2='20' y2='7'/%3E%3Ccircle cx='10' cy='7' r='2.4' fill='%23000' stroke='none'/%3E%3Cline x1='4' y1='16' x2='20' y2='16'/%3E%3Ccircle cx='15' cy='16' r='2.4' fill='%23000' stroke='none'/%3E%3C/svg%3E"); }
/* Raise/lower arrows share the landing theater's mark geometry (owner, 2026-07-18: the theater's
   indicators are the preferred look — one visual language between the demo and real results).
   Stroke 2.6 matches the theater's smark arrows; the weight-interpolated colour stays (the theater's
   flat green sits inside this hue ramp). */
.rank-adjust-chip.rank-chip-raised { border-color: currentColor;
    color: color-mix(in oklab, #7be3a6, #047857 calc(var(--w) * 1%));
    --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 19V5'/%3E%3Cpath d='m6 11 6-6 6 6'/%3E%3C/svg%3E"); }
.rank-adjust-chip.rank-chip-lowered { border-color: currentColor;
    color: color-mix(in oklab, #fca5a5, #b91c1c calc(var(--w) * 1%));
    --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14'/%3E%3Cpath d='m6 13 6 6 6-6'/%3E%3C/svg%3E"); }
/* Pinned: the theater's teal pin glyph (was a 📌 emoji — owner prefers the theater mark), standing
   ALONE — no oval drawn around it at all: border transparent (not none, so the geometry and the
   ≥24px hit target stay identical) AND no resting background plate, including the tools-row surface
   plate below. Hover/open/focus affordances remain: the hover background and the focus-visible ring
   still show it's the Adjust control. Masked (not inline SVG) so forced-colors renders it CanvasText. */
.rank-adjust-chip.rank-chip-pinned,
.result-card-tools .rank-chip.rank-chip-pinned { border-color: transparent; background: transparent; }
.rank-adjust-chip.rank-chip-pinned:hover,
.rank-adjust[open] > .rank-adjust-chip.rank-chip-pinned { background: var(--surface-2); }
.rank-adjust-chip.rank-chip-pinned { color: var(--brand);
    --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3E%3Cpath d='M4.146.146A.5.5 0 0 1 4.5 0h7a.5.5 0 0 1 .354.854L10.5 2.207v2.586l1.854 1.853A.5.5 0 0 1 12 7.5H8.5v6l-.5.5-.5-.5v-6H4a.5.5 0 0 1-.354-.854L5.5 4.793V2.207L4.146.854A.5.5 0 0 1 4.146.146z'/%3E%3C/svg%3E"); }
:root[data-theme="dark"] .rank-adjust-chip.rank-chip-pinned { color: var(--brand); }
@media (prefers-color-scheme:dark){ :root:not([data-theme="light"]) .rank-adjust-chip.rank-chip-pinned { color: var(--brand); } }
.rank-adjust-chip.rank-chip-blocked { color: var(--text-muted);   /* eye-off — shown when viewing hidden items */
    --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 10 8 10 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24'/%3E%3Cpath d='M6.61 6.61A18.5 18.5 0 0 0 2 12s3 8 10 8a9.12 9.12 0 0 0 5.06-1.44'/%3E%3Cline x1='2' y1='2' x2='22' y2='22'/%3E%3C/svg%3E"); }
.rank-menu {
    position: absolute; inset-block-start: calc(100% + 0.25rem); inset-inline-end: 0; z-index: 40; min-width: min(14rem, calc(100vw - 1.5rem)); max-inline-size: min(14rem, calc(100vw - 1.5rem));
    background: var(--surface, #fff); color: var(--text, #19172a); border: 1px solid var(--border, #ddd); border-radius: var(--radius);
    box-shadow: var(--shadow-lg, 0 8px 28px rgba(0,0,0,.18)); padding: 0.35rem; display: flex; flex-direction: column;
}
.rank-adjust-menu { min-width: min(17rem, calc(100vw - 1.5rem)); max-inline-size: min(17rem, calc(100vw - 1.5rem)); }
.rank-menu-host { font-size: 0.75rem; color: var(--text-muted); padding: 0.25rem 0.5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-act { margin: 0; }
.rank-menu-item {
    display: flex; align-items: center; gap: 0.45rem; inline-size: 100%; text-align: start; background: transparent;
    min-block-size:2.5rem; border: 0; cursor: pointer; padding: 0.4rem 0.5rem; border-radius: var(--radius-sm, 6px); color: var(--text);
    font-size: 0.875rem; text-decoration: none;
}
.rank-menu-item:hover, .rank-menu-item:focus { background: var(--surface-2); outline: none; }
.rank-menu-item:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: -2px; }
.rank-item[aria-checked="true"] { font-weight: 600; color: var(--brand-strong); }
.rank-link::before { content: ""; inline-size: 0.95rem; flex: none; text-align: center; color: var(--text-muted); }
.rank-link[href*="archive.org"]::before { content: "🏛"; }
.rank-link:not([href*="archive.org"])::before { content: "⌕"; font-weight: 700; }
.rank-sep { block-size: 1px; background: var(--border); margin: 0.35rem 0.25rem; }
.rank-group-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); padding: 0.25rem 0.5rem 0.15rem; }
.rank-more { font-size: 0.75rem; color: var(--text-muted); border-block-start: 1px solid var(--border); margin-block-start: 0.25rem; }
.rank-more:hover { color: var(--text); }
/* Translate affordance — shown only when a result's detected language differs from the user's UI language. */
.result-translate {
    display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.7rem; color: var(--text-muted); cursor: pointer;
    min-block-size:1.75rem; text-decoration: none; margin-inline-start: 0.4rem; border: 1px solid var(--control-border); border-radius: var(--radius-pill); padding: 0.15rem 0.55rem;
}
.result-translate:hover { color: var(--text); background: var(--surface-2); }
.result-translate::before { content: "🌐"; font-size: 0.85em; display: inline-block; }
/* In-flight: the icon pulses and stops taking clicks; the text about to change shimmers gently (33-result-translate.ts). */
.result-translate.xlate-busy { pointer-events: none; }
.result-translate.xlate-busy::before { animation: xlate-pulse 0.9s ease-in-out infinite; }
.xlate-pending { animation: xlate-pulse 0.9s ease-in-out infinite; }
@keyframes xlate-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
/* The swapped text lands with a soft fade. */
.xlate-swap { animation: xlate-in 0.3s ease; }
@keyframes xlate-in { from { opacity: 0.25; } to { opacity: 1; } }
/* Post-translate attribution + reversible toggle (replaces the icon after an in-place translation). */
.result-translated { display: inline-flex; align-items: center; gap: 0.45rem; font-size: 0.7rem; color: var(--text-muted); margin-inline-start: 0.4rem; }
.result-translate-toggle {
    display: inline-flex; align-items: center; font: inherit; font-size: 0.7rem; color: var(--text-muted); cursor: pointer;
    min-block-size:1.75rem; background: none; border: 1px solid var(--control-border); border-radius: var(--radius-pill); padding: 0.15rem 0.55rem;
}
.result-translate-toggle:hover { color: var(--text); background: var(--surface-2); }
/* Designer strip in-place feedback: a saved/new card pulses; a deleted card collapses out. */
.rd-card-flash { animation: rd-card-flash 1.5s ease; }
@keyframes rd-card-flash {
    0% { outline: 2px solid var(--brand); outline-offset: 2px; }
    70% { outline: 2px solid var(--brand); outline-offset: 2px; }
    100% { outline: 2px solid transparent; outline-offset: 2px; }
}
.rd-card-removing { animation: rd-card-out 0.22s ease forwards; pointer-events: none; }
@keyframes rd-card-out { to { opacity: 0; transform: scale(0.96); } }
@media (prefers-reduced-motion: reduce) {
    .result-translate.xlate-busy::before, .xlate-pending, .xlate-swap { animation: none; }
    .rd-card-flash, .rd-card-removing { animation: none; }
}
/* Overlay container — lets a kebab sit on an <a>-wrapped vertical card without nesting interactive elements. */
.result-card { position: relative; }
.result-card-tools { position: absolute; inset-block-start: 0.35rem; inset-inline-end: 0.35rem; z-index: 5; margin: 0; display: inline-flex; align-items: center; gap: 0.2rem; }
.result-card-tools .rank-control, .result-card-tools .rank-adjust { margin: 0; }
.result-card-tools .rank-chip { background: var(--surface); }
/* On dense image cells the kebab is revealed on hover/focus (keyboard-reachable), to avoid grid clutter. */
.image-cell-wrap { position: relative; display: block; }
.image-cell-wrap .result-card-tools { opacity: 0; transition: opacity 0.12s ease; }
.image-cell-wrap:hover .result-card-tools,
.image-cell-wrap:focus-within .result-card-tools,
.image-cell-wrap .rank-control[open] { opacity: 1; }
/* A ranked image (pinned/raised/lowered/blocked) always shows its kebab, so its state indicator is visible without
   hover — the hover-reveal governs only neutral cells (keeps the dense grid clean). */
.image-cell-wrap:has(.rank-chip-pinned, .rank-chip-raised, .rank-chip-lowered, .rank-chip-blocked) .result-card-tools { opacity: 1; }
@media (hover: none) { .image-cell-wrap .result-card-tools { opacity: 1; } }
/* Raise the result whose kebab menu is OPEN above the following results, so its popup is never overlapped by
   later result text (each .result-item/.result-card is position:relative, so without this the open menu — capped
   inside its own stacking context — is painted under subsequent siblings). */
.result-item:has(.rank-control[open]),
.result-card:has(.rank-control[open]),
.image-cell-wrap:has(.rank-control[open]) { z-index: 50; }
/* Active search-scope filter chips (e.g. a site: restriction) — one-tap removable. */
.active-filters { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0 0 0.85rem; }
.filter-chip {
    display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.8125rem; text-decoration: none; color: var(--text);
    background: var(--surface-2, #f3efe4); border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 0.2rem 0.65rem;
}
.filter-chip:hover { background: var(--surface, #fff); border-color: var(--brand); }
.filter-chip-x { font-weight: 700; color: var(--text-muted); line-height: 1; }
.filter-chip:hover .filter-chip-x { color: var(--brand); }
.rank-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; font-size: 0.8125rem; margin: 0.25rem 0 0.75rem; }
.rank-summary-part { white-space: nowrap; }
.rank-summary-part + .rank-summary-part::before { content: "·"; margin-inline: 0.5rem 0.5rem; color: var(--text-muted); }   /* both sides — Razor strips inter-part whitespace (the mirror of the .rank-summary-by fix) */
/* "by your rules" trails the count parts inside the (inline) .rank-summary-text. Razor strips the source
   whitespace after the final conditional part block, so without this the words collide ("…raisedby your
   rules"). A logical-start margin restores the space deterministically and stays correct in RTL —
   0.35em (not rem): a hair wider than the font's own word space, so it always READS as one. */
.rank-summary-by { margin-inline-start: 0.35em; }
.rank-reveal summary { cursor: pointer; color: var(--brand-strong); }
.rank-blocked-list { list-style: none; margin: 0.35rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.rank-blocked-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; font-size: 0.8125rem; }
.rank-blocked-host { font-weight: 500; min-width: 0; overflow-wrap: anywhere; }
.rank-unblock { min-block-size: 2rem; background: transparent; border: 1px solid var(--control-border); border-radius: var(--radius-pill); padding: 0.1rem 0.5rem; cursor: pointer; color: var(--text-muted); font-size: 0.75rem; }
.rank-unblock:hover { color: var(--text); background: var(--surface-2); }
.rank-why { font-size: 0.7rem; color: var(--text-muted); margin-inline-start: 0.4rem; }
.rank-why-pinned { color: var(--brand-strong); }
/* Malicious-domain consumer (highlight mode): a restrained in-flow "Flagged" affordance on a result, and the
   "N results removed" notice in remove mode. Danger accent, but understated; reflow-friendly (rem, flex-wrap,
   min-width:0). NEVER names a feed/source. */
.malicious-flagged { border-inline-start: 3px solid var(--danger, #b42318); padding-inline-start: 0.6rem; }
.malicious-warning { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; margin: 0.1rem 0 0.15rem; font-size: 0.75rem; color: var(--danger, #b42318); }
.malicious-warning-badge { font-size: 0.85rem; line-height: 1; }
.malicious-warning-text { font-weight: 600; min-width: 0; cursor: help; }
.malicious-removed { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; font-size: 0.8125rem; color: var(--text-muted); margin: 0.25rem 0 0.75rem; }
.malicious-removed-icon { color: var(--danger, #b42318); }
.malicious-removed-count { font-weight: 600; color: var(--text); }
/* Inline (vertical) flag variant: sits in a card meta row without the block's vertical margins; flex-wraps so the card still reflows at large text. */
.malicious-warning-inline { display: inline-flex; margin: 0; }
/* Image grid flag: no left bar/padding (would shift the cell) — a red ring on the thumbnail + a corner ⚠ badge. */
.image-cell-wrap.malicious-flagged { border-inline-start: 0; padding-inline-start: 0; }
.image-cell-wrap.malicious-flagged .image-cell { outline: 3px solid var(--danger, #b42318); outline-offset: -3px; }
.malicious-flag-corner { position: absolute; inset-block-start: 0.3rem; inset-inline-start: 0.3rem; z-index: 4; background: var(--danger, #b42318); color: var(--brand-contrast, #fff); border-radius: 4px; padding: 0 0.25rem; font-size: 0.8rem; line-height: 1.35; }
.rank-toggle { font-size: 0.8125rem; margin: 0 0 0.5rem; }
.rank-toggle-link { color: var(--text-muted); text-decoration: none; }
.rank-toggle-link:hover { color: var(--text); text-decoration: underline; }
/* The "N filters" state link — rides the time-chips row, set off from the chips by a wider gap.
   "on" means the current results apply the user's rules; "off" is the unfiltered comparison. */
.search-tool-filters { margin-inline-start: 1.25rem; }
.search-tool-filters[data-personalize="on"] { background: var(--brand-soft); color: var(--brand-strong);
    border-color: var(--brand-strong); }
.search-tool-filters[data-personalize="off"] { border-style: dashed; }

/* ---- Live rank preview: the ghost while the Adjust slider drags ---- */
/* The initiating result keeps its place under a dashed outline; a caret + translucent chip mark the
   predicted slot (overlay-positioned — nothing reflows under a held slider). Block previews as the
   fade the collapse will deliver. */
.rank-preview-source { outline: 2px dashed var(--brand-strong); outline-offset: 3px; border-radius: var(--radius-sm); }
.rank-preview-source-hidden { opacity: 0.45; }
.rank-preview-caret {
    position: absolute; inset-inline: 0.25rem; height: 2px; border-radius: 1px;
    background: var(--brand-strong); z-index: 24; pointer-events: none;
    transition: top 0.16s ease;
}
.rank-preview-caret::before {
    content: ""; position: absolute; inset-inline-start: -0.25rem; top: -3px;
    width: 8px; height: 8px; border-radius: 50%; background: var(--brand-strong);
}
.rank-preview-ghost {
    position: absolute; inset-inline-start: 1rem; transform: translateY(-50%);
    z-index: 25; pointer-events: none;
    display: flex; align-items: center; gap: 0.45rem; max-width: min(30rem, 85%);
    padding: 0.25rem 0.7rem; border: 1px dashed var(--brand-strong); border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--brand-soft) 60%, var(--surface));
    font-size: 0.8rem; color: var(--text); opacity: 0.94; box-shadow: var(--shadow-md, 0 4px 14px rgb(0 0 0 / 0.18));
    transition: top 0.16s ease;
}
.rank-preview-favicon { width: 14px; height: 14px; border-radius: 3px; flex: none; }
.rank-preview-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-preview-count { flex: none; font-weight: 700; color: var(--brand-strong); white-space: nowrap; }
/* Predicted slot outside the viewport → a fixed edge chip points the way (no auto-scroll mid-drag). */
.rank-preview-edge {
    position: fixed; inset-inline-start: 50%; transform: translateX(-50%); z-index: 70;
    padding: 0.3rem 0.85rem; border: 1px solid var(--brand-strong); border-radius: var(--radius-pill);
    background: var(--surface); color: var(--brand-strong); font-size: 0.8rem; font-weight: 700;
    box-shadow: var(--shadow-md, 0 4px 14px rgb(0 0 0 / 0.18)); pointer-events: none;
}
[dir="rtl"] .rank-preview-edge { transform: translateX(50%); }
@media (prefers-reduced-motion: reduce) {
    .rank-preview-caret, .rank-preview-ghost { transition: none; }
}
.rank-toast {
    position: fixed; inset-block-end: 1.25rem; inset-inline-start: 50%; transform: translateX(-50%); z-index: 100;
    background: var(--text); color: var(--surface); border-radius: var(--radius-pill); padding: 0.5rem 1rem;
    display: flex; align-items: center; gap: 0.75rem; box-shadow: var(--shadow-lg, 0 8px 28px rgba(0,0,0,.25)); font-size: 0.875rem; max-inline-size: 90vw;
}
.rank-toast-undo { background: transparent; border: 0; color: var(--brand, #6ea8fe); cursor: pointer; font-weight: 600; }
/* Failed ranking change (didn't persist) — a warm/danger background so it reads as an error, not a confirmation. */
.rank-toast-error { background: var(--danger, #b42318); color: var(--brand-contrast, #fff); }
.rule-group { margin-block-end: 1rem; }
.rule-group-title { font-size: 0.875rem; margin: 0 0 0.4rem; }
.rule-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.3rem; }
.rule-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.rule-pattern { font-weight: 500; min-width: 0; overflow-wrap: anywhere; }
/* A built-in view's one-line description under its name in the Settings opt-in list. */
.sc-view-desc { display: block; font-weight: 400; font-size: 0.85rem; margin-block-start: 0.1rem; max-width: 38rem; }
.rule-match { font-size: 0.75rem; }
.rule-add { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-block-start: 1rem; }
/* Handset (incl. large-font text-zoom, which shrinks the em-measured viewport): the popovers become a fixed
   BOTTOM SHEET. A right-anchored absolute panel overflowed the inline-start viewport edge as soon as its
   clamped width exceeded the anchor's distance to that edge; fixed viewport insets make overflow impossible at
   any text size. Same <details> element — the existing outside-click/Escape close handling applies unchanged. */
@media (max-width: 32em) {
    .rank-menu, .rank-adjust-menu {
        position: fixed; inset-inline: 0.75rem; inset-block-start: auto; inset-block-end: 0.75rem;
        min-width: 0; max-inline-size: none;
        max-block-size: min(75vh, calc(100dvh - 1.5rem)); overflow: auto;
        z-index: var(--z-modal, 1000);
    }
}

/* --- Search Control landing showcase ("Bury the noise") --- */
/* Roomier rhythm (owner, 2026-07-18: the section read slightly too compact): more air between the
   header and the grid, between rules, and before the foot line. */
.sc-showcase-grid{display:flex;flex-wrap:wrap;gap:2.5rem;align-items:center;justify-content:center;margin-top:2.25rem}
.sc-points{flex:1 1 22rem;min-width:0;list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1.6rem}
.sc-points li{display:flex;gap:.75rem;align-items:flex-start}
.sc-point-ico{flex:0 0 1.75rem;text-align:center;font-size:1.25rem;line-height:1.5}
/* The rule marks are the demo theater's smark imagery verbatim (owner, 2026-07-20): bare colored
   SVG glyphs in ONE uniform box — no containing discs (the old badges centered inconsistently and
   their light-mode triangles lacked contrast against the fills). currentColor carries the meaning
   with the theater's own hues; the pin nudges down a hair because its 16-viewBox glyph rides high
   next to the 24-viewBox arrows. */
.sc-mark{display:flex;align-items:center;justify-content:center;width:1.35rem;height:1.35rem;margin-inline:auto}
.sc-mark svg{width:100%;height:100%;display:block}
.sc-points .sc-mark--pin{color:var(--brand)}
.sc-mark--pin svg{width:1.1rem;height:1.1rem;margin-top:.1rem}
.sc-points .sc-mark--up{color:#2e9e5b}
.sc-points :is(.sc-mark--pin,.sc-mark--up){position:relative;inset-block-start:.1em}
.sc-points .sc-mark--lower{color:var(--text-muted)}
.sc-points .sc-mark--block{color:var(--danger)}
.sc-points p{margin:0}
.sc-points span{color:var(--text-muted)}
/* Decorative demo: cap to the available width (max-width:100%) and allow it to shrink (flex shrink + min-width:0)
   so the 16rem box can't force horizontal scroll at large text / narrow viewports. */
.sc-demo{flex:1 1 16rem;max-width:100%;min-width:0;display:flex;flex-direction:column;gap:.6rem;padding:1rem;border:1px solid rgba(127,127,127,.25);border-radius:.75rem}
.sc-demo-row{display:flex;align-items:center;gap:.6rem;padding:.5rem;border-radius:.5rem;background:rgba(127,127,127,.08)}
.sc-demo-dot{flex:0 0 auto;width:.7rem;height:.7rem;border-radius:50%;background:rgba(127,127,127,.4)}
.sc-demo-bar{flex:1 1 auto;height:.55rem;border-radius:.3rem;background:rgba(127,127,127,.35)}
.sc-demo-raise .sc-demo-dot{background:#2e9e5b}
.sc-demo-block .sc-demo-dot{background:#d05a4e}
@media (prefers-reduced-motion:no-preference){
  .sc-demo-block{animation:sc-fade 6s ease-in-out infinite}
  .sc-demo-raise{animation:sc-rise 6s ease-in-out infinite}
}
@keyframes sc-fade{0%,18%{opacity:1}32%,72%{opacity:.18}100%{opacity:1}}
@keyframes sc-rise{0%,18%{transform:translateY(0)}32%,72%{transform:translateY(-3.1rem)}100%{transform:translateY(0)}}
.sc-showcase-foot{text-align:center;color:var(--text-muted);max-width:52ch;margin:2.25rem auto 0}


/* ---------------- Landing: ambient backdrop ---------------- */
/* Owner, 2026-07-21: subtle background interest for the scrollthrough — the hero's silk current
   continues down the page as a thread trio, and five brand-family light pools alternate sides
   as chapters change (same-day presence bump: "slightly more aggressive, remain aesthetically
   pleasing" — opacities/strokes lifted, a fifth pool fills the 27→62% gap, two pools take the
   fixed periwinkle #98a5ea for hue depth; family colors are theme-neutral like the ribbons). Deliberately STATIC (no scroll listeners, no animation —
   nothing for reduced motion to fight) and token-driven so both themes come free. The glow
   anchors are ambient page-proportional positions, not registered to specific sections — they
   tolerate content growth. */
/* The final 1.25rem of ribbon clearance belongs to the landing's padding box. A margin on the
   final child sits outside this box, so the absolutely-positioned backdrop cannot paint it and a
   body-colored seam appears before the footer (especially obvious in dark mode / at text zoom). */
.landing{position:relative;padding-bottom:1.25rem}
/* Fail static. The coordinator is the only code allowed to opt these four >5-second systems into
   running motion. Explicit pause freezes CSS at its current frame; the two JS conductors also clear
   their timers through suede:landing-motionchange. */
.landing:not([data-landing-motion="running"]) :is(
  .hero-flow,.hero-flow path,.sc-demo-block,.sc-demo-raise,.fitlab,.fitlab *,.theater,.theater *
){animation-play-state:paused!important}
.landing[data-landing-motion="paused"] :is(.fitlab,.fitlab *,.theater,.theater *){
  transition:none!important}
/* stacking guard: every top-level landing block paints above the backdrop */
.landing>*{position:relative;z-index:1}
/* The Ukraine ribbon is now the landing's final child so the ambient tail reaches its resting
   place. Preserve its sticky behavior against the more-specific stacking guard above. */
.landing>.ua-ribbon{position:sticky;z-index:var(--z-fixed)}
.landing>.landing-backdrop{position:absolute;inset:0;bottom:calc(0px - var(--marketing-footer-gap));
  z-index:0;pointer-events:none;overflow:hidden;
  background-image:
    radial-gradient(64rem 44rem at 12% 5%,  color-mix(in srgb, var(--brand) 8%, transparent), transparent 64%),
    radial-gradient(58rem 40rem at 90% 27%, color-mix(in srgb, #98a5ea 8%, transparent), transparent 64%),
    radial-gradient(52rem 36rem at 82% 46%, color-mix(in srgb, var(--brand) 6%, transparent), transparent 62%),
    radial-gradient(62rem 44rem at 8% 62%,  color-mix(in srgb, var(--brand) 7%, transparent), transparent 64%),
    radial-gradient(70rem 48rem at 50% 98%, color-mix(in srgb, #98a5ea 10%, transparent), transparent 68%)}
/* SECTION TONE BANDS: every registered chapter receives a non-overlapping tonal plateau whose
   value fades to the ambient page ground at its edges. Alternating tone and whitespace—not
   ornamental rules—define the chapter changes. Adjacent bands meet at zero opacity, so the
   shared boundary stays neutral instead of becoming a darker overlap strip. */
.lb-band{
  position:absolute;inset-inline-start:-6%;inline-size:112%;pointer-events:none;
  background:none;--lb-fade:clamp(2.5rem,5vw,5rem)}
.lb-band::after{
  content:"";position:absolute;inset:0;background:var(--lb-fill);
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 var(--lb-fade),
    #000 calc(100% - var(--lb-fade)),transparent);
  mask-image:linear-gradient(to bottom,transparent,#000 var(--lb-fade),
    #000 calc(100% - var(--lb-fade)),transparent)}
.lb-band--a{--lb-fill:
  radial-gradient(48rem 30rem at 20% 28%,
    color-mix(in srgb,var(--brand) 10%,transparent),transparent 62%),
  color-mix(in srgb,var(--brand) 6.5%,transparent)}
.lb-band--b{--lb-fill:
  radial-gradient(52rem 34rem at 80% 22%,
    color-mix(in srgb,#98a5ea 7%,transparent),transparent 62%),
  color-mix(in srgb,var(--brand) 4.25%,transparent)}
.lb-band--c{--lb-fill:
  radial-gradient(46rem 30rem at 16% 68%,
    color-mix(in srgb,#b0bbfb 13%,transparent),transparent 60%),
  color-mix(in srgb,#98a5ea 8.5%,transparent)}
:root[data-contrast="high"] .lb-band::after{display:none}
@media (forced-colors:active){
  .lb-band::after{display:none}
}

/* ---------------- Landing: result-designer vignette (fit section) ---------------- */
/* v2 (owner, 2026-07-21): ONE search result being edited on a drafting canvas — its pieces get
   selected, dragged, and restyled, which is the real designer's activity (v1 showed the settings
   controls instead). Conductor 76-fit-designer.ts walks [data-beat="0..3"]; beats are CUMULATIVE
   (rest → title font raised → favicon+domain row dragged above the title → description restyled
   smaller) then loop-reset. NOT-REAL-UI cues, by owner concern: dotted drafting canvas, corner
   Demo tag, ghost cursor doing the acting, skeleton bars instead of text, pointer-events:none.
   All sizing rem (reflow mandate); tokens only, both themes free. Cursor/chip loci are plain
   rem offsets INSIDE the card (they're .fitres children): pieces are start-aligned, so the
   offsets stay glued to them at any card width — including handsets where the card is narrower
   than its 26rem cap. */
/* The Arranger owns a complete chapter. On wide screens its unframed illustration and the live
   Result Designer are peers; at reflow widths this intrinsic flex composition wraps without
   clipping either one. The 42rem art cap guarantees downscaling from the 1344px master. */
.fit-garden{
  position:relative;isolation:isolate;overflow:hidden;
  padding-block:clamp(4.75rem,7vw,7rem);
  box-sizing:border-box}
.fit-garden-stage{
  position:relative;isolation:isolate;display:block;overflow:visible;
  min-block-size:0;padding:0;
  inline-size:min(78rem,calc(100% - 2.5rem));margin-inline:auto;
  box-sizing:border-box;direction:ltr}
.fit-garden-head{
  position:relative;grid-column:auto;grid-row:auto;
  inline-size:min(68rem,100%);margin:0 auto clamp(3rem,5vw,4.5rem)}
.fit-garden-head .section-title{text-align:center}
.fit-garden-body{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(2rem,4vw,4rem);direction:ltr}
.fit-garden-art{
  position:relative;inset:auto;padding:0;flex:1 1 31rem;min-inline-size:min(31rem,100%);
  max-inline-size:min(42rem,1344px,100%);margin:0;direction:ltr;pointer-events:none}
.fit-garden-art .ill-fitpop,
.fit-garden-art .ill-fitpop img{
  display:block;inline-size:100%;block-size:auto;max-inline-size:none}
.fit-garden-content{
  position:relative;z-index:auto;grid-column:auto;grid-row:auto;align-self:center;
  flex:1 1 31rem;min-inline-size:min(31rem,100%);
  max-inline-size:36rem;display:grid;gap:clamp(1.5rem,2vw,1.75rem)}
html[dir="rtl"] .fit-garden-head,
html[dir="rtl"] .fit-garden-content{direction:rtl}
.fit-garden-content>.fitlab{
  width:100%;max-width:none;min-width:0;margin:0;direction:ltr}
.fit-garden-content>.fitlab>.fitlab-canvas{
  width:100%;min-height:20rem;display:grid;align-items:center;
  background:
    radial-gradient(color-mix(in srgb,var(--text) 10%,transparent) 1px,transparent 1.4px)
      0 0/1.1rem 1.1rem,
    linear-gradient(to right,
      color-mix(in srgb,var(--surface) 58%,transparent),
      color-mix(in srgb,var(--surface) 84%,transparent) 44%,
      color-mix(in srgb,var(--surface) 92%,transparent));
  box-shadow:0 1.2rem 3rem color-mix(in srgb,var(--text) 10%,transparent)}
.fit-garden-copy{
  position:relative;max-inline-size:33rem;margin:0 auto;
  padding:clamp(1.1rem,1.8vw,1.35rem) clamp(1.2rem,2vw,1.5rem);
  color:var(--text);text-align:start;text-wrap:pretty;line-height:1.65;
  background:color-mix(in srgb,var(--bg) 90%,transparent);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  box-shadow:0 .8rem 2rem color-mix(in srgb,var(--text) 8%,transparent);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}

/* The flex bases already wrap for enlarged text. This breakpoint only tightens handset/tablet
   rhythm after the composition has become title → art → demo → caption. */
@media (max-width:63.99em){
  .fit-garden{overflow:visible}
  .fit-garden-head{margin-block-end:clamp(2.25rem,7vw,3.5rem)}
  .fit-garden-body{row-gap:clamp(2.25rem,7vw,3.5rem)}
  .fit-garden-art{flex-basis:100%;max-inline-size:42rem;margin-inline:auto}
  .fit-garden-content{
    flex-basis:100%;max-inline-size:44rem;margin-inline:auto;
    gap:clamp(1.25rem,4vw,1.75rem)}
  .fit-garden-copy{max-inline-size:40rem}
}

@media (forced-colors:active){
  .fit-garden-art{display:none}
  .fit-garden-body{display:block}
  .fit-garden-content{max-inline-size:52rem;margin-inline:auto}
  .fit-garden-copy{background:Canvas;color:CanvasText;border:1px solid CanvasText;
    box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none}
}
.fitlab{max-width:44rem;margin:2.25rem auto 1.75rem;pointer-events:none}
.fitlab-canvas{position:relative;border:1px dashed var(--border-strong);border-radius:var(--radius-lg);
  background-color:var(--surface);
  background-image:radial-gradient(color-mix(in srgb,var(--text) 9%,transparent) 1px,transparent 1.4px);
  background-size:1.1rem 1.1rem;
  padding:3.2rem 1.5rem 2.4rem;min-height:13rem;overflow:hidden}
.fitlab-cap{position:absolute;top:.95rem;inset-inline-start:1.15rem;font-size:.72rem;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--text-muted)}
/* Shared not-real-UI tag (owner, 2026-07-21): the fit vignette's canvas corner and the demo
   theater's stage corner carry the same localized DEMO pill, so every mock surface on the page
   declares itself. The stage variant sits bottom-right INSIDE the panel — .stage has
   contain:content (paint containment), so anything straddling the border would be clipped. */
.fitlab-demo,.stage-demo{position:absolute;font-size:.66rem;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted);
  padding:.24rem .62rem;border:1px solid var(--border-strong);border-radius:var(--radius-pill);
  background:var(--surface-2);pointer-events:none}
.fitlab-demo{top:.8rem;inset-inline-end:1rem}
.stage-demo{top:.6rem;inset-inline-end:.75rem;z-index:4}

/* The single result under edit. Fixed width cap so every locus below stays truthful. */
.fitres{position:relative;width:min(26rem,100%);margin-inline:auto;background:var(--bg-elevated);
  border:1px solid var(--border);border-radius:.7rem;box-shadow:var(--shadow-md);
  padding:1.1rem 1.2rem;display:flex;flex-direction:column;align-items:flex-start;gap:.55rem}
/* Real result text (owner, 2026-07-21): title reads as a result link; single line (ellipsis)
   keeps its height deterministic so the beat-2 swap translates stay exact at every width. */
.fr-t{position:relative;max-width:100%;font-size:.95rem;line-height:1.3;font-weight:600;
  color:var(--brand);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  transition:font-size .5s ease,transform .8s ease .34s,box-shadow .3s ease}
.fr-head{position:relative;display:inline-flex;align-items:center;gap:.45rem;
  transition:transform .8s ease .34s,box-shadow .3s ease}
/* Serif W favicon tile — a generic letter in Wikipedia's visual register, not the logo mark. */
.fr-fav{flex:none;width:.95rem;height:.95rem;border-radius:.28rem;border:1px solid var(--border);
  background:#fff;color:#202122;display:inline-flex;align-items:center;justify-content:center;
  font-family:Georgia,'Times New Roman',serif;font-size:.62rem;font-weight:700;line-height:1;font-style:normal}
.fr-head{max-width:100%}
.fr-u{font-size:.78rem;line-height:1.35;color:var(--text-muted);font-family:var(--font-mono);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;font-weight:500}
/* Two-line clamped summary — the clamp makes the description's height a pure function of its
   font size, which is exactly what beat 3 manipulates. */
.fr-desc{position:relative;align-self:stretch;font-size:.8rem;line-height:1.5;color:var(--text-muted);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  transition:font-size .45s ease,line-height .45s ease,box-shadow .3s ease}

/* Beat 1+ — the title's font size is raised. */
.fitlab:is([data-beat="1"],[data-beat="2"],[data-beat="3"]) .fr-t{font-size:1.14rem}
/* Beat 2+ — the favicon+domain row is dragged above the title: pure transforms (no reflow), the
   two pieces trade places. Distances pinned to the measured text metrics (grown title 1.48rem +
   gap .55 moves the head up; head row 1.05rem + gap .55 moves the title down) — deterministic
   because title/URL are single-line ellipsis and the summary is clamped. */
.fitlab:is([data-beat="2"],[data-beat="3"]) .fr-head{transform:translateY(-2.03rem)}
.fitlab:is([data-beat="2"],[data-beat="3"]) .fr-t{transform:translateY(1.6rem)}
/* Beat 3 — the description's font is set smaller and denser (the clamp then shows more of the
   summary in less height — exactly what a compact result style does). */
.fitlab[data-beat="3"] .fr-desc{font-size:.7rem;line-height:1.4}

/* Selection: accent ring + corner handles on the piece the current beat is editing. */
.fitlab[data-beat="1"] .fr-t,
.fitlab[data-beat="2"] .fr-head,
.fitlab[data-beat="3"] .fr-desc{box-shadow:0 0 0 1.5px var(--accent),0 0 0 4.5px color-mix(in srgb,var(--accent) 16%,transparent)}
.fr-t::before,.fr-t::after,.fr-head::before,.fr-head::after,.fr-desc::before,.fr-desc::after{
  content:"";position:absolute;width:.32rem;height:.32rem;border-radius:.08rem;background:var(--accent);
  opacity:0;transition:opacity .3s ease}
.fr-t::before,.fr-head::before,.fr-desc::before{top:-.16rem;inset-inline-start:-.16rem}
.fr-t::after,.fr-head::after,.fr-desc::after{bottom:-.16rem;inset-inline-end:-.16rem}
.fitlab[data-beat="1"] .fr-t::before,.fitlab[data-beat="1"] .fr-t::after,
.fitlab[data-beat="2"] .fr-head::before,.fitlab[data-beat="2"] .fr-head::after,
.fitlab[data-beat="3"] .fr-desc::before,.fitlab[data-beat="3"] .fr-desc::after{opacity:1}

/* Action chips — pop in near the edited piece once the cursor lands. Literal "Aa±" is
   typographic shorthand, not copy (the vignette is aria-hidden and dir=ltr like all mock UI).
   Chips + cursor are positioned INSIDE .fitres in plain rem from the card's edges — width-proof:
   the pieces are start-aligned in the card, so these offsets hold at any card width. */
.fitlab-chip{position:absolute;z-index:2;display:inline-flex;align-items:center;
  padding:.26rem .55rem;border-radius:var(--radius);border:1px solid var(--accent);
  background:var(--surface);color:var(--text);font-size:.74rem;font-weight:700;line-height:1;
  box-shadow:var(--shadow-sm);opacity:0;transform:translateY(.3rem);
  transition:opacity .35s ease,transform .35s ease}
.fitlab-chip .fi{width:.9rem;height:.9rem}
.fitlab-chip--grow{top:-.85rem;inset-inline-end:.9rem}
.fitlab-chip--move{top:-.85rem;inset-inline-start:.9rem}  /* above the dragged row's landing spot */
.fitlab-chip--shrink{top:6.8rem;inset-inline-end:1rem}
.fitlab[data-beat="1"] .fitlab-chip--grow,
.fitlab[data-beat="2"] .fitlab-chip--move,
.fitlab[data-beat="3"] .fitlab-chip--shrink{opacity:1;transform:none;transition-delay:.55s}

/* Ghost cursor: glides to the piece each beat edits; the drag beat rides WITH the row (keyframe
   waypoints: leave the title, grab the row where it sits, carry it to the top — the row's own
   transform delay .34s keeps the two motions in step). Loci measured against the rendered card
   and pinned per the header note. */
.fitlab-cursor{position:absolute;z-index:3;width:1.05rem;height:1.05rem;border-radius:50%;
  background:color-mix(in srgb,var(--text) 22%,transparent);
  box-shadow:0 0 0 2px color-mix(in srgb,var(--text) 30%,transparent);
  top:1.35rem;inset-inline-start:min(6.45rem,28%);opacity:0;
  transition:top .6s ease,inset-inline-start .6s ease,opacity .3s ease}
.fitlab[data-beat="1"] .fitlab-cursor{opacity:.85;top:1.35rem;inset-inline-start:min(6.45rem,28%);
  animation:fitlab-click-a .55s ease .5s both}
.fitlab[data-beat="2"] .fitlab-cursor{opacity:.85;top:1.15rem;inset-inline-start:min(3.75rem,16%);
  animation:fitlab-drag 1.2s ease both}
.fitlab[data-beat="3"] .fitlab-cursor{opacity:.85;top:5.25rem;inset-inline-start:min(8.9rem,38%);
  animation:fitlab-click-c .55s ease .5s both}
@keyframes fitlab-click-a{50%{transform:scale(.72)}}
@keyframes fitlab-click-c{50%{transform:scale(.72)}}
@keyframes fitlab-drag{
  0%{top:1.35rem;inset-inline-start:min(6.45rem,28%);transform:scale(1)}
  34%{top:3.18rem;inset-inline-start:min(3.75rem,16%);transform:scale(.78)}
  100%{top:1.15rem;inset-inline-start:min(3.75rem,16%);transform:scale(1)}
}

/* Handset: the vignette becomes a content-sized two-row grid. The old 20rem canvas minimum grew
   into large empty bands with enlarged text, while its implicit auto track expanded to the
   nowrap result text's intrinsic width and let overflow:hidden crop the card's right side.
   A real label row removes the absolute-positioning reserve; minmax(0,1fr) and min-inline-size:0
   let the unchanged demo shrink only to the available canvas width. The more-specific fitlab
   selector is intentional: the former bare .fitlab margin lost to the wide-layout rule above. */
@media (max-width:34em){
  .fit-garden-content>.fitlab{
    inline-size:calc(100% + 1.5rem);margin-inline:-.75rem}
  .fit-garden-content>.fitlab>.fitlab-canvas{
    min-block-size:0;grid-template-columns:minmax(0,1fr) auto;align-items:start;
    column-gap:.75rem;row-gap:1rem;padding:.8rem .65rem 1.25rem}
  .fitlab-cap,.fitlab-demo{position:static}
  .fitlab-cap{
    min-inline-size:0;max-inline-size:none;white-space:normal;overflow-wrap:anywhere;
    align-self:center;line-height:1.2}
  .fitlab-demo{justify-self:end;align-self:start}
  .fitres{
    grid-column:1/-1;inline-size:100%;max-inline-size:26rem;min-inline-size:0;
    justify-self:center}
}

/* Handset art (owner, 2026-07-21): the frameless drawings break out of the container gutters and
   run edge-to-edge — at ~360px the extra 2.5rem of width is a visibly larger stage, and the
   transparent pencil scenes have no frame to collide with the viewport edge. The -1.25rem pairs
   with .container's padding-inline. The cinematic privacy band already owns its handset
   presentation (cover + focal bias + 24rem floor). */
@media (max-width:34em){
  .section-lead{margin-inline:-1.25rem}
  /* The demo's Signal, Found lead goes wider than the viewport; its tangle bleeds off-page by
     design, so a 6%-per-side crop only enlarges the subject. The figure clips; the page never
     scrolls horizontally. */
  .section-lead--wide{overflow:hidden}
  .section-lead--wide .ill-hand img{width:112%;max-width:none;margin-inline:-6%}
}

/* ------------------------- Landing: demo theater ------------------------- */
/* Six self-playing scenes driven by 78-demo-theater.ts through [data-scene="0..5"] +
   [data-phase="type|react|hold"] (+ [data-suggest] for the @ beats' mock autosuggest) on
   .theater — ALL choreography lives here. The rail's caption
   cards are the accessible content (real text, real buttons); the stage is aria-hidden. Sizing is
   rem/em only, rows collapse via a generous max-height cap (9rem — roomy even at 200% root font),
   the layout stacks on an em breakpoint, and BOTH reduced-motion channels (the OS media query and
   the site's html[data-motion="reduce"] toggle) drop every animation/transition — the JS holds the
   end-state, so static mode is complete, not broken. The stage forces dir="ltr" (query grammar is
   LTR, like the real box); the rail stays logical for RTL. */
.theater{display:grid;grid-template-columns:minmax(16rem,22rem) minmax(0,1fr);gap:1.25rem;max-width:64rem;margin:1.5rem auto 0;align-items:stretch}
@media (max-width:56em){
  .theater{grid-template-columns:minmax(0,1fr)}
  /* Handset flow (owner, 2026-07-21): the stage used to come first and users watched the
     animation without realizing the step detail sat below. Now the CURRENT step's card holds a
     constant top slot, the other steps collapse to a tappable glyph strip beneath it, and the
     stage follows. The em breakpoint fires earlier under text zoom, so large-font phones get
     this flow too. Inactive steps' copy stays in the a11y tree (sr-only pattern inline — the
     hiding is breakpoint-conditional) so every button keeps its accessible name. */
  .theater .stage{order:2}
  /* .theater prefix: the rail's base column rule sits LATER in this file — equal specificity
     would let it win the cascade over these media overrides. */
  .theater .theater-rail{flex-direction:row;flex-wrap:wrap;justify-content:center;align-items:stretch;gap:.45rem}
  .theater .theater-rail li{display:flex;min-width:0}
  .theater .theater-rail li:has(.theater-step[aria-current]){flex:1 1 100%;order:0}
  .theater .theater-rail li:not(:has(.theater-step[aria-current])){order:1;flex:0 0 auto}
  .theater .theater-rail li:not(:has(.theater-step[aria-current])) .theater-step{padding:.55rem .7rem}
  .theater .theater-rail li:not(:has(.theater-step[aria-current])) .theater-copy{
    position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap;border:0}
}
.theater-rail{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
/* Spotlight model (owner, 2026-07-18 — replaced the per-step progress underline): the playing card
   sits proud through scale, a brand border, and a soft glow. Inactive cards recede through their
   neutral surface and glyph treatment — never whole-control opacity, because their labels and
   descriptions remain meaningful button text. The only motion is a slow halo breath on the active
   glyph chip: a "this one is alive" cue, never a countdown. */
.theater-step{position:relative;display:flex;gap:.7rem;align-items:flex-start;width:100%;text-align:start;
  padding:.7rem .85rem;border:1px solid var(--control-border);border-radius:var(--radius);
  background:color-mix(in srgb,var(--surface) 76%,var(--surface-2));cursor:pointer;
  color:var(--text-muted);overflow:visible;font:inherit;
  transition:color .35s ease,transform .35s ease,border-color .35s ease,background .35s ease,box-shadow .35s ease}
.theater-step:hover{border-color:var(--brand-strong);background:var(--surface-2);color:var(--text)}
.theater-step:focus-visible{outline:2px solid var(--brand);outline-offset:2px;color:var(--text)}
.theater-step[aria-current="step"]{transform:scale(1.02);
  border-color:var(--brand-strong);background:var(--bg-elevated);color:var(--text);
  box-shadow:0 .4rem 1.5rem color-mix(in srgb,var(--brand) 16%,transparent)}
.theater-glyph{flex:none;width:1.9rem;height:1.9rem;display:flex;align-items:center;justify-content:center;
  border-radius:.55rem;background:var(--brand-soft);color:var(--brand-strong);font-weight:700;font-size:.95rem;font-family:var(--font-mono)}
.theater-step:not([aria-current="step"]) .theater-glyph{background:var(--surface-2);color:var(--text-muted)}
.theater-step[aria-current="step"] .theater-glyph{animation:glyph-breathe 2.6s ease-in-out infinite}
@keyframes glyph-breathe{50%{box-shadow:0 0 0 .4rem color-mix(in srgb,var(--brand) 20%,transparent)}}
.theater-glyph svg{width:1.05rem;height:1.05rem}
.theater-copy{display:block;min-width:0;overflow-wrap:anywhere}  /* "@docs+week:" is one unbreakable token at 200% */
.theater-copy strong{display:block;font-size:.95rem;color:var(--text);margin-bottom:.15rem}
.theater-copy span{font-size:.85rem;line-height:1.45}

/* The stage carries the same drafting-canvas register as the fit vignette (owner, 2026-07-21:
   the bottom-corner DEMO pill alone read too quiet — dashed border + dotted canvas + the pill
   moved to a reserved top band make "this is a staged demo" unmistakable). Scene geometry is
   untouched: the extra top padding only reserves the tag band. */
.stage{border:1px dashed var(--border-strong);border-radius:var(--radius);
  background-color:var(--surface);
  background-image:radial-gradient(color-mix(in srgb,var(--text) 9%,transparent) 1px,transparent 1.4px);
  background-size:1.1rem 1.1rem;
  padding:2.5rem 1rem 1rem;
  display:flex;flex-direction:column;gap:.7rem;min-height:20rem;contain:content}
.stage-pill{position:relative;display:flex;align-items:center;gap:.6rem;border:1px solid var(--border-strong);border-radius:var(--radius-pill);
  padding:.6rem 1rem;background:var(--bg);min-width:0}
.stage-lens{flex:none;width:1.05em;height:1.05em;color:var(--text-muted)}
.stage-q{display:flex;align-items:center;min-width:0;min-height:1.35em;font-family:var(--font-mono);font-size:.95rem;white-space:pre;overflow:hidden}
.stage-caret{flex:none;width:2px;height:1.15em;margin-inline-start:1px;background:var(--brand);animation:stage-caret 1.05s steps(1) infinite}
@keyframes stage-caret{50%{opacity:0}}

/* Mock autosuggest for the @ beats — the real .sc-suggest's visual grammar (surface panel, glyph ·
   trigger · muted dest · origin pill) under theater-scoped classes, anchored to the pill (which is
   position:relative — .stage's contain:content would otherwise be the containing block and the
   popup would hug the stage edge). Revealed by the conductor's [data-suggest] ONLY during the type
   phase, so "cleared at submit" is structural; per-scene row choice keys off [data-scene], with the
   stacked scene flipping snap→week via the attr VALUE. Decorative (inside the aria-hidden stage). */
.ssg{position:absolute;inset-inline-start:.9rem;top:calc(100% + .3rem);z-index:3;min-width:14rem;max-width:min(24rem,92%);
  background:var(--surface);border:1px solid rgba(127,127,127,.25);border-radius:.6rem;box-shadow:0 6px 24px rgba(0,0,0,.16);
  overflow:hidden;display:flex;flex-direction:column;pointer-events:none;
  opacity:0;transform:translateY(-.2rem);transition:opacity .18s ease,transform .18s ease}
.theater:is([data-scene="1"],[data-scene="2"],[data-scene="5"])[data-phase="type"][data-suggest] .ssg{opacity:1;transform:none}
.ssg-item{display:none;align-items:center;gap:.6rem;padding:.5rem .75rem;font-size:.85rem}
.theater[data-scene="1"][data-suggest] .ssg-snap,
.theater[data-scene="2"][data-suggest="1"] .ssg-snap,
.theater[data-scene="2"][data-suggest="2"] .ssg-week,
.theater[data-scene="5"][data-suggest] .ssg-news{display:flex}
.ssg-glyph{flex:none;display:inline-flex;color:var(--text-muted)}
.ssg-glyph svg{width:1rem;height:1rem}
.ssg-main{display:flex;align-items:baseline;gap:.5rem;min-width:0;flex:1 1 auto}
.ssg-trigger{font-weight:600;white-space:nowrap;font-family:var(--font-mono);font-size:.85rem}
.ssg-dest{color:var(--text-muted);font-size:.78rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ssg-origin{flex:none;margin-inline-start:.4rem;font-size:.62rem;font-weight:600;line-height:1.5;
  padding:.02rem .42rem;border-radius:999px;white-space:nowrap;border:1px solid currentColor}
.ssg-origin--system{color:var(--text-muted)}
.ssg-origin--user{color:var(--brand)}

/* Context chips (snap / past-week / view) land during react and stay through hold. */
.stage-chips{display:flex;flex-wrap:wrap;gap:.4rem;min-height:2rem}
/* A chip not in the CURRENT scene leaves the flow entirely (display, not just opacity) — a ghost
   chip's reserved width shoved the lone "Trusted sources" chip off the start edge in the view
   scene (owner catch, 2026-07-18). The active scene's chips are laid out from scene start (type
   phase) at opacity 0, so the react-phase fade still transitions from a painted state. */
.chip{display:none;flex-wrap:wrap;align-items:center;gap:.15rem .4rem;font-size:.8rem;padding:.25rem .65rem;
  border-radius:var(--radius-pill);max-width:100%;min-width:0;
  opacity:0;transform:translateY(-.35rem);transition:opacity .3s ease,transform .3s ease}
.theater[data-scene="1"] .chip-snap,
.theater[data-scene="2"] .chip-snap,
.theater[data-scene="2"] .chip-week,
.theater[data-scene="5"] .chip-domain,
.theater[data-scene="3"] .chip-view{display:inline-flex}
.chip-snap em{overflow-wrap:anywhere}
.chip svg{width:.85em;height:.85em}
.chip-snap{background:var(--brand-soft);color:var(--brand-strong)}
.chip-snap b{font-weight:650}
.chip-snap em{font-style:normal;opacity:.88;font-size:.72rem}
.chip-week{background:var(--surface-2);color:var(--text);border:1px solid var(--border)}
/* The ad-hoc domain chip is an @-scope like the snap — same brand-soft family, same anatomy. */
.chip-domain{background:var(--brand-soft);color:var(--brand-strong)}
.chip-domain b{font-weight:650}
.chip-domain em{font-style:normal;opacity:.88;font-size:.72rem}
.chip-view{background:color-mix(in srgb,var(--brand) 15%,transparent);color:var(--brand)}
:root[data-theme="dark"] .chip-view{color:var(--brand)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .chip-view{color:var(--brand)}}
.theater[data-scene="1"]:is([data-phase="react"],[data-phase="hold"]) .chip-snap,
.theater[data-scene="2"]:is([data-phase="react"],[data-phase="hold"]) .chip-snap,
.theater[data-scene="2"]:is([data-phase="react"],[data-phase="hold"]) .chip-week,
.theater[data-scene="5"]:is([data-phase="react"],[data-phase="hold"]) .chip-domain,
.theater[data-scene="3"]:is([data-phase="react"],[data-phase="hold"]) .chip-view{opacity:1;transform:none}
.theater[data-scene="2"] .chip-week{transition-delay:.18s}

/* Mock results. Rows are skeleton bars with REAL domain lines (the honest anchor). */
.stage-body{position:relative;display:flex;flex-direction:column;gap:.55rem;flex:1}
.srow{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:.6rem;
  border:1px solid var(--border);border-radius:.6rem;padding:.55rem .7rem;background:var(--bg-elevated);
  max-height:9rem;overflow:hidden;
  transition:opacity .45s ease,transform .5s ease,filter .45s ease,max-height .5s ease,padding .5s ease,margin .5s ease,border-color .4s ease}
.sfav{width:.9rem;height:.9rem;border-radius:.28rem;border:1px solid var(--border)}
.srow-a .sfav{background:#7885be}
.srow-b .sfav{background:var(--surface-2)}
.srow-c .sfav{background:var(--brand)}
.srow-d .sfav{background:#b0bbfb}
.sbars{display:flex;flex-direction:column;gap:.32rem;min-width:0}
.st{height:.55rem;border-radius:var(--radius-pill);background:var(--border-strong)}
.st-a{width:62%}.st-b{width:78%}.st-c{width:55%}.st-d{width:70%}
.su{font-size:.75rem;color:var(--text-muted);font-family:var(--font-mono);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .35s ease}
/* Video dressing for the front-end scene: a 16/9 mini thumb (+ duration badge, .media-badge's
   grammar) and a VIDEO host line that replace the favicon dot and the research .su there — hidden
   everywhere else. Display-toggled at [data-scene="4"] UNPHASED so the morph lands at type start
   (masked by the bang overlay's fade-out; the react-time FLIP pass then measures no layout delta). */
.svid{display:none;position:relative;flex:none;width:6.5rem;aspect-ratio:16/9;align-items:center;justify-content:center;
  border:1px solid var(--border);border-radius:.45rem;background:var(--surface-2);color:var(--text-muted)}
.svid svg{width:1.1rem;height:1.1rem}
.svid-t{position:absolute;bottom:.22rem;inset-inline-end:.22rem;background:rgba(0,0,0,.78);color:#fff;
  font-size:.58rem;font-weight:600;line-height:1.3;padding:.02rem .28rem;border-radius:3px;font-family:var(--font-mono)}
.svu{display:none;font-size:.75rem;color:var(--text-muted);font-family:var(--font-mono);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.theater[data-scene="4"] .svid{display:flex}
.theater[data-scene="4"] :is(.sfav,.su,.sdate){display:none}
.theater[data-scene="4"] .svu{display:block}
.sdate{font-size:.7rem;color:var(--text-muted);border:1px solid var(--border);border-radius:var(--radius-pill);padding:.1rem .45rem;opacity:0;transition:opacity .35s ease}
.smark{width:1.15rem;height:1.15rem;display:none;align-items:center;justify-content:center}
.smark svg{width:100%;height:100%}
.smark-up{color:#2e9e5b}
.smark-block{color:var(--danger)}
.smark-pin{color:var(--brand)}
:root[data-theme="dark"] .smark-pin{color:var(--brand)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .smark-pin{color:var(--brand)}}

/* Scene 1 — @docs: non-member row leaves; members' domains warm up. */
.theater[data-scene="1"]:is([data-phase="react"],[data-phase="hold"]) .srow-b,
.theater[data-scene="2"]:is([data-phase="react"],[data-phase="hold"]) .srow-b{
  opacity:0;max-height:0;padding-block:0;margin-block:-.28rem;border-color:transparent}
.theater:is([data-scene="1"],[data-scene="2"]):is([data-phase="react"],[data-phase="hold"]) :is(.srow-a,.srow-c,.srow-d) .su{color:var(--brand-strong)}

/* Scene 2 — @docs+week: dates surface, then the too-old member drops out too (the AND landing). */
.theater[data-scene="2"]:is([data-phase="react"],[data-phase="hold"]) .sdate{opacity:1}
.theater[data-scene="2"]:is([data-phase="react"],[data-phase="hold"]) .srow-d{
  opacity:0;max-height:0;padding-block:0;margin-block:-.28rem;border-color:transparent;transition-delay:.5s}

/* Scene 3 — a view re-ranks: pin to top, lift, drop the junk (order swap is FLIPped by the JS). */
.theater[data-scene="3"] .srow-c{order:-1}
.theater[data-scene="3"] .srow-b{order:5}
.theater[data-scene="3"]:is([data-phase="react"],[data-phase="hold"]) .srow-c{border-color:color-mix(in srgb,var(--brand) 55%,var(--border))}
.theater[data-scene="3"]:is([data-phase="react"],[data-phase="hold"]) .srow-b{opacity:.35;filter:grayscale(1)}
.theater[data-scene="3"]:is([data-phase="react"],[data-phase="hold"]) .srow-c .smark-pin,
.theater[data-scene="3"]:is([data-phase="react"],[data-phase="hold"]) .srow-a .smark-up,
.theater[data-scene="3"]:is([data-phase="react"],[data-phase="hold"]) .srow-b .smark-block{display:flex;animation:smark-pop .35s ease both}
@keyframes smark-pop{from{transform:scale(.4);opacity:0}}

/* Scenes 0, 4 and 5 — overlays that slide over the results: the bang's destination, the front-end
   swap, and the ad-hoc domain's fresh result set. */
.soverlay{position:absolute;inset:0;border-radius:.75rem;border:1px solid var(--border);background:var(--surface);
  padding:.85rem;display:flex;flex-direction:column;gap:.6rem;opacity:0;transform:translateY(.75rem);
  transition:opacity .4s ease,transform .45s ease;pointer-events:none}
.theater[data-scene="0"]:is([data-phase="react"],[data-phase="hold"]) .soverlay-gh,
.theater[data-scene="5"]:is([data-phase="react"],[data-phase="hold"]) .soverlay-domain,
.theater[data-scene="4"]:is([data-phase="react"],[data-phase="hold"]) .soverlay-fe{opacity:1;transform:none}
/* The front-end scene held on ONE small card over an opaque panel — mostly dead space (owner catch,
   2026-07-18). The overlay goes translucent and the results dim behind it instead: the story reads
   "your results are still there; you clicked one, and the arrival got rewritten". */
.soverlay-fe{background:color-mix(in srgb,var(--surface) 55%,transparent)}
.theater[data-scene="4"]:is([data-phase="react"],[data-phase="hold"]) .srow{opacity:.32}
.sgh-head{display:flex;align-items:center;gap:.55rem;font-family:var(--font-mono);font-size:.8rem;color:var(--text)}
.sgh-head b{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sgh-mono{flex:none;width:1.5rem;height:1.5rem;border-radius:50%;background:var(--text);color:var(--bg);
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.68rem}
.sgh-row{display:flex;flex-direction:column;gap:.3rem;border:1px solid var(--border);border-radius:.55rem;padding:.55rem .7rem;background:var(--bg-elevated)}
.sgh-row b{height:.55rem;width:52%;border-radius:var(--radius-pill);background:var(--border-strong)}
.sgh-row i{height:.45rem;width:78%;border-radius:var(--radius-pill);background:var(--border)}
.sgh-row-dim{opacity:.55}
/* Domain-scene rows: skeleton title + REAL nytimes.com path line (the honest anchor). No redirect
   header — unlike the bang, you never left Suede. */
.sdo-row{display:flex;flex-direction:column;gap:.3rem;border:1px solid var(--border);border-radius:.55rem;padding:.55rem .7rem;background:var(--bg-elevated)}
.sdo-row b{height:.55rem;width:60%;border-radius:var(--radius-pill);background:var(--border-strong)}
.sdo-row .sdo-u{font-style:normal;font-size:.75rem;color:var(--text-muted);font-family:var(--font-mono);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sdo-row-dim{opacity:.55}
.sfe-card{position:relative;display:flex;align-items:center;gap:.7rem;border:1px solid var(--border);border-radius:.6rem;
  padding:.7rem .8rem;background:var(--bg-elevated);margin-top:auto;margin-bottom:auto}
.sfe-play{flex:none;width:2.1rem;height:2.1rem;border-radius:.5rem;background:var(--surface-2);color:var(--text);
  display:flex;align-items:center;justify-content:center}
.sfe-play svg{width:1.1rem;height:1.1rem}
.sfe-urls{position:relative;display:block;min-width:0;flex:1;min-height:1.4em}
.sfe-urls b{position:absolute;inset-inline-start:0;top:0;max-width:100%;display:inline-flex;align-items:center;gap:.4rem;
  font-family:var(--font-mono);font-size:.8rem;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  transition:opacity .4s ease,transform .4s ease}
.sfe-url-yt{color:var(--text)}
.sfe-url-fe{color:var(--brand);opacity:0;transform:translateY(.45rem)}
:root[data-theme="dark"] .sfe-url-fe{color:var(--brand)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .sfe-url-fe{color:var(--brand)}}
.sfe-url-fe svg{width:.9em;height:.9em;flex:none}
.sfe-url-fe i{font-style:normal;opacity:.7}
.theater[data-scene="4"][data-phase="hold"] .sfe-url-yt{opacity:0;transform:translateY(-.45rem)}
.theater[data-scene="4"][data-phase="hold"] .sfe-url-fe{opacity:1;transform:none}
/* The click that triggers the rewrite: a small cursor ring glides to the link and pulses. */
.sfe-cursor{position:absolute;inset-inline-end:1rem;bottom:-1.4rem;width:.85rem;height:.85rem;border:2px solid var(--text);
  border-radius:50%;opacity:0}
.theater[data-scene="4"][data-phase="react"] .sfe-cursor{animation:sfe-cursor 1s ease-out forwards}
@keyframes sfe-cursor{
  0%{opacity:0;transform:translate(0,0)}
  25%{opacity:.9}
  70%{opacity:.9;transform:translate(-38%,-2.6rem) scale(1)}
  100%{opacity:0;transform:translate(-38%,-2.6rem) scale(1.7)}}

/* ------------------------------ Brand spots ------------------------------ */
/* Brand spots on dead ends and quiet moments.
   Decorative always (aria-hidden in the component); accessory outlines (letter/lens/creases) ride
   currentColor, so coloring the wrapper with --text-muted themes them on both grounds. */
/* Brand spots — the muted mono S mark on empty states / page moments (BrandMark Mono inherits color). */
.moment-mark{inline-size:clamp(4.25rem,10vw,5.5rem);margin:0 auto 1rem;color:var(--text-muted)}
.moment-mark svg,.empty-mark svg{display:block;inline-size:100%;block-size:auto}
.empty-mark{display:block;inline-size:3rem;margin:0 auto .6rem;color:var(--text-muted)}
.empty-mark-start{margin-inline:0;inline-size:3.75rem;margin-block:1rem .6rem}
.settings-empty{text-align:center;padding:1.25rem 0 .5rem}
.settings-empty .muted{margin-block:0}
.results-empty-state{text-align:center;padding-block:1.5rem}
.results-empty-hint{color:var(--text-muted);font-size:.9375rem;margin-top:.35rem}

/* Sigil chip beside the Bangs (!) and Snaps (@) manage-page titles — the grammar's two characters
   as their pages' marks (same visual family as the landing theater's rail glyphs). Decorative. */
.sigil-chip{display:inline-flex;align-items:center;justify-content:center;width:1.5em;height:1.5em;
  margin-inline-end:.45em;vertical-align:-.28em;border-radius:.4em;background:var(--brand-soft);
  color:var(--brand-strong);font-family:var(--font-mono);font-weight:700;font-size:.72em}

/* Commons program page (visual pass, owner 2026-07-18): terms as check-cards, steps as a real
   numbered sequence (the numbers carry meaning — it IS a sequence), the form and sponsor blocks
   as panels so the page reads in rooms rather than one long scroll. Reflow-safe: rem paddings,
   grid gaps, logical insets (RTL), no fixed heights. */
.commons h2{margin-top:2.75rem}
.commons .page-head + h2{margin-top:1.5rem}
.commons-terms{list-style:none;padding:0;margin:1.1rem 0 0;display:grid;gap:.7rem}
.commons-terms li{position:relative;border:1px solid var(--border);border-radius:.8rem;background:var(--surface);
  padding:.85rem 1.1rem .85rem 2.7rem}
.commons-terms li::before{content:"✓";position:absolute;inset-inline-start:1.05rem;top:.82rem;
  color:#2e9e5b;font-weight:800}
[dir="rtl"] .commons-terms li{padding:.85rem 2.7rem .85rem 1.1rem}
.commons-steps{list-style:none;counter-reset:cstep;padding:0;margin:1.1rem 0 0;display:grid;gap:.7rem}
.commons-steps li{counter-increment:cstep;position:relative;border:1px solid var(--border);border-radius:.8rem;
  background:var(--surface);padding:.85rem 1.1rem .85rem 3.1rem}
.commons-steps li::before{content:counter(cstep);position:absolute;inset-inline-start:.95rem;top:.78rem;
  width:1.55rem;height:1.55rem;border-radius:50%;background:var(--brand-soft);color:var(--brand-strong);
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.85rem}
[dir="rtl"] .commons-steps li{padding:.85rem 3.1rem .85rem 1.1rem}
.commons-form{display:flex;flex-direction:column;gap:.35rem;max-width:36rem;margin-top:1.25rem;
  border:1px solid var(--border);border-radius:1rem;background:var(--surface);padding:1.5rem}
.commons-form label{font-weight:600;margin-top:.85rem}
.commons-form label:first-child{margin-top:0}
.commons-form input,.commons-form select,.commons-form textarea{
  font:inherit;padding:.55rem .7rem;border:1px solid var(--control-border);border-radius:.5rem;
  background:var(--bg);color:var(--text);min-width:0}
.commons-form input:focus-visible,.commons-form select:focus-visible,.commons-form textarea:focus-visible{outline:2px solid var(--brand);outline-offset:1px}
.commons-form button{margin-top:1.25rem;align-self:flex-start}
.commons-fineprint{font-size:.875rem;margin-bottom:0}
.commons-sponsor{border:1px solid var(--border);border-radius:1rem;background:var(--surface);
  padding:1.5rem;margin-top:2.75rem}
.commons-sponsor h2{margin-top:0}
.commons-sponsor .btn{margin-top:1.1rem}

/* Service-status rows — Settings › Account AND the hamburger menu's Status widget (79-status-probe.ts
   fills latency, live-updates the region, and sets data-state degraded|offline). Degraded = the
   SERVICE reported trouble (amber); offline = the PROBE couldn't reach us at all (danger) — two
   different facts, two different colors. */
.status-row{display:inline-flex;align-items:center;gap:.5rem;flex-wrap:wrap;min-width:0}
.status-dot{flex:none;width:.55rem;height:.55rem;border-radius:50%;background:#2e9e5b}
.status-row[data-state="degraded"] .status-dot{background:var(--warning, #c99700)}
.status-row[data-state="offline"] .status-dot{background:var(--danger)}
.status-detail{font-size:.875rem;font-variant-numeric:tabular-nums}
/* In the hamburger panel the row is a quiet, non-interactive line between the account actions. */
.header-menu-status{padding:0.3rem 0.55rem 0.4rem;font-size:0.8125rem}
/* Manual status re-test. Disabled = the rate-limit window: functional via the real disabled
   attribute, visual via muted ink (never opacity on the whole control) and a default cursor. */
.status-refresh{flex:none;display:inline-flex;align-items:center;justify-content:center;
    inline-size:1.6rem;block-size:1.6rem;margin-inline-start:auto;padding:0;border:0;
    border-radius:50%;background:transparent;color:var(--text-muted);cursor:pointer}
.status-refresh:hover:not(:disabled){background:color-mix(in srgb, var(--brand-strong) 14%, transparent);color:var(--text)}
.status-refresh:focus-visible{outline:2px solid var(--ring);outline-offset:1px}
.status-refresh:disabled{color:var(--text-subtle);cursor:default}
.header-menu-status .status-text{font-weight:600;flex:1 1 auto}
.header-menu-status .status-detail{font-size:0.75rem}

/* Static mode: either reduced-motion channel drops every animation and transition — the JS parks
   each scene at data-phase="hold", so what remains is a complete, legible end-state per step.
   The fit-section designer vignette follows the same contract: its conductor parks on beat 3
   (the finished design), and the acting apparatus — ghost cursor, action chips, selection
   rings/handles — disappears entirely so the parked frame is just a designed result at rest. */
@media (prefers-reduced-motion:reduce){
  .theater *,.theater{animation:none !important;transition:none !important}
  .theater-progress{display:none}
  .fitlab *,.fitlab{animation:none !important;transition:none !important}
  .fitlab-cursor,.fitlab-chip{display:none}
  .fitlab .fr-t,.fitlab .fr-head,.fitlab .fr-desc{box-shadow:none !important}
  .fitlab .fr-t::before,.fitlab .fr-t::after,.fitlab .fr-head::before,.fitlab .fr-head::after,
  .fitlab .fr-desc::before,.fitlab .fr-desc::after{opacity:0 !important}
}
:root[data-motion="reduce"] .theater,
:root[data-motion="reduce"] .theater *{animation:none !important;transition:none !important}
:root[data-motion="reduce"] .theater-progress{display:none}
:root[data-motion="reduce"] .fitlab,
:root[data-motion="reduce"] .fitlab *{animation:none !important;transition:none !important}
:root[data-motion="reduce"] .fitlab-cursor,
:root[data-motion="reduce"] .fitlab-chip{display:none}
:root[data-motion="reduce"] .fitlab .fr-t,
:root[data-motion="reduce"] .fitlab .fr-head,
:root[data-motion="reduce"] .fitlab .fr-desc{box-shadow:none !important}
:root[data-motion="reduce"] .fitlab .fr-t::before,:root[data-motion="reduce"] .fitlab .fr-t::after,
:root[data-motion="reduce"] .fitlab .fr-head::before,:root[data-motion="reduce"] .fitlab .fr-head::after,
:root[data-motion="reduce"] .fitlab .fr-desc::before,:root[data-motion="reduce"] .fitlab .fr-desc::after{opacity:0 !important}

/* --- Search Control Phase 2: view picker, !/@ suggest, redirect tag, settings sub-lists --- */
.search-view{min-width:0;max-width:11rem;flex:0 0 auto}
/* .sc-suggest* (the bang/snap autocomplete dropdown) now lives in the shared app.css — it is used by BOTH the public
   web app and the admin Search Diagnostics box. The one web-only positioning override stays below. */
/* UNIFIED OPEN SURFACE (owner, 2026-08-01 — the Google look): while the panel is open in WIDE
   mode, the pill and the panel render as ONE shape — the pill's bottom corners square off, the
   panel's top corners square, no gap, straight shared sides, one brand border around the whole,
   and a hairline divider where the input row meets the suggestions. Caret mode keeps its
   detached floating card (Google's caret-follow popup is detached too); the anchored takeover
   keeps its own full-bleed geometry. */
.search-form[data-suggest-open]:not(.is-anchored) .search-pill {
    border-start-start-radius: var(--radius-lg); border-start-end-radius: var(--radius-lg);
    border-end-start-radius: 0; border-end-end-radius: 0;
    border-block-end-color: transparent; }
.search-form[data-suggest-open]:not(.is-anchored) .search-pill:focus-within { box-shadow: none; }
.search-form:not(.is-anchored) .sc-suggest:not([data-mode="caret"]) {
    top: 100%; inset-inline: 0; max-width: none; min-width: 0;
    border: 1px solid var(--brand);
    border-block-start: 0;
    border-start-start-radius: 0; border-start-end-radius: 0;
    border-end-start-radius: var(--radius-lg); border-end-end-radius: var(--radius-lg); }
.search-form:not(.is-anchored) .sc-suggest:not([data-mode="caret"]) .sc-suggest-list {
    border-block-start: 1px solid var(--border); }
.search-form:not(.compact) .sc-suggest[data-mode="caret"]{inset-inline-end:auto;max-width:24rem}
.rank-why-redirected{opacity:.85}
.rule-row-actions{display:inline-flex;gap:.5rem;flex-wrap:wrap}
.rule-builtins{margin:.5rem 0}
.rule-builtins summary{cursor:pointer;color:var(--text-muted)}
.rule-hint{margin-top:.4rem;font-size:.9em}

/* Landing store chips — the distribution channels as uniform, NON-interactive list items (nothing
   is live yet; "Coming soon" is the honest state). Our chrome, the channels' monochrome marks;
   flex-wrap + rem basis keeps the row reflow-safe at 200% text on narrow viewports. */
/* Equal-width chips (owner, 2026-07-18): auto-fit tracks stretch identically, so "App Store" and
   "Chrome Web Store" get the same footprint; narrow viewports reflow to fewer equal columns. */
/* Page-close stores strip: quiet eyebrow above the chips; ONE muted payoff link below them
   (visitors can act today while every chip is still "Coming soon"). */
.stores-section .section-eyebrow{text-align:center}
.stores-today{display:block;text-align:center;margin:1.4rem auto 0;max-width:44ch;
  font-size:.9rem;color:var(--text-muted);text-decoration:underline;
  text-underline-offset:.2em;text-decoration-color:color-mix(in oklab, currentColor 45%, transparent)}
.stores-today:hover{color:var(--text)}
.stores{list-style:none;margin:1.5rem auto 0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(12.5rem,100%),1fr));gap:.6rem;max-width:70rem}
.store-chip{display:flex;align-items:center;gap:.6rem;padding:.65rem .85rem;min-width:0;
  border:1px solid var(--border);border-radius:.75rem;background:var(--surface)}
.store-glyph{flex:none;width:1.5rem;height:1.5rem;color:var(--text)}
.store-lines{display:flex;flex-direction:column;min-width:0;text-align:start}
.store-lines em{font-style:normal;font-size:.7rem;text-transform:uppercase;letter-spacing:.07em;color:var(--text-muted)}
/* Channel names may wrap ("Chrome Web Store" at 200% text on a phone) — reflow, never overflow. */
.store-lines strong{font-size:.95rem;color:var(--text)}
.store-chip{max-width:100%}

/* No horizontal scroll at ~200% text (WCAG 1.4.4 / 1.4.10): break over-long words in landing headings, card/section
   copy, and the FAQ so they wrap within their column instead of forcing a scrollbar. `anywhere` (not break-word) is
   required because the FAQ <summary> is a flex item — only `anywhere` reduces its min-content so the flex line can
   shrink. It only breaks a word that would otherwise overflow, so normal-width text is unaffected. */
.hero h1, .hero .lede,
.section-title, .section-sub,
.value-card h3, .value-card p,
.reach-item h3, .reach-item p,
.sc-points p, .sc-showcase-more, .sc-showcase-foot,
.faq summary, .faq p {
    overflow-wrap: anywhere;
}

/* --- Phase 5: LibRedirect privacy redirects (settings multi-select + result indicator). Reflow-safe:
   flex-wrap + min-width:0 + rem + bounded selects, so it stays readable at 200% text / a 360px viewport. --- */
.redirect-toolbar{display:flex;flex-wrap:wrap;gap:.5rem;margin-block:.5rem 1rem}
/* Category heading + its restrained "N on" count badge (scannability for the long service list). Reflow-safe. */
.redirect-group-title{display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem;min-width:0}
.redirect-group-count{font-size:.7rem;font-weight:700;letter-spacing:.02em;color:var(--text-muted);
  background:rgba(46,158,91,.16);border-radius:var(--radius-pill,999px);padding:.05rem .5rem;white-space:nowrap}
.redirect-list{list-style:none;margin:0 0 1rem;padding:0;display:flex;flex-direction:column;gap:.5rem}
.redirect-row{display:flex;flex-wrap:wrap;align-items:flex-start;gap:.5rem 1rem;justify-content:space-between;
  padding:.6rem .75rem;border:1px solid rgba(127,127,127,.2);border-radius:.6rem;min-width:0}
.redirect-row.is-on{border-color:rgba(46,158,91,.45);background:rgba(46,158,91,.05)}
.redirect-info{display:flex;flex-wrap:wrap;align-items:baseline;gap:.35rem .6rem;min-width:0;flex:1 1 13rem}
.redirect-name{font-weight:600}
.redirect-targets{font-size:.85em;color:var(--text-muted);overflow-wrap:anywhere}
.redirect-on{background:rgba(46,158,91,.18)}
.redirect-controls{display:flex;flex-wrap:wrap;align-items:flex-end;gap:.5rem;min-width:0;flex:1 1 18rem;justify-content:flex-end}
.redirect-config{display:flex;flex-wrap:wrap;align-items:flex-end;gap:.5rem;min-width:0}
.redirect-field{display:flex;flex-direction:column;gap:.2rem;min-width:0}
.redirect-field-label{font-size:.75rem;color:var(--text-muted)}
.redirect-field .field-select{max-width:13rem}
.redirect-resolved{flex-basis:100%;margin:.15rem 0 0;font-size:.85em}
.redirect-resolved code{overflow-wrap:anywhere}
/* The seamless layer (63-redirects.ts): Apply is redundant under JS (selects self-apply on change). */
.redirects-js [data-redirect-apply]{display:none}
/* Per-row + toolbar write status: quiet until shown; errors persist until the next attempt on that row. */
.redirect-status{font-size:.85rem;color:var(--success);opacity:0}
.redirect-status.redirect-status-show{opacity:1}
.redirect-status.is-error{color:var(--danger)}
@media (prefers-reduced-motion: no-preference){ .redirect-status{transition:opacity .2s} }
/* In-flight cue: the row dims its resolved line slightly while a write is outstanding. */
.redirect-row.is-saving .redirect-resolved{opacity:.55}

/* The privacy-redirects MODE cards: two large selectable options; the active one carries the brand ring. */
.redirect-modes, .redirect-coverage { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 0.9rem; margin: 0.75rem 0 1.4rem; }
.redirect-modes form, .redirect-coverage form { display: contents; }
a.redirect-mode-card { text-decoration: none; }
a.redirect-mode-card:hover { text-decoration: none; }
.redirect-customize { align-self: flex-start; margin-top: 0.4rem; }
div.redirect-mode-card[data-custom-selected] { cursor: default; }
.coverage-dialog { max-width: 30rem; border: 1px solid var(--border-strong); border-radius: var(--radius);
    background: var(--surface); color: var(--text); padding: 1.4rem 1.5rem;
    margin: auto; }   /* the global reset zeroes margins — restore the UA's dialog centering */
.coverage-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
.coverage-dialog h3 { margin: 0 0 0.4rem; }
.coverage-dialog-list { margin: 0.7rem 0 1rem; padding-inline-start: 1.2rem; max-height: 14rem; overflow-y: auto; }
.coverage-dialog-list li { margin: 0.25rem 0; }
.coverage-dialog-actions { display: flex; gap: 0.6rem; justify-content: flex-end; }
.redirect-mode-card { display: flex; flex-direction: column; gap: 0.3rem; text-align: start; padding: 0.9rem 1.1rem;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer;
    color: var(--text); font: inherit; }
.redirect-mode-card:hover { border-color: var(--border-strong); }
.redirect-mode-card.is-active { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand) inset; }
.redirect-mode-card.is-active strong::after { content: " ✓"; color: var(--brand); }
.redirect-mode-card:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.redirect-exceptions-title { font-size: 1.05rem; margin: 1.4rem 0 0.2rem; }
.redirect-exceptions-hint { margin: 0 0 0.8rem; font-size: 0.9rem; }

/* Tabular alignment (owner-requested): FIXED rem tracks so the Front-end / Instance / switch columns align ACROSS
   rows (content-sized flex scattered them). Only under .redirects-js (the no-JS layout keeps the proven flex flow
   with its visible Apply button) and only at desktop widths (em gate ⇒ collapses to stacking at 200% text / narrow).
   display:contents dissolves the form boxes into the row grid — forms stay fully functional (purely visual).
   Explicit column assignments ⇒ a hidden Instance field leaves its track EMPTY, so alignment holds. */
@media (min-width: 56em) {
    .redirects-js .redirect-row { display: grid; grid-template-columns: minmax(0,1fr) 13rem 15rem auto;
                                  grid-auto-rows: auto; gap: 0.4rem 1rem; align-items: center; }
    .redirects-js .redirect-controls, .redirects-js .redirect-config,
    .redirects-js .redirect-toggle { display: contents; }
    .redirects-js .redirect-info { grid-column: 1; grid-row: 1; }
    .redirects-js .redirect-config .redirect-field:first-of-type { grid-column: 2; grid-row: 1; }
    .redirects-js [data-redirect-instance-field] { grid-column: 3; grid-row: 1; }
    .redirects-js .redirect-row .switch { grid-column: 4; grid-row: 1; justify-self: end; }
    .redirects-js .redirect-resolved { grid-column: 1 / 4; grid-row: 2; margin: 0; }
    .redirects-js .redirect-status { grid-column: 4; grid-row: 2; justify-self: end; white-space: nowrap; }
    .redirects-js .redirect-field .field-select { width: 100%; max-width: none; }
}
/* the restrained inline "↪ via Invidious" indicator on a redirected result */
.result-redirect{display:inline-flex;align-items:center;gap:.25rem;font-size:.8rem;color:var(--text-muted)}
.result-redirect .result-redirect-ico{font-style:normal}

/* --- Search Control Phase 3c: compute-on-view rule suggestions (understated standing panel) --- */
.rule-suggestions-block{margin-block-start:1.25rem}
.rule-suggestions{list-style:none;margin:.4rem 0 0;padding:0;display:flex;flex-direction:column;gap:.4rem}
.rule-suggestion{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem 1rem;justify-content:space-between;
  padding:.5rem .75rem;border:1px solid rgba(127,127,127,.2);border-radius:.5rem;background:rgba(127,127,127,.05)}
.rule-suggestion-body{display:flex;flex-direction:column;gap:.1rem;min-width:0;flex:1 1 16rem}
.rule-suggestion-reason{font-size:.875rem}
.rule-suggestion-proposal{font-size:.8rem}
.rule-suggestion-pattern{overflow-wrap:anywhere}
.rule-suggestion-accept{margin:0;flex:0 0 auto}
.rank-why-suggested{font-style:italic;opacity:.8}

/* ============================ Documentation platform ============================
   The docs reader as a first-class product surface. It inherits the app design system VERBATIM — global tokens
   only, no local palette — so light/dark/high-contrast/forced-colors all follow the site-wide controls with zero
   docs-specific cases. Three-column shell (nav rail · article · "On this page"), plus the modern reader kit:
   sticky self-scrolling rails, a card directory with section glyphs, scroll-spy TOC, heading copy-links, prev/next
   pagination, code blocks with copy + language tabs, tinted callouts, and a ⌘K palette with live full-text
   results. Native <details> drawers take over below the em breakpoints (reflow, never suppress, at 200% text —
   WCAG 1.4.4/1.4.10). All sizing in rem; logical properties throughout (RTL-correct). Print block at the end. */

.docs-shell{
  display:grid;
  grid-template-columns:16rem minmax(0,1fr) 13.5rem;
  gap:clamp(1.5rem,3vw,3rem);
  align-items:start;
  max-width:88rem;
  margin:0 auto;
  padding:1.75rem clamp(1rem,3vw,2rem) 4.5rem;
}
.docs-main{min-width:0}   /* lets the center column shrink instead of overflowing (min-width:auto trap) */
.docs-main h1{min-width:0}

/* The docs content container is a programmatic skip target (tabindex="-1" + the "Skip to article" link). Suppress the
   focus ring when it's focused that way; interactive controls inside keep their own visible rings. */
.docs-main:focus{outline:none}

/* --- Left rail: the docs nav. Sticky + self-scrolling on wide viewports (the article list outgrows a screen);
   a "Browse the docs" <details> drawer below 48em. --- */
.docs-sidebar{
  position:sticky;top:1.5rem;min-width:0;
  max-height:calc(100vh - 3rem);overflow-y:auto;overscroll-behavior:contain;
  padding-block-end:.5rem;
  scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent;
}
.docs-nav-drawer{display:none}
.docs-nav-drawer > summary{list-style:none}
.docs-nav-drawer > summary::-webkit-details-marker{display:none}
.docs-nav-toggle{
  display:none;align-items:center;gap:.55rem;
  padding:.6rem .8rem;border:1px solid var(--border);border-radius:var(--radius);
  background:var(--surface);color:var(--text);cursor:pointer;font-weight:600;font-size:.9rem;
}
.docs-nav-toggle:focus-visible{outline:2px solid var(--ring);outline-offset:2px}
.docs-nav-toggle-ico{color:var(--text-muted);flex:none;font-size:1.05em}
.docs-drawer-chevron{margin-inline-start:auto;color:var(--text-subtle);flex:none;transition:transform .2s ease}
details[open] > summary .docs-drawer-chevron{transform:rotate(180deg)}

.docs-nav{display:flex;flex-direction:column;gap:1.35rem;font-size:.9rem}
.docs-nav-home{
  display:block;padding:.35rem .6rem;border-radius:var(--radius-sm);
  color:var(--text-muted);text-decoration:none;font-weight:600;line-height:1.45;
}
.docs-nav-home:hover{background:var(--surface-2);color:var(--text);text-decoration:none}
.docs-nav-home.active{background:var(--brand-soft);color:var(--brand-strong)}
.docs-nav-section{display:flex;flex-direction:column;gap:.35rem}
.docs-nav-section-title{
  font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--text-subtle);
  font-weight:700;margin:0;padding-inline:.6rem;
}
.docs-nav-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.1rem}
.docs-nav-link{
  display:block;padding:.32rem .6rem;border-radius:var(--radius-sm);
  color:var(--text-muted);text-decoration:none;line-height:1.45;
}
.docs-nav-link:hover{background:var(--surface-2);color:var(--text);text-decoration:none}
.docs-nav-link.active{background:var(--brand-soft);color:var(--brand-strong);font-weight:600}

/* --- Index: a search-first hero (Suede's own gesture — the docs front door IS a search box), then the section
   directory as quiet cards with glyphs. --- */
.docs-hero{
  position:relative;isolation:isolate;text-align:center;
  padding:clamp(2rem,5vw,3.25rem) 1rem clamp(1.5rem,3.5vw,2.25rem);
}
.docs-hero::before{
  content:"";position:absolute;inset:-1rem -.5rem 0;z-index:-1;border-radius:var(--radius-lg);
  background:radial-gradient(46rem 20rem at 50% -4rem,var(--brand-soft),transparent 72%);
  pointer-events:none;
}
.docs-hero h1{font-size:clamp(1.9rem,4.5vw,2.6rem);font-weight:750;letter-spacing:-.02em;line-height:1.1;margin:0 0 .6rem}
.docs-lede{color:var(--text-muted);font-size:1.05rem;line-height:1.55;max-inline-size:44ch;margin:0 auto}
.docs-empty{color:var(--text-muted);padding:2rem 0}

/* Multi-column pack, not a grid: grid rows stretch every card in a row to the tallest one, so a two-article
   section inherits a sixteen-article neighbor's height as dead space. CSS columns pack each card at its natural
   height (masonry-style, zero JS), balance column heights, and stay responsive through the same 17rem minimum
   the old minmax carried. Reading order flows down each column — the natural direction for a directory. */
.docs-card-grid{
  columns:17rem;
  column-gap:1rem;
  margin-block-start:1.5rem;
}
.docs-section-card{
  display:flex;flex-direction:column;gap:.7rem;min-width:0;
  break-inside:avoid;                             /* a card never splits across columns */
  margin:0 0 1rem;                                /* the vertical gap (column-gap covers the horizontal) */
  padding:1.15rem 1.25rem 1.25rem;
  border:1px solid var(--border);border-radius:var(--radius-lg);
  background:var(--surface);box-shadow:var(--shadow-sm);
  scroll-margin-top:1.5rem;                       /* breadcrumb #s-{section} deep links land comfortably */
  transition:border-color .15s ease;
}
.docs-section-card:hover{border-color:var(--border-strong)}
.docs-section-card-title{display:flex;align-items:center;gap:.6rem;font-size:1.02rem;font-weight:650;margin:0;min-width:0}
.docs-section-ico{
  display:grid;place-items:center;inline-size:2rem;block-size:2rem;flex:none;
  border-radius:var(--radius);background:var(--brand-soft);color:var(--brand-strong);
}
.docs-section-ico-svg{font-size:1.1rem}
.docs-section-card-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.15rem}
.docs-section-card-list a{
  display:block;padding:.28rem .5rem;margin-inline:-.5rem;border-radius:var(--radius-sm);
  color:var(--text-muted);text-decoration:none;line-height:1.45;
}
.docs-section-card-list a:hover{background:var(--surface-2);color:var(--brand-strong);text-decoration:none}

/* --- Docs search box: the product search pill, verbatim gesture (rounded field, brand focus glow, ⌘K keycap
   inside). The hero variant grows it to the front-door stature. --- */
.docs-search{display:flex;gap:.5rem;flex-wrap:wrap;margin:1.5rem 0;min-width:0}
.docs-search-field{
  flex:1 1 16rem;min-width:0;display:flex;align-items:center;gap:.5rem;
  background:var(--input-bg);border:1px solid var(--control-border);border-radius:var(--radius-pill);
  padding:.25rem .4rem .25rem .85rem;
  transition:border-color .15s ease,box-shadow .15s ease;
}
.docs-search-field:focus-within{border-color:var(--brand);box-shadow:0 0 0 3px color-mix(in srgb,var(--brand) 22%,transparent)}
.docs-search-ico{color:var(--text-subtle);flex:none}
.docs-search-input{
  flex:1;min-width:0;border:0;outline:none;background:transparent;color:var(--text);
  font:inherit;padding:.45rem 0;
}
.docs-search-input::placeholder{color:var(--text-subtle)}
.docs-search-go{flex:0 0 auto;white-space:nowrap}
.docs-search--hero{max-width:42rem;margin:1.6rem auto 0;justify-content:center}
.docs-search--hero .docs-search-input{font-size:1.05rem;padding:.6rem 0}

/* ⌘K trigger (inside the search field + at the end of the article breadcrumb): a quiet keycap. */
.docs-cmdk-trigger{
  flex:0 0 auto;display:inline-flex;align-items:center;border:0;background:none;
  padding:.3rem;cursor:pointer;border-radius:var(--radius-sm);
}
.docs-cmdk-trigger:focus-visible{outline:2px solid var(--ring);outline-offset:1px}
.docs-cmdk-kbd{
  font-family:var(--font-mono);font-size:.72rem;line-height:1;color:var(--text-muted);
  border:1px solid var(--border);border-radius:var(--radius-sm);padding:.28em .5em;background:var(--surface-2);
}
.docs-cmdk-trigger:hover .docs-cmdk-kbd{color:var(--text);border-color:var(--border-strong)}
.docs-cmdk-trigger-crumb{margin-inline-start:auto;padding:.15rem .3rem}

/* --- Docs search results page --- */
.docs-search-results>h1{font-size:clamp(1.5rem,4vw,1.9rem);font-weight:700;letter-spacing:-.015em;margin:0 0 .5rem}
.docs-search-count{color:var(--text-muted);font-size:.9rem;margin:1rem 0 1.25rem}
.docs-hit-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.6rem}
.docs-hit{
  display:flex;flex-direction:column;gap:.3rem;min-width:0;
  padding:1rem 1.15rem;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface);
}
.docs-hit-title{font-size:1.05rem;font-weight:650;color:var(--brand-strong);text-decoration:none;overflow-wrap:anywhere}
.docs-hit-title:hover{text-decoration:underline}
.docs-hit-section{
  order:-1;font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;font-weight:700;color:var(--text-subtle);
}
.docs-hit-snippet{color:var(--text-muted);margin:0;line-height:1.6;font-size:.92rem;overflow-wrap:anywhere}
.docs-hit-snippet mark,.docs-cmdk-item-snippet mark{
  background:var(--brand-soft);color:var(--brand-stronger);padding:0 .15em;border-radius:2px;font-weight:600;
}

/* --- Breadcrumb + fallback notice + article meta row --- */
.docs-breadcrumb{
  display:flex;gap:.45rem;flex-wrap:wrap;align-items:center;
  font-size:.82rem;color:var(--text-subtle);margin-block-end:1rem;
}
.docs-breadcrumb a{color:var(--text-muted);text-decoration:none}
.docs-breadcrumb a:hover{color:var(--brand-strong);text-decoration:underline}
.docs-breadcrumb-sep{color:var(--text-subtle);opacity:.7}
[dir="rtl"] .docs-breadcrumb-sep{display:inline-block;transform:scaleX(-1)}   /* › points along reading flow */
.docs-fallback-notice{margin-block:0 1.5rem}   /* reuses .legal-lang-notice styling */

.docs-article-meta{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem 1rem;
  margin:0 0 1.75rem;padding-block-end:1rem;border-block-end:1px solid var(--border);
}
.docs-updated{font-size:.85rem;color:var(--text-subtle);margin:0}
.docs-article-actions{display:flex;flex-wrap:wrap;gap:.4rem;min-width:0}
.docs-action{
  display:inline-flex;align-items:center;gap:.4em;font-size:.8rem;font-weight:500;
  padding:.32rem .7rem;border:1px solid var(--border);border-radius:var(--radius-pill);
  background:var(--surface);color:var(--text-muted);cursor:pointer;text-decoration:none;white-space:nowrap;
  transition:border-color .15s ease,color .15s ease;
}
.docs-action:hover{border-color:var(--border-strong);color:var(--text);text-decoration:none}
.docs-action:focus-visible{outline:2px solid var(--ring);outline-offset:1px}
.docs-action.is-copied{color:var(--success);border-color:var(--success)}
.docs-action-ico{flex:0 0 auto}

/* --- Article prose: the app's sans at a comfortable measure (~72ch), clear weight-led hierarchy (no counters —
   structure reads from type, not numbering). --- */
.docs-article-body{
  max-inline-size:72ch;
  font-size:1rem;line-height:1.7;color:var(--text);
  text-rendering:optimizeLegibility;
}
.docs-article-body h1{
  font-size:clamp(1.75rem,1.3rem + 1.8vw,2.35rem);font-weight:750;letter-spacing:-.02em;line-height:1.15;
  margin:0 0 .5rem;
}
.docs-article-body h2{
  font-size:1.45rem;font-weight:700;letter-spacing:-.01em;line-height:1.25;
  margin:2.5rem 0 .8rem;scroll-margin-top:2rem;
}
.docs-article-body h3{font-size:1.15rem;font-weight:650;line-height:1.3;margin:1.9rem 0 .55rem;scroll-margin-top:2rem}
.docs-article-body h4{font-size:1rem;font-weight:650;margin:1.5rem 0 .4rem;scroll-margin-top:2rem}
.docs-article-body p{line-height:1.7;margin:0 0 1.1rem;color:var(--text)}
.docs-article-body ul,.docs-article-body ol{margin:0 0 1.1rem;padding-inline-start:1.6rem;line-height:1.7}
.docs-article-body li{margin:.35rem 0}
.docs-article-body li>ul,.docs-article-body li>ol{margin:.35rem 0}
.docs-article-body a{
  color:var(--brand-strong);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px;
}
.docs-article-body a:hover{text-decoration-thickness:2px}
.docs-article-body strong{font-weight:650}
.docs-article-body blockquote{
  margin:1.5rem 0;padding:.5rem 1.1rem;border-inline-start:3px solid var(--border-strong);
  color:var(--text-muted);background:transparent;border-radius:0 var(--radius-sm) var(--radius-sm) 0;
}
.docs-article-body blockquote p:last-child{margin-bottom:0}
.docs-article-body hr{border:0;border-block-start:1px solid var(--border);margin:2.25rem 0}
.docs-article-body :not(pre)>code{
  font-family:var(--font-mono);font-size:.86em;background:var(--surface-3);
  padding:.12em .38em;border-radius:var(--radius-sm);color:var(--text);
}
.docs-article-body img{
  display:block;max-width:100%;height:auto;margin:1.5rem auto;
  border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);
}

/* Heading copy-link anchors (SSR by DocMarkdown; TS adds copy-to-clipboard). Revealed on heading hover/focus;
   faintly visible on touch (no hover to reveal them). */
.doc-anchor{
  display:inline-flex;vertical-align:baseline;margin-inline-start:.4em;
  color:var(--text-subtle);opacity:0;text-decoration:none;
  transition:opacity .12s ease,color .12s ease;
}
.docs-article-body :is(h2,h3,h4):hover .doc-anchor,.doc-anchor:focus-visible,.doc-anchor.is-copied{opacity:1}
.doc-anchor:hover{color:var(--brand-strong)}
.doc-anchor:focus-visible{outline:2px solid var(--ring);outline-offset:2px;border-radius:2px}
.doc-anchor-ico{font-size:.72em}
.doc-anchor-ico-check{display:none;color:var(--success)}
.doc-anchor.is-copied .doc-anchor-ico-link{display:none}
.doc-anchor.is-copied .doc-anchor-ico-check{display:inline}
@media (hover:none){.doc-anchor{opacity:.5}}

/* Tables: clean horizontal rules, a quiet labeled head, rounded scroll container (Markdown emits bare tables, so
   the table itself is the scroll region — no wrapper available). */
.docs-article-body table{
  border-collapse:collapse;margin:1.5rem 0;font-size:.9rem;
  display:block;max-inline-size:100%;inline-size:fit-content;overflow-x:auto;
  border:1px solid var(--border);border-radius:var(--radius);
}
.docs-article-body table caption{
  caption-side:top;text-align:start;color:var(--text-muted);padding:.5rem .8rem 0;font-size:.85rem;
}
.docs-article-body th,.docs-article-body td{
  text-align:start;padding:.55rem .8rem;border-block-start:1px solid var(--border);vertical-align:top;
}
.docs-article-body thead th{
  border-block-start:0;background:var(--surface-2);font-weight:650;font-size:.78rem;
  text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);white-space:nowrap;
}
.docs-article-body th{font-weight:650}

/* --- Fenced code blocks: a rounded panel with a header (language label + copy) and themed token colors. --- */
.doc-code{
  margin:1.5rem 0;border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;
  background:var(--surface-2);
}
.doc-code-head{
  display:flex;align-items:center;justify-content:space-between;gap:.5rem;
  padding:.45rem .6rem .45rem .95rem;background:var(--surface-3);border-block-end:1px solid var(--border);
}
.doc-code-lang{
  font-family:var(--font-mono);font-size:.7rem;text-transform:uppercase;letter-spacing:.06em;
  color:var(--text-muted);font-weight:600;
}
.doc-code-copy{
  display:inline-flex;align-items:center;gap:.3rem;font-size:.75rem;font-weight:500;
  padding:.25rem .65rem;border:1px solid var(--border);border-radius:var(--radius-pill);
  background:var(--surface);color:var(--text-muted);cursor:pointer;
  transition:color .15s ease,border-color .15s ease;
}
.doc-code-copy:hover{color:var(--text);border-color:var(--border-strong)}
.doc-code-copy:focus-visible{outline:2px solid var(--ring);outline-offset:1px}
.doc-code-copy.is-copied{color:var(--success);border-color:var(--success)}
.doc-code-pre{
  margin:0;padding:.95rem 1.1rem;overflow-x:auto;
  font-family:var(--font-mono);font-size:.85rem;line-height:1.6;color:var(--text);
  tab-size:4;-moz-tab-size:4;
}
.doc-code-pre code{font-family:inherit}

/* ColorCode token classes — themed from the design tokens so light/dark/contrast all follow. */
.doc-code-pre .keyword,.doc-code-pre .Keyword{color:var(--brand-strong);font-weight:600}
.doc-code-pre .string,.doc-code-pre .String{color:var(--success)}
.doc-code-pre .comment,.doc-code-pre .Comment{color:var(--text-subtle);font-style:italic}
.doc-code-pre .number,.doc-code-pre .Number{color:var(--warning)}
.doc-code-pre .preprocessor-keyword,.doc-code-pre .preprocessorKeyword{color:var(--brand-strong)}
.doc-code-pre .html-element-name,.doc-code-pre .htmlElementName,
.doc-code-pre .xml-attribute,.doc-code-pre .xmlAttribute,
.doc-code-pre .xml-attribute-quotes,.doc-code-pre .xmlAttributeQuotes{color:var(--brand-strong)}
.doc-code-pre .xml-attribute-value,.doc-code-pre .xmlAttributeValue{color:var(--success)}
.doc-code-pre .type,.doc-code-pre .Type{color:var(--info)}

/* --- Language tabs (curl / C# / JS): a segmented tray docked onto the code panel. --- */
.doc-tabs{margin:1.5rem 0}
.doc-tabs-strip{
  display:flex;gap:.25rem;flex-wrap:wrap;align-items:center;
  border:1px solid var(--border);border-block-end:0;
  border-start-start-radius:var(--radius-lg);border-start-end-radius:var(--radius-lg);
  background:var(--surface-3);padding:.35rem .45rem;
}
.doc-tab{
  font-size:.78rem;font-weight:550;padding:.3rem .75rem;background:none;border:0;
  border-radius:var(--radius-pill);color:var(--text-muted);cursor:pointer;
}
.doc-tab:hover{color:var(--text)}
.doc-tab.active{background:var(--surface);color:var(--brand-strong);font-weight:650;box-shadow:var(--shadow-sm)}
.doc-tab:focus-visible{outline:2px solid var(--ring);outline-offset:-2px}
.doc-tabs .doc-code{margin:0;border-start-start-radius:0;border-start-end-radius:0}

/* --- In-page TOC: the scroll-spy rail. --- */
.docs-toc{
  position:sticky;top:1.5rem;min-width:0;font-size:.85rem;
  max-height:calc(100vh - 3rem);overflow-y:auto;overscroll-behavior:contain;
  scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent;
}
.docs-toc-title{
  font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--text-subtle);
  font-weight:700;margin:0 0 .6rem;padding-inline-start:.95rem;
}
.docs-toc-list{
  list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.15rem;
  border-inline-start:1px solid var(--border);
}
.docs-toc-list a{
  display:block;color:var(--text-muted);text-decoration:none;line-height:1.45;
  padding:.15rem .5rem .15rem .85rem;
  margin-inline-start:-1px;border-inline-start:2px solid transparent;
}
.docs-toc-list a:hover{color:var(--text)}
.docs-toc-list a.active{color:var(--brand-strong);border-inline-start-color:var(--brand);font-weight:600}
.docs-toc-l3 a{padding-inline-start:1.7rem;font-size:.95em;color:var(--text-subtle)}

/* Narrow-viewport "On this page": a <details> disclosure above the article (shown only when the rail hides). */
.docs-toc-drawer{display:none;margin:0 0 1.5rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface)}
.docs-toc-drawer-btn{
  list-style:none;display:flex;align-items:center;gap:.5rem;
  padding:.6rem .8rem;cursor:pointer;font-weight:600;font-size:.9rem;color:var(--text);
}
.docs-toc-drawer-btn::-webkit-details-marker{display:none}
.docs-toc-drawer-btn:focus-visible{outline:2px solid var(--ring);outline-offset:2px}
.docs-toc-drawer .docs-toc-list{border-inline-start:0;padding:.15rem .8rem .75rem}
.docs-toc-drawer .docs-toc-list a{border-inline-start:0;margin-inline-start:0;padding:.25rem .2rem;border-radius:var(--radius-sm)}
.docs-toc-drawer .docs-toc-list a:hover{background:var(--surface-2)}
.docs-toc-drawer .docs-toc-l3 a{padding-inline-start:1rem}

/* --- Previous / next article pagination --- */
.docs-pager{display:grid;grid-template-columns:1fr 1fr;gap:.75rem;margin-block-start:2.5rem}
.docs-pager-link{
  display:flex;flex-direction:column;gap:.25rem;min-width:0;
  padding:.85rem 1rem;border:1px solid var(--border);border-radius:var(--radius-lg);
  background:var(--surface);text-decoration:none;transition:border-color .15s ease;
}
.docs-pager-link:hover{border-color:var(--brand);text-decoration:none}
.docs-pager-next{text-align:end;align-items:flex-end}
.docs-pager-eyebrow{
  display:inline-flex;align-items:center;gap:.3rem;
  font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--text-subtle);
}
.docs-pager-arrow{flex:none}
[dir="rtl"] .docs-pager-arrow{transform:scaleX(-1)}
.docs-pager-title{font-weight:600;font-size:.95rem;color:var(--text);overflow-wrap:anywhere}
.docs-pager-link:hover .docs-pager-title{color:var(--brand-strong)}
.docs-pager-spacer{min-width:0}

/* --- "Was this helpful?" --- */
.docs-feedback{
  display:flex;flex-wrap:wrap;align-items:center;gap:.6rem 1rem;
  margin-block-start:2.5rem;padding:.9rem 1.15rem;max-inline-size:72ch;
  border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface-2);
  font-size:.9rem;color:var(--text-muted);
}
.docs-feedback-actions{display:inline-flex;gap:.5rem}
.docs-feedback-btn{
  font-size:.85rem;font-weight:500;padding:.3rem .95rem;
  border:1px solid var(--border);border-radius:var(--radius-pill);
  background:var(--surface);color:var(--text-muted);cursor:pointer;
  transition:border-color .15s ease,color .15s ease;
}
.docs-feedback-btn:hover{border-color:var(--brand);color:var(--brand-strong)}
.docs-feedback-btn:focus-visible{outline:2px solid var(--ring);outline-offset:1px}
.docs-feedback-thanks{color:var(--success);font-weight:500}

/* --- "See also" --- */
.docs-related{margin-block-start:2.25rem;max-inline-size:72ch}
.docs-related-title{
  font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  color:var(--text-subtle);margin:0 0 .6rem;
}
.docs-related-list{list-style:none;margin:0;padding:0;columns:2 14rem;column-gap:2.5rem}
.docs-related-list li{break-inside:avoid;margin:0 0 .35rem}
.docs-related-list a{color:var(--brand-strong);text-decoration:none;font-size:.95rem}
.docs-related-list a:hover{text-decoration:underline}

/* --- ⌘K command palette --- */
.docs-cmdk[hidden]{display:none}
.docs-cmdk{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:flex-start;justify-content:center}
html.docs-cmdk-open{overflow:hidden}   /* lock background scroll while open */
.docs-cmdk-backdrop{position:absolute;inset:0;background:rgba(10,8,20,.5);backdrop-filter:blur(2px)}
.docs-cmdk-panel{
  position:relative;margin-block-start:12vh;inline-size:min(40rem,92vw);max-block-size:70vh;
  display:flex;flex-direction:column;overflow:hidden;
  background:var(--surface);color:var(--text);
  border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);
}
.docs-cmdk-search{display:flex;align-items:center;gap:.6rem;padding:.75rem .95rem;border-block-end:1px solid var(--border)}
.docs-cmdk-ico{flex:0 0 auto;color:var(--text-subtle)}
.docs-cmdk-input{
  flex:1 1 auto;min-width:0;border:0;background:none;color:var(--text);
  font:inherit;font-size:1.02rem;outline:none;
}
.docs-cmdk-input::placeholder{color:var(--text-subtle)}
.docs-cmdk-esc{
  flex:0 0 auto;font-family:var(--font-mono);font-size:.68rem;color:var(--text-subtle);
  border:1px solid var(--border);border-radius:var(--radius-sm);padding:.15em .45em;background:var(--surface-2);
}
.docs-cmdk-list{list-style:none;margin:0;padding:.4rem;overflow-y:auto;min-block-size:0;overscroll-behavior:contain}
.docs-cmdk-item{
  display:flex;flex-direction:column;gap:.15rem;min-width:0;
  padding:.55rem .7rem;border-radius:var(--radius);cursor:pointer;
}
.docs-cmdk-item-row{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;min-width:0}
.docs-cmdk-item-title{color:var(--text);font-weight:500;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.docs-cmdk-item-section{
  flex:0 0 auto;font-size:.66rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--text-subtle);
}
.docs-cmdk-item-snippet{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  font-size:.8rem;line-height:1.5;color:var(--text-muted);overflow-wrap:anywhere;
}
.docs-cmdk-item.active,.docs-cmdk-item[aria-selected="true"]{background:var(--brand-soft)}
.docs-cmdk-item.active .docs-cmdk-item-title{color:var(--brand-stronger)}
.docs-cmdk-empty{margin:0;padding:1rem;color:var(--text-subtle)}
.docs-cmdk-search-all{
  display:flex;align-items:baseline;gap:.4rem;inline-size:100%;text-align:start;
  padding:.65rem .95rem;border:0;border-block-start:1px solid var(--border);
  background:none;color:var(--text-muted);font:inherit;font-size:.88rem;cursor:pointer;
}
.docs-cmdk-search-all:hover{background:var(--surface-2);color:var(--text)}
.docs-cmdk-search-all:focus-visible{outline:2px solid var(--ring);outline-offset:-2px}
.docs-cmdk-search-q{color:var(--brand-strong);font-weight:600;overflow-wrap:anywhere}

/* --- Header theme toggle (global, near the contrast toggle): icon-only keycap button --- */
.theme-toggle .theme-toggle-ico{font-size:1.05em;line-height:1}

/* --- Reflow: collapse the TOC rail (→ the drawer), then the left nav (→ the drawer), as the viewport narrows
   or text scales up. Em breakpoints fire earlier under text-zoom — exactly when the columns would overflow. --- */
@media (max-width:64em){
  .docs-shell{grid-template-columns:15rem minmax(0,1fr)}
  .docs-toc{display:none}          /* the drawer + the body's own headings take over */
  .docs-toc-drawer{display:block}
}
@media (max-width:48em){
  .docs-shell{grid-template-columns:1fr;gap:1.25rem;padding-block-start:1rem}
  .docs-sidebar{position:static;max-height:none;overflow:visible;padding-block-end:0}
  .docs-nav-desktop{display:none}
  .docs-nav-drawer{display:block}
  .docs-nav-toggle{display:flex}
  .docs-nav-drawer:not([open]) > .docs-nav{display:none}
  .docs-nav-drawer[open] > .docs-nav{
    margin-block-start:.6rem;padding:.85rem;
    border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);
  }
  .docs-article-body{max-inline-size:none}
  .docs-hero{padding-block-start:1.25rem}
}
@media (max-width:34em){
  .docs-pager{grid-template-columns:1fr}
  .docs-pager-spacer{display:none}
  .docs-pager-next{text-align:start;align-items:flex-start}
}

@media (prefers-reduced-motion:reduce){
  .doc-code-copy,.docs-action,.docs-pager-link,.docs-search-field,.docs-section-card,.doc-anchor,
  .docs-drawer-chevron,.docs-feedback-btn{transition:none}
}

/* Forced colors: keep the selected/active states visible where background tints vanish. */
@media (forced-colors:active){
  .docs-nav-link.active,.docs-nav-home.active,
  .docs-cmdk-item.active,.docs-cmdk-item[aria-selected="true"]{outline:2px solid CanvasText;outline-offset:-2px}
  .doc-callout{border-inline-start-width:4px}
}

/* ============================ Callouts / admonitions ============================
   GitHub-style alerts authored as `> [!NOTE] / [!TIP] / [!WARNING] / [!IMPORTANT] / [!HISTORY]` render as a
   semantic <aside class="doc-callout doc-callout-{type}" role="note"> (see DocMarkdown.cs CalloutRenderer). Each
   type sets one accent (--callout) from a design token; the tint + border derive via color-mix, so light/dark/
   high-contrast follow automatically and RTL is correct (logical properties only). The em-sized currentColor icon
   tracks text scaling. HISTORY is Suede's own kind — background asides "from the record" — and reads as a quiet
   accent-tinted note (same shape as the others; the violet accent + muted body set it apart). */
.doc-callout{
  --callout:var(--info);
  margin:1.5rem 0;
  padding:.9rem 1.1rem;
  border:1px solid color-mix(in srgb,var(--callout) 28%,var(--border));
  border-inline-start:3px solid var(--callout);
  border-radius:var(--radius);
  background:color-mix(in srgb,var(--callout) 7%,var(--surface));
  color:var(--text);
}
.doc-callout > :first-child{margin-block-start:0}
.doc-callout > :last-child{margin-block-end:0}
.doc-callout-head{
  display:flex;align-items:center;gap:.45rem;
  margin:0 0 .4rem;
  color:var(--callout);
  font-weight:700;
}
.doc-callout-icon{flex:none;inline-size:1.1em;block-size:1.1em}   /* em-sized → scales with OS/text-zoom font */
.doc-callout-label{font-size:.72rem;text-transform:uppercase;letter-spacing:.08em;line-height:1.2}
.doc-callout-body > :first-child{margin-block-start:0}
.doc-callout-body > :last-child{margin-block-end:0}
.doc-callout-body p{line-height:1.6;margin:0 0 .6rem}
.doc-callout-body ul,.doc-callout-body ol{margin:0 0 .6rem;padding-inline-start:1.3rem}

/* Per-type accents (each maps to a design token so dark mode / contrast follow automatically). */
.doc-callout-note{--callout:var(--info)}
.doc-callout-tip{--callout:var(--success)}
.doc-callout-warning{--callout:var(--warning)}
.doc-callout-important{--callout:var(--danger)}
.doc-callout-history{--callout:var(--accent)}
.doc-callout-history .doc-callout-body{color:var(--text-muted)}

/* ===================== Community views (sharing + directory) =====================
   Public view page (/v/{token}), the directory (/views), and the Settings share/subscription controls. All
   rem-based, flex-wrap rows + min-width:0 children, so it reflows with no horizontal scroll at 200% text. */

/* --- Public view page --- */
.view-public { padding-block: clamp(1rem, 4vw, 2rem); }
.view-public-crumb { font-size: 0.9rem; margin-bottom: 0.75rem; }
.view-public-crumb a { color: var(--brand-strong); }
.view-public-head h1 { font-size: clamp(1.5rem, 4vw, 2rem); margin: 0 0 0.5rem; }
.view-public-desc { color: var(--text-muted); font-size: 1.05rem; margin: 0 0 0.75rem; max-width: 60ch; }
.view-public-meta { display: flex; flex-wrap: wrap; gap: 0.4rem 1.25rem; font-size: 0.9rem; }
.view-public-stat { display: inline-flex; gap: 0.3rem; min-width: 0; }
.view-public-actions {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem;
    margin: 1.25rem 0 0.5rem;
}
.view-public-actions form { margin: 0; }
.view-public-actions .alert { flex: 1 1 100%; }
.view-public-hint { font-size: 0.85rem; margin: 0 0 1.5rem; max-width: 60ch; }
.view-public-rules { margin-top: 1.5rem; border-block-start: 1px solid var(--border); padding-block-start: 1.5rem; }
.view-public-rules h2 { font-size: 1.2rem; margin: 0 0 0.25rem; }
.view-public-signin { margin: 0; }

/* --- Inspectable rules table (shared: public page + admin) --- */
.view-rules { display: flex; flex-direction: column; gap: 1.25rem; margin-top: 1rem; }
.view-rules-group-title {
    display: flex; align-items: center; gap: 0.5rem; font-size: 0.95rem; font-weight: 600;
    margin: 0 0 0.5rem; color: var(--text);
}
.view-rules-count {
    font-size: 0.75rem; font-weight: 600; color: var(--text-muted);
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-pill);
    padding: 0.05rem 0.45rem;
}
.view-rules-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.view-rules-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem; min-width: 0; }
.view-rules-pattern {
    font-family: var(--font-mono); font-size: 0.9rem;
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
    padding: 0.1rem 0.4rem; word-break: break-word; min-width: 0;
}
.view-rules-arrow { color: var(--text-muted); }
.view-rules-match { font-size: 0.8rem; }
.view-rules-scope { font-size: 0.7rem; }

/* --- Directory (/views) --- */
.view-directory { padding-block: clamp(1rem, 4vw, 2rem); }
.view-directory-search {
    display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 1.25rem 0 1.5rem; max-width: 36rem;
}
.view-directory-search .field-input { flex: 1 1 12rem; min-width: 0; }
.view-directory-grid {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 1rem;
}
.view-directory-card { display: flex; flex-direction: column; gap: 0.6rem; min-width: 0; }
.view-directory-card-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; min-width: 0; }
.view-directory-card-title { font-size: 1.1rem; margin: 0; min-width: 0; }
.view-directory-card-title a { color: var(--text); }
.view-directory-card-title a:hover { color: var(--brand-strong); }
.view-directory-card-desc { color: var(--text-muted); font-size: 0.9rem; margin: 0; flex: 1 1 auto; }
.view-directory-card-foot {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: auto;
}
.view-directory-card-foot form { margin: 0; }
.view-directory-subs { font-size: 0.85rem; margin-inline-end: auto; }
.view-directory-signin { margin-top: 1.5rem; font-size: 0.9rem; }
.view-directory-signin a { color: var(--brand-strong); }

/* ==================== Search Control: Adjust slider · modal · rules page · view switches ==================== */

/* --- Adjust slider (RankSlider) — replaces the old per-result action buttons; reused on the rules-page editor --- */
.rank-slider-wrap { padding: 0.15rem 0.1rem 0; }
.rank-slider-form { display: flex; flex-direction: column; gap: 0.4rem; min-width: 0; }
.rank-slider-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.25rem 0.5rem; min-width: 0; }
.rank-slider-caption { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); }
.rank-slider-value { font-size: 0.8rem; font-weight: 600; color: var(--text); }
.rank-slider { inline-size: 100%; accent-color: var(--brand); margin: 0; min-width: 0; }
.rank-slider-apply { align-self: flex-start; }
/* Quick actions — five equal segments; pressed = the current selection band. Never wraps (segmented rule). */
.rank-quick {
    display: flex; gap: 2px; inline-size: 100%; background: var(--surface-2); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 2px;
}
.rank-quick-btn {
    flex: 1 1 0; min-inline-size: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    font: inherit; font-size: 0.72rem; padding: 0.35rem 0.15rem; min-block-size: 2rem; border: 0;
    border-radius: calc(var(--radius) - 2px); background: transparent; color: var(--text-muted); cursor: pointer;
}
.rank-quick-btn:hover { background: var(--surface); color: var(--text); }
.rank-quick-btn:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: -2px; }
.rank-quick-btn[aria-pressed="true"] { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: var(--shadow-sm, 0 1px 2px rgba(16,12,40,.12)); }
.rank-quick-block[aria-pressed="true"] { color: var(--danger, #b91c1c); }
.rank-quick-pin[aria-pressed="true"] { color: var(--brand-strong); }
@media (forced-colors: active) { .rank-quick-btn[aria-pressed="true"] { border: 1px solid; } }
/* The Advanced expander holding the fine slider. */
.rank-advanced-summary { font-size: 0.72rem; color: var(--text-muted); cursor: pointer; padding: 0.15rem 0; }
.rank-advanced[open] > .rank-advanced-summary { color: var(--text); }
.rank-advanced .rank-slider { margin-block-start: 0.25rem; }
/* The nameless implicit-submission default — clipped, NOT display:none (it must stay the default button). */
.rank-slider-default { position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); }
/* The explicit Mute/Unmute row (its own sibling form inside the Adjust popup). */
.rank-mute-form { display: contents; }
.rank-mute { font-size: 0.8rem; color: var(--text-muted); }
.rank-mute.is-on { color: var(--brand-strong); font-weight: 600; }

/* --- Reusable modal (Modal.razor) — cloned from .docs-cmdk --- */
.modal[hidden] { display: none; }
.modal { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: flex-start; justify-content: center; }
html.modal-open { overflow: hidden; }   /* lock background scroll while open */
.modal-backdrop { position: absolute; inset: 0; background: rgba(15, 12, 8, 0.45); }
.modal-panel {
    position: relative; margin-block-start: 10vh; inline-size: min(34rem, 92vw); max-block-size: 84vh;
    display: flex; flex-direction: column; overflow: hidden;
    background: var(--surface); color: var(--text);
    border: 1px solid var(--border-strong); border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; padding: 0.8rem 1rem; border-block-end: 1px solid var(--border); }
.modal-title { margin: 0; font-size: 1.05rem; }
.modal-close { flex: 0 0 auto; inline-size:2.75rem; block-size:2.75rem; border: 0; background: none; color: var(--text-muted); font-size: 1.1rem; line-height: 1; cursor: pointer; padding: 0; border-radius: var(--radius-sm); display:inline-flex; align-items:center; justify-content:center; }
.modal-close:hover { color: var(--text); background: var(--surface-2); }
.modal-close:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
.modal-body { padding: 1rem; overflow-y: auto; min-block-size: 0; }
.modal-error { margin: 0 0 0.75rem; color: var(--danger, #b42318); font-size: 0.85rem; }
.rule-add .modal-error { flex-basis: 100%; }

/* --- Search-Control sub-pages (rules list / add / view add) --- */
.sc-page { padding-block-end: 3rem; }
.sc-back { display: inline-block; font-size: 0.85rem; color: var(--text-muted); text-decoration: none; margin-block-end: 0.25rem; }
.sc-back::before { content: "← "; }
[dir="rtl"] .sc-back::before { content: "→ "; }   /* back points the other way in RTL */
.sc-back:hover { color: var(--text); }
.sc-rules-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; margin: 1rem 0; }
.sc-rules-sort { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; font-size: 0.8125rem; }
.sc-sort-link { color: var(--text-muted); text-decoration: none; padding: 0.15rem 0.55rem; border-radius: var(--radius-pill); border: 1px solid transparent; cursor: pointer; }
.sc-sort-link:hover { color: var(--text); }
.sc-sort-link.is-active { color: var(--brand-strong); border-color: var(--border); background: var(--surface-2); }
/* "Your rules" — icon-led cards. One row per rule; the leading action icon + its colour is the at-a-glance
   signature (block = red ⊘, lower = amber ↓, raise = green ↑, pin = brand ⤒), the pattern is the headline,
   match-type/scope sit muted beneath. Flex row reflows on its own (no grid breakpoint needed). */
.sc-rules { display: flex; flex-direction: column; gap: 0.4rem; }
.sc-rule-row { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
    transition: border-color 0.15s ease; }
.sc-rule-row:hover { border-color: var(--border-strong); }
.sc-rule-row[open] { border-color: var(--brand); }
.sc-rule-summary { display: flex; align-items: center; gap: 0.85rem; padding: 0.65rem 0.8rem; cursor: pointer; list-style: none; }
.sc-rule-summary::-webkit-details-marker { display: none; }
.sc-rule-icon { flex: none; display: grid; place-items: center; inline-size: 2.1rem; block-size: 2.1rem; border-radius: 50%; }
.sc-rule-icon svg { inline-size: 1.05rem; block-size: 1.05rem; }
.sc-rule-main { min-inline-size: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: 0.1rem; }
.sc-rule-pattern { font-weight: 600; font-size: 0.92rem; overflow-wrap: anywhere; line-height: 1.25; }
.sc-rule-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; font-size: 0.75rem; color: var(--text-muted); }
.sc-rule-act { font-weight: 600; }
.sc-rule-sep { opacity: 0.45; }
/* view-scoped rule: the owning view named in the summary meta, accent-tinted so it reads as a scope
   condition ("only while this view is active"), not another attribute */
.sc-rule-viewchip { color: var(--brand-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-inline-size: 14rem; }
.sc-rule-weight { flex: none; font-variant-numeric: tabular-nums; font-weight: 700; font-size: 0.8rem; padding: 0.08rem 0.5rem; border-radius: var(--radius-pill); }
.sc-rule-chevron { flex: none; display: grid; place-items: center; color: var(--text-muted); transition: transform 0.2s ease; }
.sc-rule-chevron svg { inline-size: 1.05rem; block-size: 1.05rem; }
.sc-rule-row[open] .sc-rule-chevron { transform: rotate(90deg); }
/* per-action colour (matches the result-kebab chips; tokens are theme-aware) */
.sc-rule-icon-block { background: var(--danger-soft); color: var(--danger); }
.sc-rule-icon-lower { background: var(--warning-soft); color: var(--warning); }
.sc-rule-icon-raise { background: var(--success-soft); color: var(--success); }
.sc-rule-icon-pin   { background: var(--brand-soft); color: var(--brand-strong); }
.sc-rule-icon-normal { background: var(--surface-2); color: var(--text-muted); }
.sc-rule-act-block { color: var(--danger); }
.sc-rule-act-lower { color: var(--warning); }
.sc-rule-act-raise { color: var(--success); }
.sc-rule-act-pin   { color: var(--brand-strong); }
.sc-rule-weight-lower { background: var(--warning-soft); color: var(--warning); }
.sc-rule-weight-raise { background: var(--success-soft); color: var(--success); }
/* expanded editor (the Adjust slider + delete) */
.sc-rule-edit { padding: 0.65rem 0.8rem 0.8rem; border-block-start: 1px solid var(--border);
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem 1.25rem; }
.sc-rule-edit .rank-slider-form { flex: 1 1 16rem; max-inline-size: 24rem; border: 1px solid var(--border); border-radius: var(--radius); padding: 0.5rem 0.65rem; }
.sc-rule-fromview { flex: 1 1 16rem; margin: 0; }
.sc-rule-delete { margin: 0; }

/* --- Settings › Search Control: rules-count summary + view switches + always-shown built-ins --- */
.rule-summary-counts { margin: 0 0 0.5rem; }
/* Colour-coded count chips (the pane "Your rules" summary) — icon + count + label, tinted per action via the
   shared .sc-rule-icon-{action} tokens. */
.rank-stat-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.25rem 0 0.7rem; }
.rank-stat { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.28rem 0.65rem;
    border-radius: var(--radius-pill); font-size: 0.82rem; font-weight: 500; }
.rank-stat svg { inline-size: 0.95rem; block-size: 0.95rem; flex: none; }
.rank-stat strong { font-weight: 700; font-variant-numeric: tabular-nums; }
.rule-manage-row { margin: 0.5rem 0 0; }

/* --- Settings › Views: import dropzone + one-form export (io-*) ---------------------------------
   The file input COVERS the dropzone (opacity 0, inset 0): click-anywhere browses, native drag-drop
   lands on the input with no JS; 67-views-io.ts only decorates (drag-over, filename, arming). The
   whole import/export block nests INSIDE the Views row behind a left rail — the "belongs to Views"
   grouping the flat run can't communicate on its own. */
.io-subsection { margin-block-start: 1.2rem; padding-inline-start: 1rem;
    border-inline-start: 2px solid var(--border-strong);
    display: flex; flex-direction: column; gap: 1.1rem; }
.io-subsection .rule-group-title { margin: 0; }
.io-import { margin: 0; }
.io-dropzone { position: relative; display: flex; flex-direction: column; align-items: center; gap: 0.2rem;
    padding: 1rem 1rem 1.1rem; border: 1.5px dashed var(--border-strong);
    border-radius: var(--radius); text-align: center; cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease; }
.io-dropzone.is-dragover, .io-dropzone:hover { border-color: var(--brand); background: var(--brand-soft); }
.io-dropzone:focus-within { outline: 2px solid var(--brand); outline-offset: 2px; }
.io-dropzone .io-file { position: absolute; inset: 0; opacity: 0; cursor: pointer; inline-size: 100%; block-size: 100%; }
.io-drop-glyph { inline-size: 1.5rem; block-size: 1.5rem; color: var(--text-muted); }
.io-drop-title { font-weight: 600; font-size: 0.9rem; }
.io-drop-hint { font-size: 0.8rem; max-inline-size: 34rem; }
.io-drop-file { font-size: 0.82rem; font-weight: 600; font-variant-numeric: tabular-nums; word-break: break-all;
    padding: 0.15rem 0.6rem; border-radius: var(--radius-pill); background: var(--brand-soft); }
.io-dropzone.has-file { border-style: solid; }
.io-import-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-block-start: 0.55rem; }
.io-export .field-label { display: block; margin-block-end: 0.3rem; }
.io-export-row { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.io-export-row .field-select { min-inline-size: 0; flex: 0 1 16rem; }

.view-row-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; min-width: 0; }
.view-row-head .rule-pattern { flex: 1 1 auto; }
.view-row-head .rule-row-actions { margin-inline-start: auto; }
.view-switch-form { margin: 0; flex: 0 0 auto; }
.view-builtins { margin-block-start: 1rem; }
.view-bulk { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.35rem 0 0.6rem; }
.view-mode-help { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.8rem; flex-basis: 100%; }

/* --- Settings: per-view share controls + subscriptions --- */
.rule-row-view { flex-direction: column; align-items: stretch; }
.view-share {
    flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem;
    margin-top: 0.4rem; padding-top: 0.4rem; border-block-start: 1px dashed var(--border);
}
.view-share-link { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.3rem; min-width: 0; font-size: 0.85rem; }
.view-share-url { word-break: break-all; min-width: 0; }
.view-share-url a { color: var(--brand-strong); }
.view-share-actions { display: inline-flex; flex-wrap: wrap; gap: 0.5rem; }

/* ============================ Print ============================
   A clean, chrome-free article on paper: hide navigation/controls, black on white, expand external link URLs,
   and keep code/tables/callouts from splitting badly. (The browser's own header/footer supplies page numbers.) */
@media print{
  @page{margin:16mm}

  /* App chrome + interactive-only bits */
  .app-bar,.app-header,.header-nav,.skip-link,
  .docs-sidebar,.docs-toc,.docs-toc-drawer,.docs-search,.doc-code-copy,.doc-tabs-strip,.docs-breadcrumb,
  .doc-anchor,.docs-article-actions,.docs-feedback,.docs-pager,.docs-cmdk,.docs-cmdk-trigger{display:none !important}

  html,body{background:#fff !important}
  .docs-shell{display:block;max-width:none;margin:0;padding:0;background:#fff !important;color:#000 !important}
  .docs-main,.docs-article-body{max-inline-size:none}
  .docs-article-body{font-size:11pt;line-height:1.55}
  .docs-article-body h1{font-size:20pt}
  .docs-article-meta{display:block;border-block-end:1pt solid #000}

  /* Black on white, no tints */
  body,.docs-article-body,.docs-article-body p,.docs-article-body li,
  .docs-article-body h1,.docs-article-body h2,.docs-article-body h3,.docs-article-body h4{color:#000 !important}
  .doc-code,.doc-code-pre,.doc-code-head,.docs-article-body :not(pre)>code,
  .docs-article-body th,.docs-article-body blockquote,
  .doc-callout,.doc-callout-head{background:#fff !important;color:#000 !important}
  .doc-code,.doc-code-head,.doc-code-pre,.docs-article-body table,
  .docs-article-body th,.docs-article-body td,.docs-article-body img{border-color:#999 !important}
  .doc-callout{border:1px solid #999 !important;border-inline-start:3px solid #000 !important}
  .docs-article-body a{color:#000 !important;text-decoration:underline}
  .docs-article-body blockquote{border-inline-start:2pt solid #000 !important}
  .doc-code-pre .keyword,.doc-code-pre .string,.doc-code-pre .comment,.doc-code-pre .number,
  .doc-code-pre .type,.doc-code-pre .preprocessor-keyword{color:#000 !important;font-style:normal}

  /* Language tab groups: print EVERY panel (each is labeled by its own header), not just the active one. */
  .doc-tabs [data-doc-panel][hidden]{display:block !important}
  .doc-tabs .doc-code{margin:0 0 .75rem;border-radius:0}

  /* Expand hyperlink targets so a printed page keeps the URLs (skip in-page anchors + relative links) */
  .docs-article-body a[href^="http"]::after{content:" (" attr(href) ")";font-size:.85em;color:#000;word-break:break-all}

  /* Don't split code / tables / callouts / figures awkwardly; keep headings with their text. */
  .doc-code,.doc-tabs,.docs-article-body pre,.docs-article-body table,.docs-article-body blockquote,
  .docs-article-body img,.doc-callout{break-inside:avoid;page-break-inside:avoid}
  .docs-article-body h1,.docs-article-body h2,.docs-article-body h3,.docs-article-body h4,
  .doc-code-head{break-after:avoid;page-break-after:avoid}
  .docs-article-body p,.docs-article-body li{orphans:3;widows:3}
  .doc-code-pre{white-space:pre-wrap;word-break:break-word}   /* wrap long lines so nothing is clipped on paper */
}

/* ── Advanced Search (/advanced) ───────────────────────────────────────────────────────────────────────────────
   A composable boolean query builder. Two columns on desktop (build + sticky filter rail); the JS canvas (38-
   advanced-search.ts) replaces the flat word rows with a nestable AND/OR/NOT tree and drives the live preview. */
.adv { max-width: 64rem; margin: 0 auto; padding: 1.5rem 1rem 4rem; }
.adv-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.adv-head h1 { margin: 0 0 .25rem; font-size: clamp(1.4rem, 1rem + 1.6vw, 1.75rem); }
.adv-sub { margin: 0; font-size: .9rem; max-width: 44rem; }
.adv-x { inline-size:2.75rem; block-size:2.75rem; flex:none; display:inline-flex; align-items:center; justify-content:center; font-size: 1.9rem; line-height: 1; color: var(--text-subtle); text-decoration: none; padding: 0; border-radius: var(--radius-sm); }
.adv-x:hover { color: var(--text); background: var(--bg-elevated); }

.adv-cols { display: grid; grid-template-columns: 1fr; gap: 1.25rem; }
@media (min-width: 56em) { .adv-cols { grid-template-columns: 1.45fr 1fr; align-items: start; } }

.adv-card { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); padding: 1.1rem 1.2rem; margin: 0 0 1.1rem; }
.adv-build { min-width: 0; }
.adv-build .adv-card:last-child { margin-bottom: 0; }
.adv-card > legend, .adv-rail-title { display: block; width: 100%; font-weight: 650; font-size: .72rem; line-height:1.2; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); padding: 0; margin:0 0 .9rem; }
@media (min-width: 56em) { .adv-rail { position: sticky; top: calc(var(--header-height) + 1rem); } }

.adv-row { display: flex; flex-direction: column; gap: .35rem; min-width: 0; margin-bottom: .9rem; }
.adv-row:last-child { margin-bottom: 0; }
.adv-row > label, .adv-row-label { font-size: .85rem; font-weight: 550; color: var(--text); }
.adv-hint { margin: .05rem 0 0; font-size: .78rem; color: var(--text-subtle); }
.adv-grid2 { display: grid; grid-template-columns: 1fr; gap: 0 1rem; }
@media (min-width: 30em) { .adv-grid2 { grid-template-columns: 1fr 1fr; } .adv-grid2 .adv-row:last-child { grid-column: 1 / -1; } }

.adv-chips { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .15rem; }
.adv-chip { min-block-size: 2rem; font: inherit; font-size: .78rem; padding: .2rem .6rem; border: 1px solid var(--control-border); border-radius: var(--radius-pill); background: var(--bg); color: var(--text-muted); cursor: pointer; }
.adv-chip:hover { border-color: var(--brand); color: var(--brand); }
.adv-chip.is-on { background: var(--brand-soft); border-color: var(--brand); color: var(--brand-strong); }

.adv-daterow { display: flex; flex-wrap: wrap; gap: .6rem; }
.adv-date { display: flex; flex-direction: column; gap: .2rem; flex: 1 1 8rem; min-width: 0; font-size: .78rem; color: var(--text-subtle); }

.adv-toggles { display: flex; flex-direction: column; gap: .6rem; }
.adv-check { display: flex; align-items: center; gap: .55rem; font-size: .88rem; cursor: pointer; }
.adv-check input { width: 1.05rem; height: 1.05rem; accent-color: var(--brand); flex: none; }

.adv-preview { display: flex; align-items: baseline; gap: .7rem; flex-wrap: wrap; margin-top: 1.25rem; padding: .8rem 1rem; border: 1px solid var(--border); border-left: 3px solid var(--brand); border-radius: var(--radius); background: var(--bg-elevated); }
.adv-preview-label { font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-subtle); white-space: nowrap; }
.adv-preview-q { font-family: var(--font-mono); font-size: .9rem; line-height: 1.5; color: var(--text); word-break: break-word; min-width: 0; }
.adv-preview-q:empty::before { content: attr(data-empty); color: var(--text-subtle); }

.adv-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .75rem; margin-top: 1.5rem; }
.adv-actions .btn { min-width: 8rem; justify-content: center; }

/* The boolean canvas (mounted by JS; flat rows hidden via [data-adv-words][hidden]). */
.adv-canvas[hidden], .adv-words[hidden] { display: none; }
.adv-canvas { display: flex; flex-direction: column; gap: .6rem; }
.adv-group { border: 1px solid var(--border); border-radius: var(--radius); padding: .65rem .7rem; background: var(--bg); }
.adv-group .adv-group { background: var(--bg-elevated); }
.adv-group-head { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin-bottom: .55rem; }
.adv-conn { display: inline-flex; border: 1px solid var(--control-border); border-radius: var(--radius-pill); overflow: hidden; flex: none; }
.adv-conn button { min-block-size: 2rem; font: inherit; font-size: .76rem; font-weight: 600; padding: .18rem .65rem; border: 0; background: transparent; color: var(--text-muted); cursor: pointer; }
.adv-conn button.is-on { background: var(--brand); color: var(--brand-contrast); }
.adv-spacer { flex: 1 1 auto; }
.adv-iconbtn { min-inline-size:2rem; min-block-size:2rem; font: inherit; font-size: .76rem; padding: .18rem .5rem; border: 1px solid var(--control-border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text-muted); cursor: pointer; white-space: nowrap; }
.adv-iconbtn:hover { border-color: var(--brand); color: var(--brand); }
.adv-iconbtn.adv-rm { padding: .18rem .45rem; line-height: 1; }
.adv-nodes { display: flex; flex-direction: column; gap: .45rem; }
.adv-node { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; min-width: 0; }
.adv-cond { display: flex; align-items: center; gap: .4rem; flex: 1 1 16rem; min-width: 0; }
.adv-cond .field-input { flex: 1 1 8rem; width: auto; min-width: 0; }
.adv-cond .field-select { flex: 0 0 auto; width: auto; min-width: 0; font-size: .82rem; }
.adv-not { display: inline-flex; align-items: center; gap: .25rem; font-size: .76rem; color: var(--text-subtle); white-space: nowrap; }
.adv-canvas-hint { font-size: .78rem; color: var(--text-subtle); margin: .1rem 0 0; }

/* Global safe search: a per-type safe-search toggle locked ON by the master toggle (General pane). The server
   renders it disabled; .is-disabled (set live by 65-global-safe-search.ts) dims it to read as locked. */
.toggle.is-disabled { opacity: .55; }
.toggle.is-disabled, .toggle input:disabled { cursor: not-allowed; }
.settings-group-note { margin: .5rem 0 0; font-size: .82rem; }

/* ── Search-Control dedicated pages: icon-led cards (bangs/snaps/redirects/views) ──────────────────────────────── */
.sc-cards { display: flex; flex-direction: column; gap: .5rem; margin: 0 0 1.5rem; }
.sc-card { display: flex; align-items: center; gap: .75rem; padding: .7rem .9rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.sc-card.sc-card-off {
  background:var(--surface-2);border-color:var(--control-border);border-inline-start-width:.25rem;
}
.sc-card.sc-card-off .sc-card-icon { background:var(--surface);color:var(--text-muted); }
.sc-card-icon { flex: none; width: 2rem; height: 2rem; display: grid; place-items: center; border-radius: var(--radius-sm); }
.sc-card-icon svg { width: 1.2rem; height: 1.2rem; }
.sc-card-icon-bang { background: var(--brand-soft); color: var(--brand); }
.sc-card-icon-snap { background: var(--info-soft); color: var(--info); }
.sc-card-icon-redirect { background: var(--warning-soft); color: var(--warning); }
.sc-card-icon-view { background: var(--success-soft); color: var(--success); }
/* View cards carry a mode class too — match the icon stroke to its tinted box (boost=green, restrict=brand, filter=amber). */
.sc-card-icon-view.sc-rule-icon-raise { background: var(--success-soft); color: var(--success); }
.sc-card-icon-view.sc-rule-icon-pin   { background: var(--brand-soft); color: var(--brand-strong); }
.sc-card-icon-view.sc-rule-icon-lower { background: var(--warning-soft); color: var(--warning); }
.sc-card-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.sc-card-title { font-weight: 600; font-family: var(--font-mono); word-break: break-word; }
.sc-card-sub { font-size: .82rem; color: var(--text-muted); word-break: break-word; }
.sc-card-actions { flex: none; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; justify-content: flex-end; }
.sc-add-title { font-size: 1.05rem; margin: 1.75rem 0 .85rem; }
.sc-form { display: flex; flex-direction: column; gap: 1rem; max-width: 34rem; }
.sc-form .field { display: flex; flex-direction: column; gap: .3rem; }
.sc-form .field-label { font-weight: 550; font-size: .9rem; }
.sc-form .field-hint { margin: 0; font-size: .8rem; color: var(--text-subtle); }
.sc-builtins { margin-top: 1.75rem; }

/* ── Account › Email address (/account/settings/email) + the Account email-row Change button ─────────────────────── */
.email-page { max-width: 40rem; }
.account-email-value { display: flex; align-items: center; gap: 0.55rem; flex-wrap: wrap; justify-content: flex-end; }
.account-email-addr { word-break: break-all; min-width: 0; }
.account-email-change { flex: none; }
.email-badge-warn { background: var(--warning-soft); color: var(--warning); }

.email-current { display: flex; flex-direction: column; gap: 0.35rem; margin: 1.25rem 0;
    border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); padding: 1rem 1.2rem; }
.email-current-label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); }
.email-current-value { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; min-width: 0; }
.email-current-addr { font-size: 1.1rem; font-weight: 600; word-break: break-all; min-width: 0; }

.email-form { display: flex; flex-direction: column; gap: 1.15rem; margin-top: 0.4rem;
    border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); padding: 1.4rem; }
.email-form .field { display: flex; flex-direction: column; gap: 0.4rem; }
.email-form .field-label { font-weight: 600; font-size: 0.9rem; }
.email-form .field-hint { font-size: 0.8rem; color: var(--text-subtle); line-height: 1.45; }
.email-form-submit { align-self: flex-start; min-width: 12rem; justify-content: center; margin-top: 0.2rem; }

.email-pending { display: flex; gap: 0.9rem; margin-top: 0.4rem;
    border: 1px solid color-mix(in srgb, var(--warning) 40%, var(--border)); border-radius: var(--radius-lg);
    background: var(--warning-soft); padding: 1.3rem; }
.email-pending-icon { flex: none; color: var(--warning); margin-top: 0.1rem; }
.email-pending-body { display: flex; flex-direction: column; gap: 0.45rem; min-width: 0; }
.email-pending-title { margin: 0; font-size: 1.05rem; }
.email-pending-text { margin: 0; color: var(--text); line-height: 1.5; }
.email-pending-addr { word-break: break-all; }
.email-pending-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.35rem; }
.email-pending-actions form { margin: 0; }
@media (max-width: 30em) { .email-form-submit { width: 100%; align-self: stretch; } .account-email-value { justify-content: flex-start; } }

/* ===== Result Designer (WYSIWYG result-template editor) ===== */
.rd { margin-top: 0.5rem; }
.rd-nojs { padding: 1.5rem; text-align: center; }
.rd-nojs .btn { margin-inline-start: 0.6rem; }

/* Result Designer's native form editor. The visual canvas is an enhancement over this same bounded model;
   six lines × four slots mirrors ResultTemplate's server caps exactly. Every row and action reflows at 200% text. */
.rd-form-page { max-width: 70rem; padding-block: 2rem 4rem; }
.rd-form-page .page-head { margin-bottom: 1.5rem; }
.rd-form-preview { margin-bottom: 1.25rem; overflow: hidden; }
.rd-form-preview h2 { font-size: 1.05rem; margin-bottom: 1rem; }
.rd-form { display: grid; gap: 1.5rem; }
.rd-form-fieldset { min-width: 0; padding: 0; border: 0; }
.rd-form-fieldset > legend { width: 100%; font-size: 1.05rem; font-weight: 700; margin-bottom: 0.25rem; }
.rd-form-line { display: grid; grid-template-columns: minmax(4.5rem, auto) minmax(0, 1fr); gap: 0.75rem; align-items: start; padding-block: 0.45rem; }
.rd-form-line + .rd-form-line { border-top: 1px solid var(--border); }
.rd-form-slots { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.5rem; min-width: 0; }
.rd-form-slots .field-select { width: 100%; min-width: 0; }
.rd-form-group-favicon { max-width: 24rem; }
.rd-form-style-list { display: grid; gap: 0.5rem; margin-top: 0.75rem; }
.rd-form-style { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.rd-form-style > summary { cursor: pointer; padding: 0.75rem 0.9rem; font-weight: 650; }
.rd-form-style-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr)); gap: 0.9rem; padding: 0.25rem 0.9rem 1rem; align-items: end; }
.rd-form-style-fields > label:not(.toggle) { display: grid; gap: 0.3rem; min-width: 0; }
.rd-form-style-fields .field-select { width: 100%; min-width: 0; }
.rd-form-check { min-height: 2.75rem; align-self: end; }
.rd-form-actions { display: flex; flex-wrap: wrap; align-items: end; gap: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--border); }
.rd-form-name { display: grid; gap: 0.3rem; flex: 1 1 14rem; max-width: 24rem; }
.rd-native-action { position: relative; }
.rd-native-action > summary { list-style: none; }
.rd-native-action > summary::-webkit-details-marker { display: none; }
.rd-native-action[open] { flex-basis: 100%; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.rd-native-action[open] > summary { margin-bottom: 0.65rem; }
.rd-native-action form { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: end; }
.rd-native-action label { display: grid; gap: 0.3rem; flex: 1 1 12rem; }
.rd-native-danger[open] { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.rd-native-danger p { margin-bottom: 0.65rem; }

@media (max-width: 55em) {
    .rd-form-line { grid-template-columns: 1fr; }
    .rd-form-slots { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 30em) {
    .rd-form-slots { grid-template-columns: 1fr; }
    .rd-form-actions > .btn, .rd-form-actions > button { width: 100%; }
}
.rd-stage { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-start; }
.rd-stage-main { flex: 1 1 20rem; min-width: 0; }
.rd-panel { flex: 0 0 15rem; min-width: 0; display: flex; flex-direction: column; gap: 0.7rem; padding: 0.9rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); position: sticky; top: 1rem; }
@media (max-width: 44em) { .rd-stage { flex-direction: column; } .rd-panel { position: static; flex-basis: auto; width: 100%; } }

.rd-canvas { border: 1px solid var(--border); border-radius: var(--radius); padding: 0.5rem 1rem; background: var(--surface); }
/* Square designer: the editable card wears the REAL tile chrome (media + foot meta) at grid-tile width, so
   what you design is what the results grid renders; context samples sit beside each other like a grid row. */
.rd-canvas .sq-card { max-inline-size: 16rem; }
.rd-ctx-row { display: flex; flex-wrap: wrap; gap: 1rem; align-items: flex-start; }
.rd-ctx-row .sq-card { flex: 0 1 14rem; min-width: 0; }
.rd-sample { animation: none; }
.rd-rowsolo { min-width: 0; }
.rd-context { margin-top: 0.5rem; border-top: 1px dashed var(--border); padding-top: 0.5rem; opacity: 0.85; }
/* closed-details hiding is overridable by author display on children (the nav pattern exploits this;
   here it backfires — the result cards carry their own display) — hide explicitly. */
details.rd-context:not([open]) > :not(summary) { display: none !important; }
.rd-context-label { margin: 1rem 0 0.4rem; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em;
    cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 0.4rem; border-radius: var(--radius-sm); padding: 0.15rem 0.3rem; }
.rd-context-label::-webkit-details-marker { display: none; }
.rd-context-label::before { content: "▸"; font-size: 0.7rem; transition: transform 0.15s ease; }
details.rd-context[open] > .rd-context-label::before { transform: rotate(90deg); }
.rd-context-label:hover { background: var(--surface-2); color: var(--text); }
.rd-context-label:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .rd-context-label::before { transition: none; } }
.rd-empty { padding: 1rem 0; }

.rd-editable .rd-chip { display: block; position: relative; border-radius: var(--radius-sm); cursor: grab; outline: 1px dashed transparent; outline-offset: 2px; touch-action: none; user-select: none; -webkit-user-select: none; }
/* The favicon is an <img> — natively draggable, which hijacks pointermove and killed the chip drag (owner: "only
   the favicon won't drop"). draggable=false is set in JS; these are the CSS belts for WebKit + selection drags. */
.rd-editable .rd-chip img { -webkit-user-drag: none; user-drag: none; }
.rd-editable .rt-row { align-items: center; }
.rd-editable .rd-chip:hover { outline-color: var(--border-strong); }
.rd-editable .rd-chip:focus-visible { outline: 2px solid var(--brand-strong); }
.rd-editable .rd-chip.rd-selected { outline: 2px solid var(--brand); background: var(--brand-soft); }
body.rd-dragging { cursor: grabbing; user-select: none; }

.rd-slot { background: transparent; border-radius: 2px; transition: background 0.1s; }
.rd-slot-row { min-height: 4px; margin: 1px 0; }
.rd-slot-col { align-self: stretch; min-width: 4px; }
body.rd-dragging .rd-slot-row { min-height: 16px; background: var(--surface-2); }
body.rd-dragging .rd-slot-col { min-width: 16px; background: var(--surface-2); }
/* EDITABLE solo rows are flex like multi-element rows: (a) chips hug their content — a block .rd-rowsolo
   stretched a lone favicon's chip (and its cloned drag GHOST) to the full card width, burying the drop bands
   under a giant slab and making the selection outline read as full-width; (b) col slots get real height — as
   block children they were 0-tall and UNHITTABLE, so "drop beside a lone element" was silently impossible.
   Context cards keep the true block rendering (fidelity); the editable card trades exact solo-row geometry for
   a manipulable surface. */
.rd-editable .rd-rowsolo { display: flex; flex-wrap: wrap; align-items: baseline; }
body.rd-dragging .rd-rowsolo { display: flex; align-items: center; }
/* During a drag, SOLO text chips flex from basis 0 so the row's start/end col slots share their line — with the
   natural (max-content) basis, flex line-breaking exiled those slots to their own wrapped lines as invisible
   slivers (owner: "the excerpt's start/end dropzones don't appear unless the favicon is already there"). Atoms
   (favicon/date/number) stay content-sized. */
body.rd-dragging .rd-rowsolo > .rd-chip:has(> .result-title), body.rd-dragging .rd-rowsolo > .rd-chip:has(> .result-desc),
body.rd-dragging .rd-rowsolo > .rd-chip:has(> .result-url), body.rd-dragging .rd-rowsolo > .rd-chip:has(> .result-sitelinks) {
    flex: 1 1 0; min-width: 0;
}
.rd-slot.rd-slot-active { background: var(--brand) !important; }
.rd-ghost { position: fixed; z-index: 1000; pointer-events: none; opacity: 0.85; transform: translate(-50%, -50%); box-shadow: var(--shadow); background: var(--surface); border: 1px solid var(--brand); border-radius: var(--radius-sm); padding: 0.15rem 0.35rem; }
/* Multi-select: the drag ghost's count badge, dimmed origin chips, and the panel's mixed-value affordances. */
.rd-ghost-count { position: absolute; top: -0.5rem; inset-inline-end: -0.5rem; min-width: 1.1rem; text-align: center;
    background: var(--brand); color: var(--brand-contrast, #fff); border-radius: var(--radius-pill, 999px);
    font-size: 0.7rem; font-weight: 600; padding: 0 0.35rem; }
.rd-chip.rd-drag-src { opacity: 0.35; }
.rd-mixed-tag { font-size: 0.68rem; color: var(--text-muted); border: 1px dashed var(--border-strong);
    border-radius: var(--radius-pill, 999px); padding: 0 0.3rem; margin-inline-start: 0.3rem; }
.rd-toggle.mixed { border-style: dashed; color: var(--text); }
.rd-panel-sub { margin: -0.3rem 0 0.5rem; font-size: 0.8rem; }

.rd-tray-head { font-size: 0.72rem; margin: 0.9rem 0 0.35rem; }
/* Template-level "Favicons in site groups" strip: permanent chrome under the canvas (the style
   panel is selection-scoped and wiped per selection, so it can't host template-wide options). */
.rd-groupopts { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.6rem; margin-top: 0.75rem; }
.rd-groupopts .rd-field-label { margin: 0; }
/* The synthetic cluster heading above the editable sample — preview chrome, never interactive. */
.rd-group-head { pointer-events: none; margin-bottom: 0.25rem; padding-block: 0.25rem 0.15rem; }
/* A favicon the current group placement hides on cluster members: dimmed, not removed — the chip
   must stay selectable/movable in the editor. */
.rd-fav-suppressed { opacity: 0.25; }
.rd-tray { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.rd-tray-chip { font-size: 0.8rem; cursor: grab; touch-action: none; color: var(--text); background: var(--surface-2); border: 1px dashed var(--border-strong); border-radius: var(--radius-pill); padding: 0.25rem 0.7rem; }
.rd-tray-chip:hover { border-color: var(--brand); color: var(--brand-strong); }
.rd-tray-chip:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }

.rd-panel-hint { margin: 0; font-size: 0.82rem; }
.rd-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
    font-weight: 600; font-size: 0.95rem; }
.rd-panel-head-label { min-width: 0; overflow-wrap: anywhere; }
/* The familiar top-right ✕ — hides the selected element(s); the accessible name carries the verb. */
.rd-close { flex: none; width: 2rem; height: 2rem; display: inline-flex; align-items: center;
    justify-content: center; cursor: pointer; color: var(--text-muted); background: transparent;
    border: 1px solid transparent; border-radius: var(--radius-pill); font-size: 0.8rem; line-height: 1; }
.rd-close:hover { color: var(--text); background: var(--surface-2); }
.rd-close:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }
.rd-field { display: flex; flex-direction: column; gap: 0.25rem; }
.rd-field-label { font-size: 0.72rem; color: var(--text-muted); }
.rd-seg { display: inline-flex; flex-wrap: wrap; gap: 0.15rem; padding: 0.2rem; background: var(--surface); border: 1px solid var(--control-border); border-radius: var(--radius-pill); }
.rd-seg-opt { min-width: 0; min-block-size: 2rem; cursor: pointer; font-size: 0.78rem; color: var(--text-muted); background: transparent; border: 0; border-radius: var(--radius-pill); padding: 0.2rem 0.55rem; }
.rd-seg-opt:hover { color: var(--text); }
.rd-seg-opt.active { background: color-mix(in srgb, var(--accent) 16%, var(--surface)); color: var(--text); box-shadow: inset 0 0 0 1px var(--accent); }
.rd-seg-opt:focus-visible { outline: 2px solid var(--brand-strong); outline-offset: 1px; }
.rd-toggle { min-block-size: 2rem; align-self: flex-start; font-size: 0.78rem; cursor: pointer; color: var(--text-muted); background: var(--surface); border: 1px solid var(--control-border); border-radius: var(--radius-pill); padding: 0.25rem 0.7rem; }
.rd-toggle.active { color: var(--text); border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.rd-moves { display: flex; gap: 0.25rem; }
.rd-move { min-block-size: 2rem; flex: 1 1 0; cursor: pointer; color: var(--text-muted); background: var(--surface); border: 1px solid var(--control-border); border-radius: var(--radius-sm); padding: 0.25rem 0; }
.rd-move:hover { color: var(--text); border-color: var(--border-strong); }

.rd-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin-top: 1.25rem; }
.rd-status { font-size: 0.85rem; color: var(--success); opacity: 0; transition: opacity 0.2s; }
.rd-status.rd-status-show { opacity: 1; }

/* Saved designs + built-in gallery strips (server-rendered, below the editor; work without JS). */
.rd-designs, .rd-gallery { margin-top: 2rem; }
.rd-strip-head { font-size: 1rem; margin: 0 0 0.75rem; }
.rd-embed { min-width: 0; }
.rd-design-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr)); gap: 1rem; }
.rd-design-card { display: flex; flex-direction: column; gap: 0.5rem; min-width: 0; padding: 0.75rem; border: 1px solid var(--border); border-radius: 0.6rem; background: var(--surface, var(--bg)); }
.rd-design-card.is-active { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
.rd-mini { max-height: 8rem; overflow: hidden; padding: 0.5rem 0.6rem; border: 1px solid var(--border); border-radius: 0.4rem; background: var(--bg); font-size: 0.72rem; line-height: 1.3; pointer-events: none; }
.rd-mini .result-item { margin: 0; }
.rd-mini .result-card-tools { display: none; }   /* the ⋮ kebab isn't part of a design preview */
.rd-mini .result-favicon { width: 14px; height: 14px; }
/* Square minis: a full 4:3 media block would eat the whole preview box — a slim banner keeps the
   tile anatomy (media → rows → foot meta) recognizable inside the strip card. */
.rd-mini .sq-media { block-size: 3.2rem; aspect-ratio: auto; }
.rd-mini .sq-card .result-title:not([class*="rt-clamp"]),
.rd-mini .sq-card .result-desc:not([class*="rt-clamp"]) { -webkit-line-clamp: 2; }
.rd-design-name { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem; min-width: 0; font-weight: 600; color: var(--text); }
.rd-design-name > span:first-child { overflow: hidden; text-overflow: ellipsis; }
.rd-active-badge { padding: 0 0.3rem; border: 1px solid var(--brand); border-radius: 0.3rem; font-size: 0.7rem; font-weight: 500; color: var(--brand); }
.rd-design-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: auto; }
/* Gallery cards: the single Use button sits at the card's end corner (owner-directed); the My-designs
   strip keeps its start-aligned multi-action row. flex-end is direction-aware, so RTL mirrors. */
.rd-gallery .rd-design-actions { justify-content: flex-end; }
.rd-design-actions form { display: inline; margin: 0; }

/* header theme cycle (marketing chrome; anonymous-visible) */
/* language switcher — shared: a wrap row of native-name buttons; the current option gets the brand
   highlight + aria-current (the switcher is an enhanced form — PRG + soft morph, no client swap). */
.lang-switcher { display: flex; flex-wrap: wrap; gap: 0.25rem; margin: 0; }
.lang-switcher .lang-option.is-current { background: var(--brand-soft); color: var(--brand-strong); font-weight: 600; }
/* Vertical variant for header menu panels (six options must never become a segmented row). */
.lang-switcher--menu { flex-direction: column; flex-wrap: nowrap; gap: 0.1rem; }
.lang-switcher--menu .lang-option {
    inline-size: 100%; min-inline-size: 0; justify-content: flex-start; text-align: start;
    white-space: normal; line-height: 1.25;
}
/* The row follows the PAGE's reading edge; this isolated label keeps its own native bidi ordering. */
.lang-switcher--menu .lang-option-label {
    min-inline-size: 0; overflow-wrap: anywhere; text-align: match-parent;
}
/* marketing footer third column */
.footer-lang { display: flex; flex-direction: column; gap: 0.35rem; min-inline-size: 0; }
.footer-lang .lang-switcher { max-inline-size: 22rem; }
/* the marketing header's language popover rides the header-menu recipe; only sibling spacing is new
   (it sits AFTER the theme-cycle, whose auto margin anchors the whole right cluster). */
.app-header .lang-menu > .header-menu-btn { min-inline-size: 2.25rem; }
/* This six-item list needs less measure than the multi-control header menu. The viewport cap also
   prevents a closed <details> phantom-overflow at high zoom in Chromium. */
.app-header .lang-menu > .header-menu-panel {
    inline-size: min(11rem, calc(100vw - 1.5rem)); min-inline-size: 0;
}
.app-header .theme-cycle{font-size:1rem;line-height:1;padding:.35rem .55rem;min-inline-size:2.75rem;min-block-size:2.75rem;align-items:center;justify-content:center;gap:.55rem}

/* ═══ Signup — the membership desk ═══
   Two columns at ≥56em (the form does the work; a quiet value rail says why), single column below.
   Signature: a slim aurora edge across the card's top — the landing pulse's colors, whispered. */
.signup-shell { align-items: flex-start; gap: clamp(2rem, 5vw, 3.5rem); }
/* The GREET state (no value rail): one card, vertically centered in the viewport on every form factor,
   with a roomier internal rhythm than the working signup form. */
.signup-shell:not(.has-aside) { min-height: 72dvh; align-items: center; }
.signup-shell:not(.has-aside) .auth-card--signup { padding: 2.5rem min(2.25rem, 7vw); }
.signup-shell:not(.has-aside) h1 { margin: 0 0 0.75rem; }
.signedin-as { margin-bottom: 1.75rem; }
.signedin-avatar { margin-bottom: 1.4rem; }
.signedin-actions { gap: 0.75rem; }
.signedin-switch { margin-top: 1.25rem; }
.signup-shell.has-aside { display: flex; flex-wrap: wrap; justify-content: center; }
.auth-card--signup { position: relative; overflow: hidden; }
.auth-card--signup::before { content: ""; position: absolute; inset-block-start: 0; inset-inline: 0; height: 3px;
    background: linear-gradient(90deg, var(--brand), #98a5ea 35%, #b0bbfb 70%, var(--brand));
    background-size: 220% 100%; animation: signup-aurora 9s linear infinite; }
@keyframes signup-aurora { from { background-position: 0% 0; } to { background-position: 220% 0; } }
/* wrap: at 200% text the nowrap badge alone can fill a phone-width card — the caption drops below it */
.signup-step { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.5rem; margin: 0 0 0.9rem; font-size: 0.8125rem; color: var(--text-muted); }
.signup-step-badge { flex: none; font-weight: 700; font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--brand); border: 1px solid color-mix(in srgb, var(--brand) 45%, transparent);
    border-radius: var(--radius-pill, 999px); padding: 0.1rem 0.55rem;
    background: color-mix(in srgb, var(--brand) 8%, transparent); white-space: nowrap; }
.signup-cta { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; margin-top: 0.75rem; }
.signup-cta-lock { width: 1.05em; height: 1.05em; flex: none; }
.signup-trust { display: flex; flex-direction: column; gap: 0.2rem; text-align: center; margin-top: 0.8rem;
    font-size: 0.8125rem; color: var(--text-muted); }
.signup-stripe { font-size: 0.75rem; color: var(--text-subtle); }
.signup-aside { flex: 0 1 19rem; min-width: 15rem; padding-block-start: 0.5rem; }
.signup-aside-title { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--text-muted); margin: 0 0 0.7rem; }
.signup-aside-title + .signup-aside-title, .signup-how { margin-top: 0; }
.signup-value-list { list-style: none; margin: 0 0 1.6rem; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.signup-value-list li { display: flex; gap: 0.55rem; align-items: flex-start; font-size: 0.9rem; color: var(--text); }
.signup-value-list .check { color: var(--success); flex: none; }
.signup-how { margin: 0; padding-inline-start: 1.2rem; display: flex; flex-direction: column; gap: 0.45rem;
    font-size: 0.9rem; color: var(--text-muted); }
.signup-how li::marker { color: var(--brand); font-weight: 700; }
.signedin-avatar { width: 3rem; height: 3rem; margin-inline: auto; border-radius: 50%; display: flex; align-items: center; justify-content: center;
    font-weight: 800; font-size: 1.2rem; color: var(--brand-strong, var(--brand));
    background: color-mix(in srgb, var(--brand) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--brand) 40%, transparent); margin-bottom: 0.9rem; }
.signedin-as { overflow-wrap: anywhere; }
/* Stacked rail: min-width must reset (15rem is 480px at 200% text — wider than a phone), and the
   cap is rem+% so it scales with text yet never exceeds the viewport. */
@media (max-width: 56em) { .signup-aside { flex-basis: 100%; min-width: 0; max-width: min(26.25rem, 100%); } }
@media (prefers-reduced-motion: reduce) { .auth-card--signup::before { animation: none; } }

/* Settings > Search — the Default display mode pushbuttons (the results toolbar's language, radio-backed
   so the plain form post works without JS; the check state mirrors .view-opt.active). */
.vm-seg { justify-content: flex-start; }
.vm-opt { cursor: pointer; }
.vm-opt input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.vm-opt:has(input:checked) { background: color-mix(in srgb, var(--brand) 16%, transparent); color: var(--text); border-color: var(--brand); }
.vm-opt:has(input:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; }

/* ---------- Support portal (/support) ---------- */
/* Reflow-first: rem spacing, flex-wrap, min-width:0 — readable at 200% text with no horizontal scroll. */
.support-page .page-head { padding-block-end: 1rem; }
.support-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-block: 0.5rem 1.5rem; }
.support-list-title { font-size: 1.1rem; margin-block: 1.25rem 0.6rem; }
.support-ticket-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.support-ticket-row { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.support-ticket-link { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; align-items: baseline; justify-content: space-between;
    padding: 0.7rem 0.9rem; color: inherit; }
.support-ticket-link:hover { text-decoration: none; background: var(--surface-2); border-radius: var(--radius); }
.support-ticket-subject { flex: 1 1 16rem; min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.support-ticket-num { color: var(--text-muted); font-weight: 600; font-variant-numeric: tabular-nums; }
.support-ticket-meta { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: baseline; }
.support-newreply { display: inline-block; margin-inline-start: 0.4rem; padding: 0.05rem 0.5rem; border-radius: 999px;
    background: var(--brand); color: var(--brand-contrast); font-size: 0.72rem; font-weight: 700; }
.support-status { display: inline-block; padding: 0.1rem 0.55rem; border-radius: 999px; font-size: 0.78rem; font-weight: 700;
    border: 1px solid var(--border); }
.support-status-new, .support-status-open { background: var(--success-soft); color: var(--success); border-color: transparent; }
.support-status-pending { background: var(--warning-soft); color: var(--warning); border-color: transparent; }
.support-status-on_hold { color: var(--text-muted); }
.support-status-solved { color: var(--success); }
.support-status-closed { color: var(--text-muted); }

.support-new-layout { display: flex; flex-wrap: wrap; gap: 2rem; align-items: flex-start; }
.support-new-form { flex: 1 1 24rem; min-width: 0; }
.support-new-aside { flex: 1 1 14rem; min-width: min(14rem, 100%); max-width: 22rem; }
.support-impact { border: 0; padding: 0; margin: 0 0 1.1rem; }
.support-impact-opt { display: flex; gap: 0.5rem; align-items: baseline; padding-block: 0.25rem; }
.support-diag-label { display: flex; gap: 0.5rem; align-items: baseline; font-weight: 600; font-size: 0.9375rem; }
.support-file-input { font-size: 0.9rem; max-width: 100%; }
.support-suggest { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2);
    padding: 0.75rem 0.9rem; margin-block-end: 1.1rem; }
.support-suggest-title { margin: 0 0 0.4rem; font-weight: 600; font-size: 0.9rem; }
.support-suggest-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.92rem; }

.support-ticket-title { overflow-wrap: anywhere; }
.support-ticket-headline { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: baseline; margin-block-start: 0.4rem; }
.support-transcript { font-size: 0.85rem; }
.support-sla-line { display: block; margin-block-start: 0.25rem; }
.support-newreply-note[hidden] { display: none; }

.support-thread { list-style: none; margin: 1rem 0; padding: 0; display: flex; flex-direction: column; gap: 0.75rem; }
.support-msg { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 0.8rem 1rem; }
.support-msg-staff { border-inline-start: 0.2rem solid var(--brand); }
.support-msg-you { background: var(--surface-2); }
.support-msg-head { display: flex; flex-wrap: wrap; gap: 0.5rem 0.75rem; align-items: baseline; margin-block-end: 0.4rem; font-size: 0.875rem; }
.support-msg-body { white-space: pre-wrap; overflow-wrap: anywhere; }
.support-msg-attachments { list-style: none; margin: 0.5rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.6rem; font-size: 0.85rem; }
.support-event { color: var(--text-muted); font-size: 0.85rem; padding-inline-start: 0.5rem; }
.support-event-time { white-space: nowrap; }

.support-composer-wrap { margin-block: 1.25rem 2rem; }
.support-composer { display: flex; flex-direction: column; gap: 0.6rem; }
.support-composer-foot { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }
.support-composer-foot .btn-primary { margin-inline-start: auto; }
.support-file-label { display: inline-flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; font-size: 0.9rem; color: var(--text-muted); min-width: 0; }
.support-self-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-block-start: 0.75rem; }

.support-csat { margin-block: 1.25rem; }
.support-csat-title { font-size: 1.05rem; margin: 0 0 0.6rem; }
.support-csat-form { display: flex; flex-direction: column; gap: 0.6rem; }
.support-csat-choices { min-inline-size:0; margin:0; padding:0; border:0; display: flex; flex-wrap: wrap; gap: 1rem; }
.support-csat-opt { display: inline-flex; gap: 0.4rem; align-items: baseline; font-weight: 600; }
.support-csat-form .btn { align-self: flex-start; }
/* Reflow: every support-page button wraps its label at large text sizes rather than forcing h-scroll. */
.support-page .btn { white-space: normal; line-height: 1.25; }
.support-self-actions form { min-width: 0; max-width: 100%; }

/* ── Instant answers ─────────────────────────────────────────────────────────────────────────────
   The answer card sits between the rank summary and the results. Fully SSR; 22-instant-answers.ts
   reveals the copy button and upgrades live widgets. rem-based throughout (reflows at 200% text);
   direction-neutral (logical properties) so RTL mirrors for free. */
.ia-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
  padding: 1rem 1.125rem; margin: 0.25rem 0 1rem; max-width: 42rem; }
.ia-card.ia-error { border-color: var(--border-strong); }
.ia-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; margin: 0 0 0.25rem; }
.ia-primary { font-size: 1.75rem; font-weight: 650; line-height: 1.2; margin: 0;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.ia-error .ia-primary { color: var(--text-muted); }
.ia-expression { font-size: 0.875rem; margin: 0.25rem 0 0; overflow-wrap: anywhere; }
.ia-secondary { font-size: 0.9375rem; margin: 0.375rem 0 0; color: var(--text); overflow-wrap: anywhere; }
.ia-items { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  gap: 0.375rem 1rem; margin: 0.625rem 0 0; }
.ia-item dt { font-size: 0.75rem; color: var(--text-muted); }
.ia-item dd { margin: 0; font-size: 0.9375rem; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.ia-svg svg { width: min(11rem, 60vw); height: auto; display: block; margin: 0.375rem 0; border-radius: 0.5rem; }
.ia-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; margin-top: 0.625rem; }
.ia-foot:empty { display: none; }
.ia-copy { font-size: 0.8125rem; padding: 0.25rem 0.75rem; border: 1px solid var(--control-border);
  min-block-size:2rem; border-radius: var(--radius-pill); background: none; color: var(--text); cursor: pointer; }
.ia-copy:hover { border-color: var(--border-strong); }
.ia-requeries { display: flex; flex-wrap: wrap; gap: 0.375rem; min-width: 0; }
.ia-requery { font-size: 0.8125rem; padding: 0.25rem 0.75rem; border: 1px solid var(--control-border);
  min-block-size:2rem; display:inline-flex; align-items:center; border-radius: var(--radius-pill); text-decoration: none; color: var(--text-muted); white-space: nowrap; }
.ia-requery:hover { color: var(--text); border-color: var(--border-strong); }
.ia-disclosure { font-size: 0.75rem; margin: 0.625rem 0 0; }

/* Flagship timezone card: ONE shared content width for everything that reads as a timeline —
   the city matrix, the hour axis, the slider, and the map — so their right edges line up as a
   single column instead of each element picking its own stopping point. */
.ia-tz { --tz-content: 46rem; --tz-label-col: clamp(9rem, 32%, 15rem); }

/* The city matrix. Every row (and the axis) uses the SAME grid template — city block | timeline —
   which is what actually aligns the strips into one comparable band. Collapses to stacked
   label-over-strip below the em breakpoint (strips stay full-width ⇒ still aligned). */
.ia-tz-axis { display: grid; grid-template-columns: var(--tz-label-col) minmax(0, 1fr);
  column-gap: 1rem; align-items: end; max-width: var(--tz-content); margin: 0.75rem 0 0; }
.ia-tz-axis-label { font-size: 0.6875rem; }
.ia-tz-axis-scale { position: relative; display: block; height: 1rem; font-size: 0.6875rem;
  font-variant-numeric: tabular-nums; }
.ia-tz-axis-scale i { position: absolute; bottom: 0; font-style: normal; transform: translateX(-50%); }
.ia-tz-axis-scale i:nth-child(1) { left: 0; transform: none; }
.ia-tz-axis-scale i:nth-child(2) { left: 25%; }
.ia-tz-axis-scale i:nth-child(3) { left: 50%; }
.ia-tz-axis-scale i:nth-child(4) { left: 75%; }
.ia-tz-axis-scale i:nth-child(5) { left: 100%; transform: translateX(-100%); }
.ia-tz-rows { list-style: none; margin: 0.25rem 0 0; padding: 0; display: grid; gap: 0.625rem;
  max-width: var(--tz-content); }
.ia-tz-row { display: grid; grid-template-columns: var(--tz-label-col) minmax(0, 1fr);
  column-gap: 1rem; align-items: center; min-width: 0; }
.ia-tz-rowhead { display: grid; gap: 0.125rem; min-width: 0; }
.ia-tz-headline { display: flex; align-items: center; gap: 0.375rem; min-width: 0; }
.ia-tz-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.5rem; }
.ia-tz-glyph { width: 1.25rem; text-align: center; flex: none; }
.ia-tz-city { font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ia-tz-remove { flex: none; margin-inline-start: auto; width: 1.75rem; height: 1.75rem;
  display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-pill);
  color: var(--text-muted); text-decoration: none; font-size: 0.75rem; line-height: 1;
  opacity: 0; transition: opacity 120ms ease; }
.ia-tz-row:hover .ia-tz-remove, .ia-tz-row:focus-within .ia-tz-remove { opacity: 1; }
.ia-tz-remove:hover, .ia-tz-remove:focus-visible { color: var(--text); background: var(--border); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .ia-tz-remove { transition: none; } }
@media (hover: none) { .ia-tz-remove { opacity: 1; } }   /* touch: no hover to reveal — always visible */
.ia-tz-time { font-variant-numeric: tabular-nums; font-size: 1.0625rem; }
.ia-tz-chip { font-size: 0.6875rem; border: 1px solid var(--border); border-radius: var(--radius-pill);
  padding: 0.0625rem 0.5rem; color: var(--text-muted); white-space: nowrap; }
.ia-tz-dst { border-style: dashed; }
.ia-tz-strip { display: flex; gap: 1px; height: 0.875rem; min-width: 0; }
.ia-tz-slot { flex: 1 1 0; border-radius: 1px; background: var(--border); }
.ia-tz-b { background: var(--brand); }
.ia-tz-d { background: var(--border-strong); }
.ia-tz-next { font-size: 0.75rem; }
.ia-tz-unix { font-size: 0.8125rem; font-variant-numeric: tabular-nums; }
/* The card mid-swap (add/remove/knobs fetch the fresh server render): calm, no layout shift. */
.ia-tz[aria-busy="true"] { opacity: 0.6; transition: opacity 120ms ease; }
@media (prefers-reduced-motion: reduce) { .ia-tz[aria-busy="true"] { transition: none; } }
@media (max-width: 38em) {
  .ia-tz-row, .ia-tz-axis { grid-template-columns: minmax(0, 1fr); }
  .ia-tz-axis-label { display: none; }
  .ia-tz-remove { opacity: 1; }
}

/* Timer state: a static (reduced-motion-safe) accent when the countdown completes; the SR live
   region announces regardless of audio. */
.ia-timer-done .ia-primary { color: var(--brand-strong); }
.ia-card .visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap; }
.ia-tz-legend { display: flex; align-items: center; gap: 0.375rem; font-size: 0.75rem; margin: 0.375rem 0 0; }
.ia-tz-legend .ia-tz-slot { flex: 0 0 auto; width: 0.75rem; height: 0.5rem; }

/* The flagship world map: theme-aware sea/land, computed night + twilight overlays, city markers.
   Night stays darker than day in EVERY mode. The overlay is a component token because one literal
   can't serve both grounds: over the light sea a soft navy veil reads clearly, but over the dark
   theme's #14121f sea the same veil was near-invisible — dark themes deepen the fill to black and
   raise the opacity (the app.css dual pattern, scoped: media query for system dark, [data-theme]
   for the explicit toggle, both directions). High-contrast adds a STROKED terminator edge — over a
   solid-black (light-HC) or solid-white (dark-HC) landmass a fill difference alone can't carry the
   boundary. forced-colors keeps geometry, drops the tints. */
.ia-tz-map { margin: 0.625rem 0 0; max-width: var(--tz-content, 46rem);
  --ia-map-night: #0b1026; --ia-map-night-op: 0.30; --ia-map-twilight-op: 0.15; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ia-tz-map {
    --ia-map-night: #000000; --ia-map-night-op: 0.50; --ia-map-twilight-op: 0.25; }
}
:root[data-theme="dark"] .ia-tz-map {
  --ia-map-night: #000000; --ia-map-night-op: 0.50; --ia-map-twilight-op: 0.25; }
.ia-tz-map svg { width: 100%; height: auto; display: block; }
.ia-map-sea { fill: var(--surface); stroke: var(--border); stroke-width: 1; }
.ia-map-land { fill: var(--border-strong); }
.ia-map-twilight { fill: var(--ia-map-night); opacity: var(--ia-map-twilight-op); }
.ia-map-night { fill: var(--ia-map-night); opacity: var(--ia-map-night-op); }
.ia-map-halo { fill: var(--brand); opacity: 0.25; }
.ia-map-dot { fill: var(--text-muted); }
.ia-map-dot--primary { fill: var(--brand); }
.ia-map-line { stroke: var(--brand); stroke-width: 1.5; fill: none; stroke-dasharray: 4 3; opacity: 0.7; }
[data-contrast="high"] .ia-map-night,
[data-contrast="high"] .ia-map-twilight { stroke: var(--text); stroke-width: 1; }
[data-contrast="high"] .ia-map-night { opacity: 0.40; }
@media (prefers-contrast: more) {
  .ia-map-night, .ia-map-twilight { stroke: var(--text); stroke-width: 0.75; }
}
@media (forced-colors: active) {
  .ia-map-sea { fill: Canvas; stroke: CanvasText; }
  .ia-map-land { fill: CanvasText; }
  .ia-map-twilight, .ia-map-night { fill: none; }
  .ia-map-halo { fill: none; }
  .ia-map-dot, .ia-map-dot--primary { fill: Highlight; }
}

/* The time slider — the flagship's central lever. A GET form; the range sweeps the reference zone's
   chosen day in quarter-hours; Apply submits no-JS and the client module hides it once live. The
   axis is pinned ltr (a day axis never mirrors in RTL — it must stay aligned with the strips and
   the map); labels around it stay logical. The strip cursor uses physical `left` deliberately: its
   container is dir=ltr. */
.ia-tz-slider { display: grid; grid-template-columns: var(--tz-label-col) minmax(0, 1fr);
  column-gap: 1rem; align-items: center; margin-top: 0.625rem; min-width: 0;
  max-width: var(--tz-content, 46rem); }
.ia-tz-slider-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; min-width: 0; }
.ia-tz-range { width: 100%; min-width: 0; accent-color: var(--brand); margin: 0; }
@media (max-width: 38em) {
  .ia-tz-slider { grid-template-columns: minmax(0, 1fr); row-gap: 0.375rem; }
}
.ia-tz-date input { font: inherit; font-size: 0.8125rem; padding: 0.2rem 0.5rem;
  border: 1px solid var(--control-border); border-radius: var(--radius);
  background: var(--input-bg); color: var(--text); }
.ia-tz-strip { position: relative; }
.ia-tz-cursor { position: absolute; inset-block: -2px; left: var(--tz-cursor, 50%); width: 2px;
  margin-left: -1px; border-radius: 1px; background: var(--brand-strong); }
@media (forced-colors: active) { .ia-tz-cursor { background: Highlight; } }

.ia-tz-knobs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; margin-top: 0.625rem; }
.ia-tz-add { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; min-width: 0; position: relative; }
.ia-tz-add-input[aria-invalid="true"] { border-color: var(--danger); }
.ia-tz-add-error { font-size: 0.75rem; color: var(--danger); flex-basis: 100%; }
.ia-tz-add-input { font-size: 0.8125rem; padding: 0.25rem 0.625rem; border: 1px solid var(--control-border);
  border-radius: var(--radius-pill); background: none; color: var(--text); width: 11rem; max-width: 100%; }
.ia-tz-suggest { position: absolute; top: calc(100% + 0.25rem); inset-inline-start: 0; z-index: 30;
  background: var(--surface); border: 1px solid var(--control-border); border-radius: var(--radius);
  min-width: 14rem; max-width: 90vw; padding: 0.25rem; display: grid; }
.ia-tz-suggest button { text-align: start; padding: 0.375rem 0.625rem; border: 0; background: none;
  color: var(--text); border-radius: 0.375rem; cursor: pointer; font-size: 0.875rem; }
.ia-tz-suggest button:hover, .ia-tz-suggest button[aria-selected="true"] { background: var(--border); }
.ia-tz-suggest .muted { font-size: 0.75rem; }
.ia-live { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; margin: 0.625rem 0 0; }
.ia-live-field { display: grid; gap: 0.125rem; font-size: 0.75rem; color: var(--text-muted); min-width: 0; }
.ia-live-field input { width: 6.5rem; max-width: 100%; font-size: 0.875rem; padding: 0.25rem 0.5rem;
  border: 1px solid var(--control-border); border-radius: 0.5rem; background: none; color: var(--text);
  font-variant-numeric: tabular-nums; }

/* Definitions (the dictionary card). The day-to-day shape is: headword row (word + IPA + play),
   POS sections with numbered senses, linked Wiktionary attribution. Mixed-direction: under an RTL
   page, English content (the labeled EN-gloss fallback) renders as proper LTR islands. */
.ia-def-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.625rem; }
.ia-def-head .ia-primary { margin: 0; }
.ia-def-ipa { font-size: 0.875rem; unicode-bidi: isolate; }
.ia-def-play { border: 1px solid var(--control-border); border-radius: var(--radius-pill); background: none;
  color: var(--text-muted); width: 2rem; height: 2rem; display: inline-flex; align-items: center;
  justify-content: center; cursor: pointer; align-self: center; flex: none; }
.ia-def-play:hover { color: var(--text); border-color: var(--border-strong); }
.ia-def-play[data-state="playing"] { color: var(--brand-strong); border-color: var(--brand-strong); }
.ia-def-play[data-state="loading"] .ia-def-play-wave,
.ia-def-play[data-state="playing"] .ia-def-play-wave { animation: ia-def-wave 1s ease-in-out infinite; }
@keyframes ia-def-wave { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) { .ia-def-play .ia-def-play-wave { animation: none !important; } }
@media (forced-colors: active) { .ia-def-play[data-state="playing"] { color: Highlight; border-color: Highlight; } }
.ia-def-glossnote { font-size: 0.75rem; margin: 0.375rem 0 0; }
.ia-def-pos { margin-top: 0.625rem; }
.ia-def-posname { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  margin: 0 0 0.25rem; }
.ia-def-senses { margin: 0; padding-inline-start: 1.375rem; display: grid; gap: 0.375rem;
  font-size: 0.9375rem; line-height: 1.5; }
.ia-def-senses li::marker { color: var(--text-muted); font-size: 0.8125rem; }
.ia-def-example { font-size: 0.8125rem; margin: 0.125rem 0 0; font-style: italic; }
.ia-def-more { margin-top: 0.375rem; }
.ia-def-more > summary { cursor: pointer; font-size: 0.8125rem; color: var(--link);
  width: fit-content; }
.ia-def-more[open] > summary { margin-bottom: 0.375rem; }
.ia-def-more > .ia-def-senses { margin-top: 0.25rem; }
.ia-disclosure a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.ia-def-credit { display: inline-block; margin-inline-start: 0.625rem; }
.ia-def-credit > summary { cursor: pointer; display: inline; color: var(--link); }
.ia-def-credit > span { display: block; margin-top: 0.25rem; }
/* LTR islands under an RTL page: the labeled English-gloss fallback (and any en-tagged content). */
[dir="rtl"] .ia-def [lang="en"], [dir="rtl"] .ia-def[data-ia-kind] .ia-def-senses[lang="en"] {
  direction: ltr; text-align: start; }
[dir="rtl"] .ia-def .ia-def-senses[lang="en"] { padding-inline-start: 1.375rem; }

/* The Search button lives INSIDE the pill (its far end), so the autosuggest dropdown — which opens
   below the form stack — can never occupy the same space as the button. The old z-stacking
   mitigation (z 45 over the panel) is retired with the collision itself; the BAR row (the form is
   a column stack now) still never wraps. */
.search-bar { flex-wrap: nowrap; }

/* --- /bot — Suede-HealthMonitor documentation (reuses the .legal typography; adds the ranges table).
   The table wrapper scrolls on its own axis so enlarged text reflows without page-level horizontal
   scroll (WCAG 1.4.10); code spans stay LTR islands under the RTL UI languages. --- */
.botdoc .tbl { overflow-x: auto; margin: 0.5rem 0 1rem; }
.botdoc table { border-collapse: collapse; min-width: 100%; }
.botdoc th, .botdoc td { text-align: start; padding: 0.4rem 1.1rem 0.4rem 0; border-bottom: 1px solid var(--border); white-space: nowrap; }
.botdoc th { font-size: 0.85rem; color: var(--muted, inherit); font-weight: 600; }
.botdoc code { direction: ltr; unicode-bidi: isolate; }

/* ── Views collection (settings): the unified user-orderable list ─────────────────────────────────
   Rows carry a ⠿ drag handle (revealed only when JS wires the list — .view-list--drag) and always-on
   accessible ↑/↓ buttons (the no-JS / keyboard path). Built-in rows are badged; the handle column keeps
   the cards aligned whether or not the row is draggable. */
.view-collection-row { align-items: center; flex-wrap: wrap; }
.view-collection-row .sc-card-main { min-width: 0; flex: 1 1 12rem; }
/* System (built-in) rows: the layers glyph in a muted brand tone — the icon alone marks a system view. */
.sc-card-icon-builtin { color: var(--text-muted); background: var(--surface-2); }
/* The enable switch is the LAST action in every row; pinning it to the row's end aligns the toggles in one
   column regardless of what other actions a row carries. */
.view-collection-row .sc-card-actions .view-switch-form { margin-inline-start: auto; }

/* flex 0 1 auto (base is flex:none): the actions block must be SHRINKABLE for its internal wrap to
   engage at large text — flex:none lets it overflow the row instead. */
.view-collection-row .sc-card-actions { flex: 0 1 auto; flex-wrap: wrap; min-width: 0; }
.view-collection-row .view-share { min-width: 0; }
.view-collection-row .view-share-actions { flex-wrap: wrap; }
.view-collection-row .btn, .view-collection-row .rank-unblock { white-space: normal; max-inline-size: 100%; }
.view-drag { display: none; cursor: grab; color: var(--text-subtle); font-size: 1rem; padding: 0.25rem; user-select: none; }
.view-list--drag .view-drag { display: inline-block; }
.view-list--drag [data-view-slug].is-dragging { opacity: 0.5; }
.view-updown { display: inline-flex; flex-direction: column; gap: 0.1rem; }
.view-updown form { margin: 0; }
.view-move {
    display: inline-flex; align-items: center; justify-content: center; inline-size: 2rem; block-size: 2rem;
    font: inherit; font-size: 0.75rem; line-height: 1; cursor: pointer; color: var(--text-muted);
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.view-move:hover:not(:disabled) { color: var(--text); border-color: var(--border-strong); }
.view-move:disabled { opacity: 0.35; cursor: default; }

/* ── The per-view EDITOR (identity header · sites-first card · grouped form · danger zone) ── */
.vw-page { max-inline-size: 52rem; }
.vw-identity { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.8rem; min-width: 0; }
.vw-identity h1 { margin: 0; overflow-wrap: anywhere; }
.vw-identity-meta { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; }
.vw-slug-chip { font-size: 0.85rem; padding: 0.1rem 0.5rem; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-pill); color: var(--text-muted); }
.vw-mode-chip { text-transform: none; }
.vw-mode-boost { color: var(--success); border-color: currentColor; }
.vw-mode-restrict { color: var(--brand-strong); border-color: currentColor; }
.vw-mode-filter { color: var(--warning); border-color: currentColor; }

.vw-card { padding: 1.15rem 1.3rem; margin-block-end: 1.1rem; }
.vw-card-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.3rem 1rem; margin-block-end: 0.85rem; }
.vw-card-head h2 { font-size: 1.02rem; margin: 0; }
.vw-card-head .muted { margin: 0; font-size: 0.85rem; flex-basis: 100%; }

/* Sites & keywords */
.vw-restrict-meter { font-variant-numeric: tabular-nums; font-size: 0.8rem; font-weight: 700; color: var(--text-muted); padding: 0.1rem 0.55rem; border: 1px solid var(--border); border-radius: var(--radius-pill); }
.vw-restrict-meter-hot { color: var(--warning); border-color: currentColor; }
.vw-empty { padding: 1rem 0.2rem; color: var(--text-muted); }
.vw-empty p { margin: 0; }
.vw-rule-list { margin: 0 0 0.9rem; padding: 0; list-style: none; }
.vw-rule-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.75rem; padding: 0.5rem 0.15rem; border-block-end: 1px solid var(--border); }
.vw-rule-row:last-child { border-block-end: 0; }
.vw-rule-kind-ic { display: inline-flex; inline-size: 1.05rem; block-size: 1.05rem; color: var(--text-subtle); flex: none; }
.vw-rule-kind-ic svg { inline-size: 100%; block-size: 100%; }
.vw-rule-row .rule-pattern { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; min-width: 0; overflow-wrap: anywhere; flex: 1 1 12rem; }
.vw-rule-row .rule-del { margin-inline-start: auto; }
/* Included/Excluded group scaffolding — the group heading carries the include/exclude meaning
   (rows stay clean: no strikethrough, no per-row Excluded badge). */
.vw-group-head { margin: 0.7rem 0 0.15rem; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.05em;
    text-transform: uppercase; color: var(--text-muted); }
.vw-group-hint { margin: 0 0 0.25rem; font-size: 0.78rem; color: var(--text-subtle); }
.vw-sites-context { margin: -0.35rem 0 0.75rem; font-size: 0.85rem; }
.vw-sites-warn { margin-block-end: 0.9rem; }
.vw-site-add { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.vw-site-add .field-input { flex: 1 1 14rem; min-width: 0; }
.vw-site-add .field-select { width: auto; flex: 0 1 auto; }
.vw-site-add .btn { flex: none; }
.vw-grammar { margin: 0.6rem 0 0; font-size: 0.8rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.45rem; }
.vw-grammar code { font-size: 0.78rem; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.05rem 0.35rem; overflow-wrap: anywhere; }

/* Field groups */
.vw-field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr)); gap: 0.85rem 1.1rem; }
.vw-field { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.vw-field > span { font-size: 0.8rem; font-weight: 600; color: var(--text-muted); }
.vw-field-hint { font-size: 0.76rem; color: var(--text-subtle); line-height: 1.35; }
.vw-field-wide { grid-column: 1 / -1; }
.vw-field-check { flex-direction: row; align-items: center; gap: 0.5rem; }
.vw-field-check > span { font-size: inherit; font-weight: 500; color: var(--text); }

/* Activation bang adornment */
.vw-bang-wrap { display: flex; align-items: stretch; min-width: 0; }
.vw-bang-prefix { display: inline-flex; align-items: center; padding: 0 0.6rem; font-weight: 700; color: var(--text-muted); background: var(--surface-2); border: 1px solid var(--border); border-inline-end: 0; border-start-start-radius: var(--radius-sm); border-end-start-radius: var(--radius-sm); }
.vw-bang-input { border-start-start-radius: 0; border-end-start-radius: 0; min-width: 0; }

/* Sticky save — always reachable while editing a long form. */
.vw-savebar { position: sticky; inset-block-end: 0; z-index: 5; display: flex; justify-content: flex-end; padding: 0.6rem 0.2rem; background: linear-gradient(to top, var(--bg) 65%, transparent); }

/* Destructive button (confirm dialog). */
.btn-danger { background: transparent; color: var(--danger); border: 1px solid currentColor; }
.btn-danger:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }

/* The time-scope group: three UNIFORM label-above fields (preset select + the custom date pair) on one
   row — bottom-aligned so the inputs sit on one line (and single-line labels on another), wrapping on
   narrow screens. The dates wrapper is display:contents so its two fields are laid out as direct row
   items; author display beats the UA's [hidden] rule, so hiding needs the explicit [hidden] override. */
.vw-time-group { border: 0; padding: 0; margin: 0; min-width: 0; }
/* Top-aligned: single-line labels sit on one line and the input TOPS on another (a native date input
   renders ~2px taller than a select, so bottom-alignment would nudge the select's label down). */
.vw-time-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.75rem 1.1rem; }
.vw-time-row .vw-field { flex: 0 1 auto; min-width: 0; }
.vw-time-row .field-select { width: auto; }
.vw-time-dates { display: contents; }
.vw-time-dates[hidden] { display: none; }

/* Destructive list action: same ghost chrome as its neighbors, red text on hover/focus only. */
.sc-action-danger:hover, .sc-action-danger:focus-visible { color: var(--danger); border-color: currentColor; }

/* Result-layouts group (Settings > Search): the segmented switcher + per-layout designer sections. */
.rl-switch { margin-block-end: 0.9rem; }
.rl-title { margin: 0 0 0.5rem; font-size: 0.95rem; }

/* Public view page: the restrict list's Sites inspection block. */
.view-public-sites { margin: 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 0.4rem; }
.view-public-sites code { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.1rem 0.45rem; overflow-wrap: anywhere; }

/* ── App-wide feedback: the flash strip (no-JS face of the toast) + the confirm dialog ── */
.flash-toast { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.9rem; }
.flash-undo-form { margin: 0; display: inline-flex; }
.flash-undo { background: transparent; border: 0; padding: 0; font: inherit; font-weight: 700;
    color: var(--brand-strong); cursor: pointer; text-decoration: underline; }

.confirm-dialog { max-width: 26rem; border: 1px solid var(--border-strong); border-radius: var(--radius);
    background: var(--surface); color: var(--text); padding: 1.4rem 1.5rem;
    /* The global reset zeroes margins, killing the UA's dialog centering — restore it. */
    margin: auto; box-shadow: var(--shadow-lg); }
.confirm-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
.confirm-dialog h2 { margin: 0 0 0.6rem; font-size: 1.1rem; }
.confirm-dialog-name { margin: 0 0 0.35rem; overflow-wrap: anywhere; }
.confirm-dialog-body { margin: 0 0 1.1rem; font-size: 0.9rem; }
.confirm-dialog-list { margin: -0.6rem 0 1.1rem; padding-inline-start: 1.2rem; max-height: 10rem; overflow-y: auto; font-size: 0.88rem; }
.confirm-dialog-list li { margin: 0.2rem 0; overflow-wrap: anywhere; }
.confirm-dialog-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: flex-end; }

/* Mode hints: JS reveals only the selected mode's line (all three render for no-JS). */
.vw-mode-hints-live .vw-field-hint[data-vw-mode-hint] { display: none; }
.vw-mode-hints-live .vw-field-hint[data-vw-mode-hint].is-active { display: block; }

/* ── Results page: the "Add site to a view" inline picker (cloned from the page template) ── */
.view-add-panel { border-block-start: 1px solid var(--border); margin-block-start: 0.25rem; padding-block-start: 0.25rem; }
.view-add-list { display: flex; flex-direction: column; max-block-size: 14rem; overflow-y: auto; }
.view-add-list form { margin: 0; }
.view-add-item { inline-size: 100%; text-align: start; }
.view-add-new { font-weight: 600; }

/* --------------------------- Landing pop-art era --------------------------- */
/* Round-18 design (branding/landing-pop): Ben-Day masters on exact page grounds. Landing-local
   accent tokens only — the app palette (app.css four-block system) is untouched. */
.landing { --pop-coral: #e2643f; }
:root[data-theme="dark"] .landing { --pop-coral: #ff7a52; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .landing { --pop-coral: #ff7a52; } }

/* Hero: copy column beside the burst, pulled a smidge closer (owner) — tight column gap and the
   art nudged toward the copy. The art is the LCP; the legacy silk-stage paddings are overridden. */
.hero-pop { display: grid; text-align: start; overflow: visible; padding: 0;
    min-height: 0; max-width: 110rem; margin-inline: auto; background: none; }
.hero-pop .hero-pop-art, .hero-pop .hero-copy { grid-area: 1 / 1; }
.hero-pop .hero-copy { background: none; border: 0; backdrop-filter: none; -webkit-backdrop-filter: none;
    align-self: center; justify-self: start; z-index: 1;
    /* "a smidge closer" (owner): the copy field reaches toward the burst — wider column,
       tighter end padding than the mockup's 46%/4rem. */
    max-width: min(50%, 46rem); margin-inline: 0;
    padding: 1.5rem clamp(1rem, 2vw, 2rem) 1.5rem clamp(1.25rem, 4vw, 4rem); }
.hero-pop-art { margin: 0; }
.hero-pop-art img { display: block; width: 100%; height: auto; }
/* The composition's open center is inside the raster. Expand it toward the copy while anchoring
   its physical right edge; the 2016px source still renders strictly down at the 110rem maximum. */
@media (min-width: 56.001em) {
    .hero-pop-art img { width: min(104%, 2016px); max-width: none;
        margin-left: calc(100% - min(104%, 2016px)); }
}
.hero-pop .hero-cta { justify-content: flex-start; }
.hero-pop .uk-hosted { inset-inline-end: 1rem; top: 1rem; }
/* Handset: the copy OVERLAPS the illustration (owner, 2026-07-31 — the separate-row layout made
   enlarged text push the heading a full screen down). The eyebrow pill anchors to the very top of
   the viewport; the heading's top edge anchors JUST BELOW the heroine's chin so her face and fist
   stay clear and everything below belongs to the words. The anchor is a FRACTION of the art band
   (--hero-art-band): at any band >= 43vw the 2016x864 master's cover scale is height-driven, so
   the full artwork is visible top-to-bottom and the chin sits at a fixed ~29% of the band at
   EVERY font size — enlarged text grows the band minimum (rem) and the padding fraction together,
   so the heading can never climb over her face. */
@media (max-width: 56em) {
    .hero-pop { --hero-art-band: clamp(15rem, 80vw, 20rem); padding: 0; grid-template-rows: none; }
    .hero-pop .hero-pop-art { grid-area: 1 / 1; overflow: hidden; height: var(--hero-art-band);
        -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 76%, transparent 100%);
        mask-image: linear-gradient(to bottom, #000 0%, #000 76%, transparent 100%); }
    .hero-pop-art img { width: 100%; height: 100%; min-height: 0; object-fit: cover; object-position: 66% 0; }
    .hero-pop .hero-copy { grid-area: 1 / 1; align-self: start; justify-self: stretch;
        max-width: none; margin: 0; z-index: 1;
        /* +3.15rem = 1 1/3 heading lines (2.25rem x 1.05 line-height x 4/3) — owner-tuned drop below
           the chin so enough of the figure reads before the copy begins. */
        padding: calc(var(--hero-art-band) * .31 + 3.15rem) 1.25rem 2.25rem;
        background: linear-gradient(180deg,
            transparent calc(var(--hero-art-band) * .26),
            color-mix(in srgb, var(--bg) 82%, transparent) calc(var(--hero-art-band) * .44),
            var(--bg) calc(var(--hero-art-band) * .92)); }
    .hero-pop .hero-eyebrow { position: absolute; top: .8rem; inset-inline-start: 1rem; z-index: 2; }
}
/* RTL: the art is directional (subject right, waves leftward) and must not flip. The desktop copy
   stays in the physical-left open field; the handset art row keeps its crop while only text flow
   switches to RTL. */
html[dir="rtl"] .hero-pop { direction: ltr; }
html[dir="rtl"] .hero-pop .hero-copy { direction: rtl; }

/* The shibboleth chips (replaces .hero-nerd). */
.power-strip { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem .6rem;
    max-width: 74rem; margin: 1.75rem auto 0; padding: 0 1.25rem; list-style: none; }
.power-strip li { font-size: .82rem; font-weight: 600; color: var(--text-muted);
    border: 1px solid var(--border); border-radius: 999px; padding: .38rem .85rem; }
.power-strip li.power-noai { color: var(--pop-coral, #e2643f); border-color: currentColor; }
/* Six wrapping capsules become one swipeable capability rail on handsets. A partial next label
   supplies the scroll affordance while the single row caps vertical cost at every text size.
   Desktop keeps the complete centered pill cloud. */
@media (max-width: 34em) {
    .power-strip { flex-wrap: nowrap; justify-content: flex-start; gap: 0; overflow-x: auto;
        overscroll-behavior-inline: contain; scroll-snap-type: inline proximity;
        -webkit-overflow-scrolling: touch;
        margin-block-start: 1rem; padding: .15rem 1.25rem;
        border-block: 1px solid var(--border);
        background: color-mix(in srgb, var(--surface) 72%, transparent); }
    .power-strip li { flex: none; scroll-snap-align: start; white-space: nowrap;
        border: 0; border-radius: 0; padding: .6rem .8rem; }
    .power-strip li + li { border-inline-start: 1px solid var(--border); }
}

/* Why spots grow from 44px glyphs to full spot illustrations. */
.landing .value-icon { width: auto; height: 4.5rem; }
.landing .value-icon img { width: auto; height: 4.5rem; }

/* One compact wavelet punctuates each chapter BELOW its title. The single continuous path (one
   crest + one trough, no spark/cap/second stroke) fixes the old two-stroke junction ambiguity; its
   34px visible footprint and deliberate title gap keep it far too short to behave as an underline.
   The night edition is authored separately in sky blue—never a retained indigo stroke that can
   disappear on #0b0a12. Normal-flow centering is direction-agnostic and remains stable in RTL. */
.landing .section-title { position: relative; padding-bottom: 0; }
.landing .section-title::before { content: none; }
.landing .section-title::after { content: ""; display: block;
    inline-size: 2.25rem; block-size: .75rem; margin: .75rem auto 0; background:
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 12"><path d="M1.5 6C6.5 .5 11.5 .5 17 6S27.5 11.5 34.5 6" fill="none" stroke="%236C79FF" stroke-width="3" stroke-linecap="round"/></svg>')
    no-repeat 50% / contain; }
:root[data-theme="dark"] .landing .section-title::after { background-image:
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 12"><path d="M1.5 6C6.5 .5 11.5 .5 17 6S27.5 11.5 34.5 6" fill="none" stroke="%237FC9FF" stroke-width="3" stroke-linecap="round"/></svg>'); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .landing .section-title::after { background-image:
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 12"><path d="M1.5 6C6.5 .5 11.5 .5 17 6S27.5 11.5 34.5 6" fill="none" stroke="%237FC9FF" stroke-width="3" stroke-linecap="round"/></svg>'); } }
@media (forced-colors: active) { .landing .section-title::after { display: none; } }

/* Section-lead pop art: unframed, capped, centered. */
.section-lead-pop img { max-width: min(52rem, 100%); height: auto; margin-inline: auto; display: block; }

/* Superpowers kiss: the art leads the section, right-leaning, wave tips overlapping the
   theater's top edge; the theater below keeps its designed full-width layout and paints above. */
.powers-art { margin: .5rem 0 clamp(-3.25rem, -3vw, -1.5rem); display: flex; justify-content: flex-end;
    pointer-events: none; position: relative; z-index: 0; }
.powers-art img { width: min(60rem, 92%); height: auto; display: block; }
.landing .theater { position: relative; z-index: 1; }
/* Wide composition: reclaim the transparent master's intrinsic top/bottom gutters in FLOW. The
   heading remains untouched, the raster remains downscaled, and the theater's existing z-index
   lets its surfaces overlap the lower-left signal wave cleanly. */
@media (min-width: 62.001em) {
    .demo-theater > .section-sub { margin-block-end: 0; }
    .powers-art { margin-block-start: -2rem; margin-block-end: -4.5rem; }
    .demo-theater > .theater { margin-block-start: 0; }
}
@media (max-width: 62em) {
    .powers-art { justify-content: stretch; margin: .25rem -1.25rem -1.6rem; }
    .powers-art img { width: 100%; max-height: 13.5rem; object-fit: cover; object-position: 76% 30%; }
}

/* Threat band: intrinsic-aspect art (zero crop), frosted copy card floating in the open field. */
.safety-stage { position: relative; }
.safety-stage-media { position: relative; inset: auto; transform: none; inline-size: 100%;
    margin: 0; }
.safety-stage-media img { display: block; width: 100%; height: auto; }
.safety-stage .safety-stage-copy { position: absolute; inset: 0; display: flex; align-items: center;
    max-width: 110rem; margin-inline: auto; padding: 0 clamp(1rem, 4vw, 4rem); }
.safety-card { max-width: 40rem; background: color-mix(in srgb, var(--bg) 82%, transparent);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    border: 1px solid var(--border); border-radius: var(--radius-lg, 16px);
    padding: clamp(1.25rem, 2.5vw, 2rem); }
@media (max-width: 56em) {
    .safety-stage .safety-stage-copy { position: static; padding: 1rem 1.25rem 0; }
    .safety-card { max-width: none; background: none; border: 0;
        -webkit-backdrop-filter: none; backdrop-filter: none; padding: 0; }
}

/* Fit chapter art (the Arranger) sizes like the other pop leads. */
.ill-fitpop img { width: 100%; height: auto; }

/* Finale + UA polish. */
.brand-moment .hero-trust, .brand-moment .brand-moment-caption { margin-top: 1.6rem; }
