/* ============================================================
   Clarify — Editor Suite (the shared editor + input layer)

   What this file is
   -----------------
   The companion layer to suite.css. suite.css is the design SYSTEM
   (tokens + the everyday component kit: buttons, fields, tables,
   drawers). This file is the EDITOR + INPUT layer on top of it: the
   one shared set of editing-chrome components (selection box, resize
   handles, snap guides, contextual format bubble, brand-aware colour
   picker, first-run coachmark, Preview/Edit toggle, filmstrip) plus
   the richer intake components (choice cards, dropzone, stepper,
   inline validation) that every Clarify tool will inherit so listing,
   email and social all feel like the same premium, learnable product.

   The whole point of building this ONCE is the "one coherent product"
   payoff: the editor language is defined here, not re-invented in each
   tool's CSS. (See MISC/CLARIFY-EDITOR-LANGUAGE.md §1-§2.)

   How to use
   ----------
   - It CONSUMES suite.css's --s-* tokens. It defines no colour tokens
     of its own. NEVER hardcode a colour here — reference --s-text,
     --s-accent, --s-border, --s-surface, --s-focus, --s-ok, --s-warn,
     --s-danger, the --s-r-* radii, the --s-shadow-* tiers, --s-t /
     --s-t-fast. (Load editor-suite.css AFTER suite.css.)
   - It is ADDITIVE and INERT: nothing changes behaviour until a page
     links this stylesheet AND uses these classes. Linking it alone is a
     no-op — there are no global/element selectors, only .s-edit-* /
     .s-choice-* / .s-dropzone* / .s-stepper / .s-field-msg / .s-shake
     class hooks. Zero blast radius on existing surfaces.

   Monochrome-ink rule (locked)
   ----------------------------
   Editing CHROME is monochrome ink (--s-* neutrals). The agent's BRAND
   colour appears in exactly TWO places app-wide: (a) the colour-picker's
   "From your branding" swatch row here, and (b) inside the deliverable
   they're designing (not chrome). So the only non-token colours in this
   file are:
     - #1c1c1e  — the dark contextual-toolbar / element-toolbar / guide
                  badge pill (matches suite.css's .s-toast surface; the
                  one place a dark surface is sanctioned).
     - #fff / white-alpha — icons/handles on those dark pills, and the
                  snap-guide core (which also carries a thin black-alpha
                  ring so it reads on dark canvases).
     - --s-brand fallback gold — the picker brand-row swatch ONLY, and
                  only because that row literally previews the agent's
                  own brand colour. It is page-overridable.

   Canadian spelling throughout. Pure CSS, no frameworks, no build step.
   ============================================================ */

/* ------------------------------------------------------------
   Local helper tokens (NOT a new palette — all derive from --s-*)
   These exist so the dark pill + guide values are named once and the
   monochrome-ink intent is self-documenting. They reference suite's
   --s-* where possible; the two literals are the sanctioned dark-pill
   surface (#1c1c1e, == .s-toast) and the guide white/shadow.
   ------------------------------------------------------------ */
:root {
    /* The one sanctioned dark surface (contextual bubble, element
       toolbar, guide badge) — identical to suite.css .s-toast. */
    --s-edit-pill: #1c1c1e;
    --s-edit-pill-text: #cfd2db;          /* muted icon/label on the pill */
    --s-edit-pill-hover: rgba(255, 255, 255, 0.12);
    --s-edit-pill-sep: rgba(255, 255, 255, 0.16);

    /* Snap/alignment guides: white core + thin dark ring so they read
       on a dark hero/slide AND on a white canvas. */
    --s-edit-guide-core: rgba(255, 255, 255, 0.92);
    --s-edit-guide-ring: 0 0 0 1px rgba(0, 0, 0, 0.28);

    /* The agent's brand colour — used ONLY by the picker "From your
       branding" swatch row. Page can override via inline --s-brand /
       --s-brand-2 (the agent's real primary/secondary). Falls back to
       the app's brand gold so the row is never empty in the kit. */
    --s-brand: #b0843f;
    --s-brand-2: #946c2e;
}

/* ============================================================
   GROUP A — EDITOR COMPONENTS (.s-edit-*)
   Monochrome ink, ported from MISC/clarify-unified-prototype.html.
   ============================================================ */

/* ------------------------------------------------------------
   A1. Preview / Edit segmented toggle (the signature affordance)
   The explicit "you are previewing vs editing" pill with an ink thumb
   that slides under the active label. Reused for tool-switching too
   (.s-edit-seg--tool gives the deeper surface-3 track).
   Prototype: .seg / .seg button / .seg .thumb (lines 111-133),
   .toolseg variant (lines 135-159).
   ------------------------------------------------------------ */
.s-edit-seg {
    display: inline-flex;
    position: relative;
    gap: 2px;
    padding: 3px;
    background: var(--s-surface-2);
    border: 1px solid var(--s-border-strong);
    border-radius: var(--s-r-pill);
}
.s-edit-seg button {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px 16px;
    border: 0;
    background: transparent;
    border-radius: var(--s-r-pill);
    font-family: inherit;
    font-size: 0.81rem;
    font-weight: 600;
    color: var(--s-text-3);
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--s-t-fast);
}
.s-edit-seg button:hover { color: var(--s-text-2); }
.s-edit-seg button.is-on { color: var(--s-on-accent); }
.s-edit-seg button svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2; fill: none; }
/* The sliding ink thumb. Position/width are JS-driven (transform +
   width) so it animates under the active button. */
.s-edit-seg-thumb {
    position: absolute;
    z-index: 1;
    top: 3px;
    left: 3px;
    height: calc(100% - 6px);
    border-radius: var(--s-r-pill);
    background: var(--s-accent);
    box-shadow: 0 2px 8px var(--s-focus);
    transition: transform var(--s-t), width var(--s-t);
}
/* Tool-switch variant: deeper neutral track, flat ink thumb. */
.s-edit-seg--tool { background: var(--s-surface-3); border-color: var(--s-border); }
.s-edit-seg--tool .s-edit-seg-thumb { box-shadow: var(--s-shadow-xs); }
@media (max-width: 900px) {
    .s-edit-seg--tool button span { display: none; }
    .s-edit-seg--tool button { padding: 7px 11px; }
}

/* ------------------------------------------------------------
   A2. Edit-mode helper banner ("you're editing — click any block…")
   A dismissible strip under the top bar. Neutral surface-3 wash.
   Prototype: .edit-banner (lines 471-481), re-tinted off the prototype's
   blue (#D9E4FF) to suite neutrals per the monochrome-ink rule.
   ------------------------------------------------------------ */
.s-edit-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 9px 16px;
    background: var(--s-surface-3);
    color: var(--s-text-2);
    border-bottom: 1px solid var(--s-border);
    font-size: 0.78rem;
    font-weight: 600;
}
.s-edit-banner svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2; fill: none; }
.s-edit-banner kbd {
    font-family: inherit;
    font-weight: 700;
    font-size: 0.69rem;
    color: var(--s-text);
    background: var(--s-surface);
    border: 1px solid var(--s-border-strong);
    border-radius: 5px;
    padding: 1px 7px;
}
.s-edit-banner-x {
    display: inline-flex;
    margin-left: 4px;
    color: var(--s-text-3);
    cursor: pointer;
    opacity: 0.8;
    transition: opacity var(--s-t-fast), color var(--s-t-fast);
}
.s-edit-banner-x:hover { opacity: 1; color: var(--s-text); }
.s-edit-banner-x svg { width: 14px; height: 14px; }

/* ------------------------------------------------------------
   A3. Hover-reveal cue on an editable block
   The "this is editable" outline + faint lift on hover, and the
   focused/editing ring on a per-element click-to-edit target. Applied
   to a wrapper (block) and/or a [contenteditable]-style text node.
   Prototype: body.mode-edit .section::after + :hover (lines 230-241),
   [data-edit] hover/editing (lines 261-268).
   ------------------------------------------------------------ */
.s-edit-hover {
    position: relative;
    transition: box-shadow var(--s-t), transform var(--s-t);
}
.s-edit-hover::after {
    content: "";
    position: absolute;
    inset: 6px;
    border: 1.5px solid transparent;
    border-radius: var(--s-r-sm);
    pointer-events: none;
    transition: border-color var(--s-t), background var(--s-t);
}
.s-edit-hover:hover {
    transform: translateY(-3px);
    box-shadow: inset 0 0 0 9999px rgba(10, 10, 10, 0.02);
}
.s-edit-hover:hover::after {
    border-color: var(--s-accent);
    background: rgba(10, 10, 10, 0.04);
}
/* the over-exaggerated cue can be suppressed on a selected/active block */
.s-edit-hover.is-active::after { border-color: var(--s-accent); }

/* Per-element editable text node (lighter than the block outline). */
.s-edit-text {
    border-radius: var(--s-r-sm);
    outline: none;
    cursor: text;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    transition: box-shadow var(--s-t-fast), background var(--s-t-fast);
}
.s-edit-text:hover { box-shadow: 0 0 0 2px var(--s-accent-soft), 0 0 0 3px var(--s-accent); }
.s-edit-text.is-editing {
    background: var(--s-surface);
    box-shadow: 0 0 0 3px var(--s-focus), 0 0 0 1.5px var(--s-accent);
}

/* ------------------------------------------------------------
   A4. Contextual floating format toolbar (.s-edit-bubble)
   The dark pill that appears at a text selection (B / I / U / colour …).
   This is the one sanctioned dark surface (== .s-toast / #1c1c1e).
   White icons. Hidden by default; .is-shown reveals + animates in.
   Prototype: .float-tb / .tb-btn / .tb-sep / .tb-swatches (lines 384-410).
   ------------------------------------------------------------ */
.s-edit-bubble {
    position: fixed;
    z-index: 90;
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 5px;
    background: var(--s-edit-pill);
    border-radius: var(--s-r-md);
    box-shadow: var(--s-shadow-lg);
    opacity: 0;
    transform: translateY(6px) scale(0.96);
    pointer-events: none;
    transition: opacity var(--s-t-fast), transform var(--s-t-fast);
}
.s-edit-bubble.is-shown { opacity: 1; transform: none; pointer-events: auto; }
/* little downward caret tying the pill to the selection */
.s-edit-bubble::after {
    content: "";
    position: absolute;
    bottom: -5px;
    left: 50%;
    width: 10px;
    height: 10px;
    background: var(--s-edit-pill);
    border-radius: 2px;
    transform: translateX(-50%) rotate(45deg);
}
.s-edit-bubble--up::after { bottom: auto; top: -5px; }
.s-edit-bubble-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    background: transparent;
    border-radius: var(--s-r-sm);
    color: var(--s-edit-pill-text);
    font-family: inherit;
    font-weight: 700;
    font-size: 0.875rem;
    cursor: pointer;
    transition: background var(--s-t-fast), color var(--s-t-fast);
}
.s-edit-bubble-btn:hover { background: var(--s-edit-pill-hover); color: #fff; }
.s-edit-bubble-btn.is-active { background: var(--s-accent); color: #fff; }
.s-edit-bubble-btn svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2; fill: none; }
/* italic/underline glyph helpers */
.s-edit-bubble-btn i { font-style: normal; }
.s-edit-bubble-btn .u { text-decoration: underline; }
/* an auto-width labelled button (e.g. "Rewrite" with an icon) */
.s-edit-bubble-btn.s-edit-bubble-btn--wide { width: auto; gap: 5px; padding: 0 9px; }
.s-edit-bubble-btn.s-edit-bubble-btn--wide svg { width: 14px; height: 14px; }
.s-edit-bubble-sep { width: 1px; height: 20px; margin: 0 3px; background: var(--s-edit-pill-sep); }
/* inline quick-swatch row inside the bubble (brand colours allowed) */
.s-edit-bubble-swatches { display: flex; gap: 4px; padding: 0 4px; }
.s-edit-bubble-sw {
    width: 20px;
    height: 20px;
    border-radius: var(--s-r-sm);
    border: 2px solid rgba(255, 255, 255, 0.25);
    cursor: pointer;
    transition: transform var(--s-t-fast);
}
.s-edit-bubble-sw:hover { transform: scale(1.15); }

/* ------------------------------------------------------------
   A5. Element mini-toolbar (.s-edit-eltb) — Colour · Duplicate · Delete
   The dark chip-toolbar that floats above a selected free-move element.
   Same dark-pill language as the format bubble.
   Prototype: #elTb / .el-btn / .el-sep / .dotc (lines 559-567).
   ------------------------------------------------------------ */
.s-edit-eltb {
    position: fixed;
    z-index: 90;
    display: none;
    align-items: center;
    gap: 3px;
    padding: 5px;
    background: var(--s-edit-pill);
    border-radius: var(--s-r-md);
    box-shadow: var(--s-shadow-lg);
}
.s-edit-eltb.is-shown { display: flex; }
.s-edit-eltb::after {
    content: "";
    position: absolute;
    bottom: -5px;
    left: 50%;
    width: 10px;
    height: 10px;
    background: var(--s-edit-pill);
    border-radius: 2px;
    transform: translateX(-50%) rotate(45deg);
}
.s-edit-eltb-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 10px;
    border: 0;
    background: transparent;
    border-radius: var(--s-r-sm);
    color: var(--s-edit-pill-text);
    font-family: inherit;
    font-weight: 600;
    font-size: 0.78rem;
    cursor: pointer;
    transition: background var(--s-t-fast), color var(--s-t-fast);
}
.s-edit-eltb-btn:hover { background: var(--s-edit-pill-hover); color: #fff; }
.s-edit-eltb-btn svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2; fill: none; }
/* current-colour dot on the "Colour" action (shows the live element colour
   inline via --dot-c, set by JS — can be a brand colour). */
.s-edit-eltb-dot {
    width: 14px;
    height: 14px;
    border-radius: var(--s-r-sm);
    background: var(--dot-c, #fff);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}
.s-edit-eltb-sep { width: 1px; height: 18px; margin: 0 2px; background: var(--s-edit-pill-sep); }

/* ------------------------------------------------------------
   A6. Selection box + resize handles + live size badge
   The marching box around a selected free-move element (1.5px ink),
   8 resize handles (white fill, ink border; N/S hidden so the corner +
   E/W handles do the work), and the live "W × H" badge while sizing.
   Prototype: #selbox / .handle / #selSize (lines 529-545).
   ------------------------------------------------------------ */
.s-edit-selbox {
    position: fixed;
    z-index: 88;
    display: none;
    border: 1.5px solid var(--s-accent);
    border-radius: 4px;
    pointer-events: none;
}
.s-edit-selbox.is-shown { display: block; }
.s-edit-handle {
    position: absolute;
    width: 12px;
    height: 12px;
    background: #fff;
    border: 1.5px solid var(--s-accent);
    border-radius: 3px;
    box-shadow: var(--s-shadow-xs);
    pointer-events: auto;
    transform: translate(-50%, -50%);
    transition: transform var(--s-t-fast);
}
.s-edit-handle:hover { transform: translate(-50%, -50%) scale(1.28); }
/* invisible larger hit-target so the small handle is easy to grab */
.s-edit-handle::before { content: ""; position: absolute; inset: -10px; }
.s-edit-handle[data-h="nw"] { left: 0;    top: 0;    cursor: nwse-resize; }
.s-edit-handle[data-h="n"]  { left: 50%;  top: 0;    cursor: ns-resize; }
.s-edit-handle[data-h="ne"] { left: 100%; top: 0;    cursor: nesw-resize; }
.s-edit-handle[data-h="e"]  { left: 100%; top: 50%;  cursor: ew-resize; }
.s-edit-handle[data-h="se"] { left: 100%; top: 100%; cursor: nwse-resize; }
.s-edit-handle[data-h="s"]  { left: 50%;  top: 100%; cursor: ns-resize; }
.s-edit-handle[data-h="sw"] { left: 0;    top: 100%; cursor: nesw-resize; }
.s-edit-handle[data-h="w"]  { left: 0;    top: 50%;  cursor: ew-resize; }
/* N/S hidden: free-move text resizes from corners + sides, not top/bottom */
.s-edit-handle[data-h="n"], .s-edit-handle[data-h="s"] { display: none; }
/* live dimensions badge, shown only while actively sizing (.is-sizing) */
.s-edit-size {
    position: absolute;
    left: 50%;
    bottom: -27px;
    transform: translateX(-50%);
    display: none;
    padding: 2px 8px;
    background: var(--s-accent);
    color: var(--s-on-accent);
    border-radius: var(--s-r-sm);
    box-shadow: var(--s-shadow-xs);
    font-size: 0.69rem;
    font-weight: 700;
    white-space: nowrap;
}
.s-edit-selbox.is-sizing .s-edit-size { display: block; }

/* ------------------------------------------------------------
   A7. Snap / alignment guides (.s-edit-guide)
   White-core lines with a thin dark ring so they read on any canvas
   (dark hero/slide or white doc). Variants: vertical/horizontal line,
   centre dot, distance/measure badge (dark pill), and an equal-spacing
   box. Ctrl/Cmd-bypass is JS-side; this is purely the visual.
   Prototype: #guides / .gline / .gdot / .gbadge / .gspace (lines 547-557).
   ------------------------------------------------------------ */
.s-edit-guide-host {
    position: fixed;
    inset: 0;
    z-index: 87;
    overflow: hidden;
    pointer-events: none;
}
.s-edit-guide {
    position: absolute;
    background: var(--s-edit-guide-core);
    box-shadow: var(--s-edit-guide-ring);
}
.s-edit-guide.s-edit-guide--v { width: 1px; }
.s-edit-guide.s-edit-guide--h { height: 1px; }
.s-edit-guide-dot {
    position: absolute;
    width: 6px;
    height: 6px;
    border-radius: var(--s-r-pill);
    background: var(--s-edit-guide-core);
    box-shadow: var(--s-edit-guide-ring);
    transform: translate(-50%, -50%);
}
.s-edit-guide-badge {
    position: absolute;
    padding: 1px 6px;
    background: var(--s-edit-pill);
    color: #fff;
    border-radius: 5px;
    box-shadow: var(--s-shadow-xs);
    font-size: 0.625rem;
    font-weight: 700;
    white-space: nowrap;
    transform: translate(-50%, -50%);
}
.s-edit-guide-space {
    position: absolute;
    border: 1px solid var(--s-edit-guide-core);
    box-shadow: var(--s-edit-guide-ring);
}

/* ------------------------------------------------------------
   A8. Brand-aware colour picker (.s-edit-picker)
   Floating popover: chrome is ink; the ONLY brand-coloured bit is the
   "From your branding" row, which previews the agent's own colours
   (via --s-brand / --s-brand-2, page-overridable). Custom hex input +
   eyedropper. Contrast warning uses --s-warn (functional state).
   Prototype: #picker + .pk-* (lines 569-595).
   ------------------------------------------------------------ */
.s-edit-picker {
    position: fixed;
    z-index: 93;
    display: none;
    width: 248px;
    padding: 12px;
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-r-md);
    box-shadow: var(--s-shadow-lg);
}
.s-edit-picker.is-shown { display: block; }
/* "From your branding" header row — the sanctioned brand-colour swatch */
.s-edit-picker-from {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 11px;
    font-size: 0.656rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--s-text-3);
}
.s-edit-picker-from .s-edit-picker-brandchip {
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    border-radius: var(--s-r-sm);
    /* brand gold here is intentional + page-overridable — it literally
       previews the agent's own brand colour, the one allowed exception. */
    background: linear-gradient(135deg, var(--s-brand), var(--s-brand-2));
}
.s-edit-picker-row + .s-edit-picker-row { margin-top: 13px; }
.s-edit-picker-label {
    margin-bottom: 7px;
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--s-text-3);
}
.s-edit-picker-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; }
.s-edit-picker-swatch {
    width: 28px;
    height: 28px;
    border-radius: var(--s-r-sm);
    cursor: pointer;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.14);
    transition: transform var(--s-t-fast);
}
.s-edit-picker-swatch:hover { transform: scale(1.13); }
.s-edit-picker-swatch.is-selected { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.14), 0 0 0 2px var(--s-accent); }
.s-edit-picker-empty { font-size: 0.719rem; font-style: italic; color: var(--s-text-3); }
/* custom-colour drawer (hex + eyedropper) */
.s-edit-picker-custom { margin-top: 13px; padding-top: 12px; border-top: 1px solid var(--s-border); }
.s-edit-picker-cbtn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    width: 100%;
    height: 34px;
    background: transparent;
    border: 1px dashed var(--s-border-strong);
    border-radius: var(--s-r-sm);
    color: var(--s-text-2);
    font-family: inherit;
    font-weight: 600;
    font-size: 0.78rem;
    cursor: pointer;
    transition: background var(--s-t-fast), border-color var(--s-t-fast), color var(--s-t-fast);
}
.s-edit-picker-cbtn:hover { background: var(--s-surface-2); border-color: var(--s-accent); color: var(--s-accent); }
.s-edit-picker-cbtn svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2; fill: none; }
.s-edit-picker-cwrap { display: none; align-items: center; gap: 8px; margin-top: 10px; }
.s-edit-picker-cwrap.is-shown { display: flex; }
.s-edit-picker-cwrap input[type="color"] {
    width: 38px;
    height: 34px;
    padding: 2px;
    background: none;
    border: 1px solid var(--s-border-strong);
    border-radius: var(--s-r-sm);
    cursor: pointer;
}
.s-edit-picker-hex {
    flex: 1;
    min-width: 0;
    height: 34px;
    padding: 0 10px;
    border: 1px solid var(--s-border-strong);
    border-radius: var(--s-r-sm);
    background: var(--s-surface);
    color: var(--s-text);
    font-family: inherit;
    font-size: 0.81rem;
    font-weight: 600;
    outline: none;
    transition: border-color var(--s-t-fast), box-shadow var(--s-t-fast);
}
.s-edit-picker-hex:focus { border-color: var(--s-accent); box-shadow: 0 0 0 3px var(--s-focus); }
.s-edit-picker-eye {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: var(--s-surface);
    border: 1px solid var(--s-border-strong);
    border-radius: var(--s-r-sm);
    color: var(--s-text-2);
    cursor: pointer;
    transition: background var(--s-t-fast), color var(--s-t-fast), border-color var(--s-t-fast);
}
.s-edit-picker-eye:hover { background: var(--s-surface-3); color: var(--s-accent); border-color: var(--s-accent); }
.s-edit-picker-eye svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2; fill: none; }
/* WCAG contrast warning — functional state, so --s-warn (not ink). */
.s-edit-picker-contrast {
    display: none;
    margin-top: 11px;
    padding: 8px 10px;
    background: var(--s-warn-soft);
    border: 1px solid var(--s-warn-border);
    border-radius: var(--s-r-sm);
    color: var(--s-warn);
    font-size: 0.719rem;
    font-weight: 600;
    line-height: 1.45;
}
.s-edit-picker-contrast.is-shown { display: block; }
.s-edit-picker-contrast a { color: var(--s-accent); font-weight: 700; text-decoration: underline; cursor: pointer; }

/* ------------------------------------------------------------
   A9. First-run coachmark / spotlight (.s-edit-coach)
   The teaching overlay: a dimming veil, a spotlight ring drawn around
   the focused element, and a card with a step badge, copy, progress
   dots, Skip + Next. All ink. Gated by a per-surface localStorage key
   (JS-side); this is just the chrome.
   Prototype: .coach-veil / .coach / .spotlight (lines 414-452).
   ------------------------------------------------------------ */
.s-edit-coach-veil {
    position: fixed;
    inset: 0;
    z-index: 95;
    background: rgba(10, 10, 10, 0.28);
    -webkit-backdrop-filter: blur(1px);
    backdrop-filter: blur(1px);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--s-t);
}
.s-edit-coach-veil.is-shown { opacity: 1; pointer-events: auto; }
/* spotlight ring around the element being taught (box-shadow doubles as
   the ring + the dimmed surround). Position/size JS-driven. */
.s-edit-coach-spot {
    position: fixed;
    z-index: 95;
    border-radius: var(--s-r-md);
    pointer-events: none;
    box-shadow: 0 0 0 3px var(--s-accent), 0 0 0 9999px rgba(10, 10, 10, 0.28);
    opacity: 0;
    transition: opacity var(--s-t), all var(--s-t);
}
.s-edit-coach-spot.is-shown { opacity: 1; }
.s-edit-coach {
    position: fixed;
    z-index: 96;
    max-width: 312px;
    padding: 20px 22px;
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-r-lg);
    box-shadow: var(--s-shadow-lg);
    opacity: 0;
    transform: translateY(10px) scale(0.97);
    pointer-events: none;
    transition: opacity var(--s-t), transform var(--s-t);
}
.s-edit-coach.is-shown { opacity: 1; transform: none; pointer-events: auto; }
.s-edit-coach-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 12px;
    padding: 5px 11px;
    background: var(--s-accent-soft);
    border-radius: var(--s-r-pill);
    color: var(--s-accent);
    font-size: 0.688rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.s-edit-coach h4 {
    margin: 0 0 6px;
    font-size: 1rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--s-text);
}
.s-edit-coach p { margin: 0 0 16px; font-size: 0.844rem; color: var(--s-text-2); line-height: 1.55; }
.s-edit-coach-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.s-edit-coach-dots { display: flex; gap: 6px; }
.s-edit-coach-dot {
    width: 7px;
    height: 7px;
    border-radius: var(--s-r-pill);
    background: var(--s-border-strong);
    transition: background var(--s-t-fast), width var(--s-t-fast);
}
.s-edit-coach-dot.is-on { width: 18px; background: var(--s-accent); }
.s-edit-coach-btns { display: flex; align-items: center; gap: 8px; }
.s-edit-coach-skip {
    padding: 8px 10px;
    background: transparent;
    border: 0;
    border-radius: var(--s-r-sm);
    color: var(--s-text-3);
    font-family: inherit;
    font-weight: 600;
    font-size: 0.81rem;
    cursor: pointer;
    transition: background var(--s-t-fast), color var(--s-t-fast);
}
.s-edit-coach-skip:hover { background: var(--s-surface-2); color: var(--s-text-2); }
.s-edit-coach-next {
    padding: 9px 16px;
    background: var(--s-accent);
    border: 0;
    border-radius: var(--s-r-pill);
    color: var(--s-on-accent);
    font-family: inherit;
    font-weight: 700;
    font-size: 0.81rem;
    cursor: pointer;
    transition: background var(--s-t-fast), transform var(--s-t-fast);
}
.s-edit-coach-next:hover { background: var(--s-accent-hover); transform: translateY(-1px); }
.s-edit-coach-next:active { transform: translateY(0) scale(0.98); }

/* ------------------------------------------------------------
   A10. Filmstrip — slide / section thumbnail strip (.s-edit-filmstrip)
   A row of thumbnails with a selected ring, hover-lift, an index badge,
   and a drag affordance (grab cursor + a grip that fades in on hover).
   Used for social slides + listing-section reorder.
   Prototype: .filmstrip / .film-thumb / .film-thumb .ix (lines 692-705),
   drag affordance modelled on the prototype's .drag-handle (lines 205-215).
   ------------------------------------------------------------ */
.s-edit-filmstrip {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
}
.s-edit-filmstrip-thumb {
    position: relative;
    width: 64px;
    height: 80px;
    border: 2px solid transparent;
    border-radius: var(--s-r-sm);
    overflow: hidden;
    background: var(--s-surface-3);
    cursor: pointer;
    transition: border-color var(--s-t-fast), transform var(--s-t-fast), box-shadow var(--s-t-fast);
}
.s-edit-filmstrip-thumb:hover { transform: translateY(-2px); box-shadow: var(--s-shadow-sm); }
.s-edit-filmstrip-thumb.is-selected { border-color: var(--s-accent); }
.s-edit-filmstrip-thumb img,
.s-edit-filmstrip-thumb .s-edit-filmstrip-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.s-edit-filmstrip-ix {
    position: absolute;
    right: 5px;
    bottom: 4px;
    padding: 0 5px;
    background: rgba(10, 10, 10, 0.55);
    border-radius: 5px;
    color: #fff;
    font-size: 0.625rem;
    font-weight: 800;
}
/* drag affordance: a grip pill, hidden until hover, grab cursor */
.s-edit-filmstrip-thumb.is-draggable { cursor: grab; }
.s-edit-filmstrip-thumb.is-draggable:active,
.s-edit-filmstrip-thumb.is-dragging { cursor: grabbing; }
.s-edit-filmstrip-thumb.is-dragging { opacity: 0.55; box-shadow: var(--s-shadow-lg); }
.s-edit-filmstrip-grip {
    position: absolute;
    top: 4px;
    left: 50%;
    transform: translateX(-50%) translateY(-4px);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 16px;
    background: rgba(10, 10, 10, 0.55);
    border-radius: 5px;
    color: #fff;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--s-t-fast), transform var(--s-t-fast);
}
.s-edit-filmstrip-thumb:hover .s-edit-filmstrip-grip { opacity: 1; transform: translateX(-50%); }
.s-edit-filmstrip-grip svg { width: 13px; height: 13px; stroke: currentColor; stroke-width: 2; fill: none; }

/* ============================================================
   GROUP B — INPUT COMPONENTS
   The intake family (forms research §3). suite.css already ships
   .s-field / .s-input / .s-select / .s-segmented; these are the FIVE
   additive components it is missing.
   ============================================================ */

/* ------------------------------------------------------------
   B1. Choice card + grid (.s-choice-card / .s-choice-grid)
   The rich "pick one of N" card (icon + title + sub + selected dot).
   Generalises the four bespoke card-selectors (format / buyer-type /
   ps-type / type-card) into one. Default 3-col, --cols override,
   collapses to 1 under 600px. Adds the :focus-visible ring the bespoke
   versions were missing (forms research #1, #2).
   Prototype: .s-choice-grid / .s-choice-card + states (lines 762-775, 807).
   ------------------------------------------------------------ */
.s-choice-grid {
    display: grid;
    grid-template-columns: repeat(var(--cols, 3), 1fr);
    gap: 12px;
}
.s-choice-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 5px;
    padding: 16px 15px;
    background: var(--s-surface);
    border: 1.5px solid var(--s-border-strong);
    border-radius: var(--s-r-md);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color var(--s-t-fast), box-shadow var(--s-t-fast), transform var(--s-t-fast);
}
.s-choice-card:hover { border-color: var(--s-text-3); transform: translateY(-2px); box-shadow: var(--s-shadow-sm); }
.s-choice-card:focus-visible {
    outline: none;
    border-color: var(--s-accent);
    box-shadow: 0 0 0 3px var(--s-focus);
}
.s-choice-card svg { width: 20px; height: 20px; stroke: var(--s-text); stroke-width: 2; fill: none; }
.s-choice-title { font-size: 0.875rem; font-weight: 700; color: var(--s-text); }
.s-choice-sub { font-size: 0.719rem; color: var(--s-text-3); line-height: 1.4; }
/* selected = ink border + filled dot top-right (forms research §3.0 "selected") */
.s-choice-card.is-selected { border-color: var(--s-accent); box-shadow: 0 0 0 3px var(--s-focus); }
.s-choice-card.is-selected::after {
    content: "";
    position: absolute;
    top: 12px;
    right: 12px;
    width: 11px;
    height: 11px;
    border-radius: var(--s-r-pill);
    background: var(--s-accent);
}
.s-choice-card:disabled,
.s-choice-card.is-disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
    border-color: var(--s-border-strong);
}
@media (max-width: 600px) { .s-choice-grid { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------
   B2. Dropzone + file list (.s-dropzone / .s-filelist / .s-file)
   The ONE dropzone the kit was missing — folds in all four bespoke
   ones and standardises the drag-state on .is-dragover (kills the
   .drag-over vs .drop-zone-hover split). States: rest (dashed), hover,
   .is-dragover (ink border + surface-2 + focus glow), .is-invalid flash.
   The label IS the click-to-browse target (keyboard-focusable). Always
   pair with a real <input type=file> + an explicit Browse fallback.
   (forms research §3.4, #7.) Prototype: .s-dropzone / .s-filelist /
   .s-file + states (lines 776-794).
   ------------------------------------------------------------ */
.s-dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 28px 20px;
    background: var(--s-surface);
    border: 1.5px dashed var(--s-border-strong);
    border-radius: var(--s-r-md);
    text-align: center;
    cursor: pointer;
    transition: border-color var(--s-t-fast), background var(--s-t-fast), box-shadow var(--s-t-fast);
}
.s-dropzone:hover { border-color: var(--s-text-3); }
.s-dropzone:focus-within { border-color: var(--s-accent); box-shadow: 0 0 0 3px var(--s-focus); }
.s-dropzone.is-dragover {
    border-color: var(--s-accent);
    background: var(--s-surface-2);
    box-shadow: 0 0 0 4px var(--s-focus);
}
/* rejected file type — a brief danger flash (toggle .is-invalid in JS) */
.s-dropzone.is-invalid {
    border-color: var(--s-danger-border);
    background: var(--s-danger-soft);
    animation: s-dropzone-flash var(--s-t) ease;
}
@keyframes s-dropzone-flash {
    0%, 100% { background: var(--s-surface); }
    50% { background: var(--s-danger-soft); }
}
.s-dropzone-ico { width: 34px; height: 34px; stroke: var(--s-text-3); stroke-width: 1.7; fill: none; }
.s-dropzone-title { font-size: 0.875rem; font-weight: 700; color: var(--s-text); }
.s-dropzone-sub { font-size: 0.75rem; color: var(--s-text-3); }
.s-dropzone-browse { margin-top: 4px; }

/* Compact variant — the inline edit-chat "drop more files" target. */
.s-dropzone-compact { flex-direction: row; gap: 10px; padding: 12px 14px; text-align: left; }
.s-dropzone-compact .s-dropzone-ico { width: 22px; height: 22px; }
.s-dropzone-compact .s-dropzone-title { font-size: 0.8rem; }

/* Tile variant — branding's square headshot/logo uploads (1:1). The
   image preview fills it via JS (style.display, NOT the hidden attr). */
.s-dropzone-tile {
    aspect-ratio: 1 / 1;
    justify-content: center;
    gap: 6px;
    padding: 16px;
    position: relative;
    overflow: hidden;
}
.s-dropzone-tile .s-dropzone-ico { width: 26px; height: 26px; }
.s-dropzone-tile .s-dropzone-title { font-size: 0.78rem; }
.s-dropzone-tile-preview {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: calc(var(--s-r-md) - 2px);
}

/* File rows under the dropzone: name · size · remove. */
.s-filelist {
    list-style: none;
    margin: 10px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 7px;
}
.s-file {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 11px;
    background: var(--s-surface-2);
    border: 1px solid var(--s-border);
    border-radius: var(--s-r-sm);
    font-size: 0.81rem;
    color: var(--s-text-2);
    /* ~100ms settle on insert (forms research #7) */
    animation: s-file-in var(--s-t-fast) ease;
}
@keyframes s-file-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}
.s-file > svg { flex: 0 0 auto; width: 15px; height: 15px; stroke: var(--s-text-3); stroke-width: 2; fill: none; }
.s-file-name {
    flex: 1;
    min-width: 0;
    font-weight: 600;
    color: var(--s-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.s-file-size { font-size: 0.719rem; color: var(--s-text-3); }
.s-file-remove {
    display: flex;
    flex: 0 0 auto;
    color: var(--s-text-3);
    cursor: pointer;
    transition: color var(--s-t-fast);
}
.s-file-remove:hover { color: var(--s-danger); }
.s-file-remove svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2; fill: none; }

/* ------------------------------------------------------------
   B3. Stepper + progress bar (.s-stepper / .s-step / .s-progress)
   Unifies the three progress UIs (import stepper, onboarding bar, the
   implicit step fades). .s-step states: upcoming (muted), .is-current
   (ink + ring), .is-done (ink + check). A connector line runs between
   numbered markers. .s-progress is the slim track + ink fill (width
   JS-driven) for compact contexts. (forms research §3.5, #6.)
   ------------------------------------------------------------ */
.s-stepper { width: 100%; }
.s-stepper ol {
    display: flex;
    align-items: center;
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}
.s-step {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 0 auto;
    font-size: 0.81rem;
    font-weight: 600;
    color: var(--s-text-3);
}
/* numbered circular marker before each step label */
.s-step::before {
    content: counter(s-step-i);
    counter-increment: s-step-i;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    flex: 0 0 auto;
    border-radius: var(--s-r-pill);
    background: var(--s-surface-3);
    border: 1.5px solid var(--s-border-strong);
    color: var(--s-text-3);
    font-size: 0.75rem;
    font-weight: 700;
    transition: background var(--s-t-fast), border-color var(--s-t-fast), color var(--s-t-fast);
}
.s-stepper ol { counter-reset: s-step-i; }
/* Connector line between markers. Markup places an .s-step-line element
   (e.g. <li class="s-step-line" aria-hidden="true"></li>) between each
   pair of <li class="s-step">; it flex-grows to fill the gap and turns
   ink once the preceding step is done. */
.s-step-line {
    flex: 1 1 auto;
    height: 1.5px;
    min-width: 18px;
    margin: 0 0.5rem;
    background: var(--s-border-strong);
    transition: background var(--s-t-fast);
}
.s-step.is-current { color: var(--s-text); }
.s-step.is-current::before {
    background: var(--s-accent);
    border-color: var(--s-accent);
    color: var(--s-on-accent);
    box-shadow: 0 0 0 3px var(--s-focus);
}
.s-step.is-done { color: var(--s-text); }
.s-step.is-done::before {
    /* checkmark replaces the number on a completed step */
    content: "";
    background: var(--s-accent);
    border-color: var(--s-accent);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
}
.s-step.is-done + .s-step .s-step-line,
.s-step.is-done .s-step-line { background: var(--s-accent); }

/* slim progress track + ink fill (compact / onboarding) */
.s-progress {
    width: 100%;
    height: 6px;
    background: var(--s-surface-3);
    border-radius: var(--s-r-pill);
    overflow: hidden;
}
.s-progress-fill {
    height: 100%;
    width: 0;
    background: var(--s-accent);
    border-radius: var(--s-r-pill);
    transition: width var(--s-t);
}

/* step panels (one logical chunk per panel; fade/slide in on activate) */
.s-step-panel { display: none; }
.s-step-panel.is-active { display: block; animation: s-step-panel-in var(--s-t) var(--s-t-fast); }
@keyframes s-step-panel-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------
   B4. Inline validation (.s-field-msg + .s-field.is-invalid)
   The message line under a field (small, danger, with leading-icon
   space) + the invalid border state. Colour is ALWAYS paired with icon
   + text, never red-only (forms research #3). Announce politely via
   aria-live on the message element (markup-side).
   ------------------------------------------------------------ */
.s-field-msg {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin-top: 6px;
    font-size: 0.719rem;
    font-weight: 600;
    color: var(--s-danger);
    line-height: 1.45;
}
.s-field-msg svg {
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    margin-top: 1px;
    stroke: currentColor;
    stroke-width: 2;
    fill: none;
}
/* recolour the control's border when its field is flagged invalid */
.s-field.is-invalid .s-input,
.s-field.is-invalid .s-textarea,
.s-field.is-invalid .s-select {
    border-color: var(--s-danger-border);
}
.s-field.is-invalid .s-input:focus,
.s-field.is-invalid .s-textarea:focus,
.s-field.is-invalid .s-select:focus {
    border-color: var(--s-danger);
    box-shadow: 0 0 0 3px var(--s-danger-soft);
}

/* ------------------------------------------------------------
   B5. Shake (.s-shake) — the "you missed this" nudge
   Promoted from the prototype's format-shake. Used on a required-but-
   empty control/group on submit (don't block typing — just nudge).
   Prototype: @keyframes shake / .s-shake (lines 805-806).
   ------------------------------------------------------------ */
@keyframes s-shake {
    10%, 90% { transform: translateX(-1px); }
    20%, 80% { transform: translateX(2px); }
    30%, 50%, 70% { transform: translateX(-4px); }
    40%, 60% { transform: translateX(4px); }
}
.s-shake { animation: s-shake 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; }

/* ============================================================
   REDUCED MOTION — mandatory guard
   Neutralise every animation/transition introduced by this layer for
   users who prefer reduced motion. suite.css guards .suite descendants;
   this guards the .s-edit-* / input components by class regardless of
   ancestor, so the editor chrome (which may render at the document root
   / in an overlay outside .suite) is covered too.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    .s-edit-seg, .s-edit-seg button, .s-edit-seg-thumb,
    .s-edit-banner-x, .s-edit-hover, .s-edit-hover::after, .s-edit-text,
    .s-edit-bubble, .s-edit-bubble-btn, .s-edit-bubble-sw,
    .s-edit-eltb, .s-edit-eltb-btn,
    .s-edit-handle, .s-edit-size,
    .s-edit-picker-swatch, .s-edit-picker-cbtn, .s-edit-picker-hex, .s-edit-picker-eye,
    .s-edit-coach-veil, .s-edit-coach-spot, .s-edit-coach, .s-edit-coach-dot,
    .s-edit-coach-skip, .s-edit-coach-next,
    .s-edit-filmstrip-thumb, .s-edit-filmstrip-grip,
    .s-choice-card, .s-dropzone, .s-file, .s-file-remove,
    .s-step::before, .s-step-line, .s-progress-fill, .s-step-panel.is-active,
    .s-shake, .s-dropzone.is-invalid {
        transition-duration: 0.001ms !important;
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
    }
}

/* ============================================================
   MEDIA / RESULT PATTERNS  (promoted from the Photo Studio
   prototype — docs/DESIGN-SYSTEM.md §4). One before/after slider,
   one staged-loading state, one result grid, one lightbox, shared
   by every tool. Chrome stays monochrome ink; the media carries
   all the colour.
   ============================================================ */

/* --- Before/After compare slider --- */
.s-compare { position:relative; aspect-ratio:3/2; background:#000; overflow:hidden;
    cursor:ew-resize; user-select:none; touch-action:none; border-radius:var(--s-r-lg); }
.s-compare img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; pointer-events:none; }
.s-compare-after { z-index:1; }
/* before is a full-size overlay revealed by clip-path so both images stay pixel-aligned */
.s-compare-before { z-index:2; clip-path:inset(0 50% 0 0); }
.s-compare.is-animate .s-compare-before { transition:clip-path .5s cubic-bezier(.4,0,.2,1); }
.s-compare-lab { position:absolute; top:12px; z-index:4; font-family:var(--s-mono); font-size:10.5px;
    letter-spacing:.14em; text-transform:uppercase; color:#fff; background:rgba(10,10,10,.55);
    padding:4px 9px; border-radius:var(--s-r-pill); }
.s-compare-lab.is-b { left:12px; } .s-compare-lab.is-a { right:12px; }
.s-compare-handle { position:absolute; top:0; bottom:0; z-index:3; width:40px; margin-left:-20px;
    left:50%; display:grid; place-items:center; pointer-events:none; }
.s-compare-bar { position:absolute; top:0; bottom:0; width:2px; background:rgba(255,255,255,.9);
    box-shadow:0 0 0 1px rgba(10,10,10,.15); }
.s-compare-knob { width:42px; height:42px; border-radius:50%; background:#fff; box-shadow:var(--s-shadow-md);
    display:grid; place-items:center; color:var(--s-text); transition:transform var(--s-t-fast); }
.s-compare:hover .s-compare-knob { transform:scale(1.06); }
.s-compare-knob svg { width:20px; height:20px; }
/* disclosure stamp burned into the AFTER side */
.s-compare-stamp { position:absolute; right:12px; bottom:12px; z-index:4; display:flex; align-items:center;
    gap:5px; font-size:10.5px; font-weight:600; color:#fff; background:rgba(10,10,10,.5); padding:5px 9px;
    border-radius:7px; letter-spacing:.01em; }

/* --- Staged "working" checklist --- */
.s-stages { display:flex; flex-direction:column; gap:9px; }
.s-stage { display:flex; align-items:center; gap:9px; font-size:12.5px; color:var(--s-text-3); transition:color var(--s-t); }
.s-stage-mk { width:16px; height:16px; border-radius:50%; border:1.5px solid var(--s-border-strong);
    flex:0 0 16px; display:grid; place-items:center; transition:all var(--s-t); }
.s-stage-mk svg { width:10px; height:10px; opacity:0; color:#fff; }
.s-stage.is-done { color:var(--s-text); } .s-stage.is-done .s-stage-mk { background:var(--s-text); border-color:var(--s-text); }
.s-stage.is-done .s-stage-mk svg { opacity:1; }
.s-stage.is-active { color:var(--s-text); font-weight:600; }
.s-stage.is-active .s-stage-mk { border-color:var(--s-text); box-shadow:0 0 0 4px var(--s-focus); }
.s-stages-bar { height:5px; border-radius:var(--s-r-pill); background:var(--s-surface-3); overflow:hidden; margin-top:13px; }
.s-stages-bar i { display:block; height:100%; width:0; background:var(--s-text); border-radius:var(--s-r-pill);
    transition:width .6s cubic-bezier(.4,0,.2,1); }
.s-shimmer { background:linear-gradient(110deg,#f1f1f1 30%,#e6e6e6 50%,#f1f1f1 70%); background-size:220% 100%;
    animation:s-shimmer 1.5s linear infinite; }
@keyframes s-shimmer { to { background-position:-220% 0; } }

/* --- Result grid + hover-alive cards --- */
.s-result-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:18px; }
@media (max-width:820px) { .s-result-grid { grid-template-columns:repeat(2,1fr); } }
@media (max-width:560px) { .s-result-grid { grid-template-columns:1fr; } }
.s-result-card { background:var(--s-surface); border:1px solid var(--s-border); border-radius:var(--s-r-lg);
    overflow:hidden; box-shadow:var(--s-shadow-xs); transition:transform var(--s-t),box-shadow var(--s-t),border-color var(--s-t); }
.s-result-card:hover { transform:translateY(-4px); box-shadow:var(--s-shadow-lg); border-color:var(--s-border-strong); }
.s-result-media { position:relative; aspect-ratio:3/2; overflow:hidden; background:var(--s-surface-3); }
.s-result-media img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
    transition:transform .5s cubic-bezier(.2,.7,.2,1); }
.s-result-card:hover .s-result-media img { transform:scale(1.04); }
.s-result-badge { position:absolute; left:10px; top:10px; z-index:4; display:flex; align-items:center; gap:5px;
    font-size:10px; font-weight:600; color:#fff; background:rgba(10,10,10,.5); padding:4px 8px; border-radius:var(--s-r-pill); }
.s-result-hov { position:absolute; left:0; right:0; bottom:0; z-index:4; padding:30px 12px 12px;
    background:linear-gradient(to top,rgba(10,10,10,.62),transparent); display:flex; gap:8px;
    opacity:0; transform:translateY(8px); transition:opacity var(--s-t),transform var(--s-t); }
.s-result-card:hover .s-result-hov { opacity:1; transform:translateY(0); }
.s-result-meta { padding:11px 13px; display:flex; align-items:center; gap:8px; }
.s-result-meta .nm { font-size:13px; font-weight:600; }
.s-result-meta .tag { font-family:var(--s-mono); font-size:10.5px; color:var(--s-text-3); margin-left:auto; }

/* --- Lightbox --- */
.s-lightbox { position:fixed; inset:0; z-index:100; background:rgba(10,10,10,.62);
    -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); display:none; align-items:center;
    justify-content:center; padding:26px; }
.s-lightbox.is-open { display:flex; animation:s-fade .25s ease both; }
.s-lightbox-panel { background:var(--s-surface); border-radius:var(--s-r-xl); width:min(960px,100%);
    max-height:92vh; overflow:hidden; box-shadow:var(--s-shadow-lg); display:flex; flex-direction:column; }
.s-lightbox-head { display:flex; align-items:center; gap:12px; padding:15px 18px; border-bottom:1px solid var(--s-border); }
.s-lightbox-body { padding:18px; overflow-y:auto; }
.s-lightbox-foot { display:flex; gap:10px; padding:14px 18px; border-top:1px solid var(--s-border); align-items:center; }
@keyframes s-fade { from { opacity:0; } to { opacity:1; } }

@media (prefers-reduced-motion: reduce) {
    .s-compare.is-animate .s-compare-before, .s-compare-knob, .s-result-card,
    .s-result-media img, .s-result-hov, .s-stage, .s-stage-mk, .s-stages-bar i,
    .s-shimmer, .s-lightbox.is-open {
        transition-duration: 0.001ms !important;
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
    }
}
