/* Autoclick landing — HTML panel replica, feature-card connector arrows, and
   the self-playing setup demo. Cosmic-themed: consumes var(--qa-*) tokens
   only (see theme.css), no hardcoded brand colors. Linked only by
   autoclick_landing.html. All motion is disabled under prefers-reduced-motion
   (the JS also renders a static end-state instead of animating). */

/* Simple header (no app-menu dropdown): keep the 2 nav links visible on mobile,
   since there's no dropdown to collapse them into. Higher specificity than
   theme.css's `@media(max-width:820px){.cosmic .qa-nav{display:none}}`. */
@media (max-width: 820px) {
    .cosmic .qa-header--simple .qa-nav { display: flex; }
}

/* Page-scoped boost of the shared .qa-stars twinkle (theme.css): same class,
   same specificity as `.cosmic .qa-stars` (two classes each) so this later
   stylesheet wins the density/brightness properties by source order, while
   the shared `qa-tw` keyframe (theme.css, unaffected here) still animates
   opacity on top. Colors stay on var(--qa-*) tokens. */
.qa-stars.ac-stars-boost {
    background-size: 260px 260px;
    opacity: .9;
    background-image:
        radial-gradient(1.5px 1.5px at 15% 25%, var(--qa-ink), transparent),
        radial-gradient(1.5px 1.5px at 65% 55%, var(--qa-cyan), transparent),
        radial-gradient(2px 2px at 35% 80%, var(--qa-ink), transparent),
        radial-gradient(1.5px 1.5px at 85% 15%, var(--qa-violet), transparent),
        radial-gradient(1.5px 1.5px at 50% 10%, var(--qa-cyan), transparent),
        radial-gradient(2px 2px at 5% 65%, var(--qa-ink), transparent),
        radial-gradient(1.5px 1.5px at 95% 75%, var(--qa-violet), transparent),
        radial-gradient(1.5px 1.5px at 25% 45%, var(--qa-cyan), transparent);
}

/* ── Panel replica (faithful HTML rebuild of the extension's floating panel) ── */
.ac-replica-wrap { display: flex; justify-content: center; }
.ac-replica {
    width: 300px; max-width: 100%; font-size: 12.5px; color: var(--qa-ink);
    background: linear-gradient(160deg, rgba(40, 20, 80, .55), rgba(20, 10, 40, .55));
    border: 1px solid var(--qa-line); border-radius: var(--qa-radius);
    box-shadow: var(--qa-shadow), 0 0 46px -18px var(--qa-violet); backdrop-filter: blur(10px); overflow: hidden;
    /* Subtle 3D tilt: fixed base angle plus an optional JS mouse-parallax
       delta via --ac-tilt-x/--ac-tilt-y (0deg by default, and never set at
       all under prefers-reduced-motion — see autoclick-demo.js). Child field
       rects (used by the connector-arrow measurement) already reflect this
       transform automatically, since getBoundingClientRect() is post-transform. */
    transform: perspective(1000px) rotateY(calc(-8deg + var(--ac-tilt-x, 0deg))) rotateX(calc(3deg + var(--ac-tilt-y, 0deg)));
    transition: transform .25s ease;
    will-change: transform;
}
.ac-replica-hd { display: flex; align-items: center; gap: 6px; padding: 8px 10px; background: var(--qa-grad); }
.ac-replica-title { flex: 1; font-weight: 700; font-size: 13px; color: #fff; }
.ac-replica-ic {
    min-width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 5px; background: rgba(255, 255, 255, .2); color: #fff; font-size: 11px; font-weight: 700;
}
.ac-replica-bd { padding: 12px; }
.ac-replica-row { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.ac-replica-label { width: 78px; flex: 0 0 auto; color: var(--qa-muted); }
.ac-replica-box, .ac-replica-input {
    flex: 1; padding: 4px 7px; border-radius: 6px; font: inherit; color: var(--qa-ink); min-width: 0;
}
.ac-replica-box { background: rgba(255, 255, 255, .05); }
.ac-replica-input { background: rgba(255, 255, 255, .05); border: 1px solid var(--qa-line); }
.ac-replica-input::placeholder { color: var(--qa-faint); }
.ac-replica-input-flex { flex: 1; }
.ac-replica-sec { font-weight: 700; font-size: 11.5px; color: var(--qa-muted); margin: 10px 0 5px; }
.ac-replica-steps { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.ac-replica-step, .ac-replica-preset, .ac-replica-block {
    display: flex; align-items: center; gap: 6px; padding: 5px 7px; margin-bottom: 6px;
    background: rgba(255, 255, 255, .04); border: 1px solid var(--qa-line-soft); border-radius: 6px;
}
.ac-replica-block input[type="checkbox"] { flex: 0 0 auto; }
.ac-replica-hint { color: var(--qa-muted); font-size: 10.5px; line-height: 1.4; margin: 0 0 4px; }
.ac-replica-mini {
    display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
    flex: 0 0 auto; border-radius: 5px; background: rgba(255, 255, 255, .1); font-size: 11px;
    font-weight: 700; color: var(--qa-ink);
}
.ac-replica-tag { flex: 1; color: var(--qa-muted); font-size: 11.5px; }
.ac-replica-btn { border: 0; border-radius: 6px; padding: 7px 10px; font: inherit; font-weight: 700; cursor: default; color: #fff; }
.ac-replica-btn-add { width: 100%; background: var(--qa-grad); margin-bottom: 8px; }
.ac-replica-btns { display: flex; gap: 6px; }
.ac-replica-btn-start { flex: 1; background: var(--qa-ok); color: #06210f; }
.ac-replica-btn-stop { flex: 1; background: rgba(255, 107, 107, .18); color: var(--qa-bad); border: 1px solid var(--qa-bad); }
.ac-replica-btn-mini, .ac-replica-btn-mini2 { background: rgba(255, 255, 255, .1); color: var(--qa-ink); padding: 5px 9px; font-size: 11.5px; flex: 0 0 auto; }
.ac-replica-badge {
    display: inline-block; padding: 2px 10px; border-radius: var(--qa-radius-pill); font-weight: 700; font-size: 11.5px;
    background: rgba(59, 214, 122, .18); color: var(--qa-ok); border: 1px solid rgba(59, 214, 122, .4);
}
.ac-replica-field { margin-bottom: 4px; }
.ac-replica-field .ac-replica-row { margin-bottom: 4px; }

/* ── Arrow-annotation callouts — one per key field, pointing up at it.
   Also the mobile fallback once the feature-card connector arrows (below)
   are hidden below 768px. ── */
.ac-callout {
    display: flex; align-items: flex-start; gap: 5px; margin: 0 0 10px 4px;
    font-size: 11.5px; line-height: 1.35; color: var(--qa-cyan);
}
.ac-arrow { flex: 0 0 auto; font-weight: 700; }

/* ── Feature cards + connector diagram (desktop: cards point at the panel) ── */
.ac-feature-card {
    border: 1px solid var(--qa-line); border-radius: var(--qa-radius-sm); padding: 16px 18px;
    background: rgba(255, 255, 255, .03);
}
.ac-feature-card h3 { margin: 0 0 4px; font-size: 1.05rem; }
.ac-feature-card p { margin: 0; color: var(--qa-muted); font-size: 0.95rem; line-height: 1.5; }
.ac-connectors { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2; overflow: visible; }
/* Crisp elbow (orthogonal) connectors, not soft curves — a circuit/PCB feel:
   thin stroke, sharp corners (default miter join), small glow, a node dot at
   the card end. Colors alternate cyan/violet per pair for variety. */
.ac-connector-line { fill: none; stroke-width: 1.5; opacity: .65; filter: drop-shadow(0 0 3px currentColor); }
.ac-connector-line--cyan { stroke: var(--qa-cyan); color: var(--qa-cyan); }
.ac-connector-line--violet { stroke: var(--qa-violet); color: var(--qa-violet); }
.ac-connector-arrowhead { opacity: .9; }
.ac-connector-arrowhead--cyan { fill: var(--qa-cyan); }
.ac-connector-arrowhead--violet { fill: var(--qa-violet); }
.ac-connector-node { opacity: .9; }
.ac-connector-node--cyan { fill: var(--qa-cyan); }
.ac-connector-node--violet { fill: var(--qa-violet); }
@media (max-width: 768px) {
    .ac-connectors { display: none; }
}

/* ── "Watch it set up" storyboard shell: 4 steps, one lit at a time ──
   All 3 mini-scenes (webstore / toolbar / page+panel) share the same grid
   cell (grid-area:1/1) so the container auto-sizes to the tallest one and
   nothing jumps around; only the active step's opacity/blur/scale is
   "on" (see .is-active) so the transition between steps reads as a
   focus/dim cross-fade, and at rest exactly one is visible — the simpler
   of the two layouts the spec allowed for. */
.ac-story { display: flex; flex-direction: column; align-items: center; gap: 16px; max-width: 760px; width: 100%; margin: 0 auto; }
/* grid-template-columns:1fr (not the implicit "auto" default) so the single
   column deterministically fills the container's full inline size — an
   auto-sized implicit column can shrink-wrap to its narrowest item instead
   of stretching, which let the wide scene item (and everything under it)
   overflow past this box on narrow viewports. */
.ac-story-stage { position: relative; display: grid; grid-template-columns: 1fr; place-items: center; width: 100%; min-width: 0; }
.ac-story-stage-item {
    grid-area: 1 / 1; position: relative; opacity: 0; filter: blur(6px) saturate(.7); transform: scale(.96);
    pointer-events: none; transition: opacity .35s ease, filter .35s ease, transform .35s ease;
}
.ac-story-stage-item.is-active { opacity: 1; filter: none; transform: scale(1); }
/* Only the page+panel scene needs to fill the stage width (a big browser
   window); the webstore card and toolbar mock stay their own natural size,
   centered via .ac-story-stage's place-items:center. */
.ac-story-stage-item[data-stage="scene"] { width: 100%; min-width: 0; }
.ac-story-caption { font-size: .95rem; font-weight: 600; color: var(--qa-ink); text-align: center; min-height: 1.4em; }
.ac-story-dots { display: flex; gap: 10px; }
/* Real buttons, not decorative dots — reset native button chrome; the
   visible focus ring comes free from theme.css's shared :focus-visible rule. */
.ac-story-dot {
    width: 10px; height: 10px; border-radius: 50%; background: var(--qa-line); border: 0; padding: 0;
    cursor: pointer; transition: background .25s ease, transform .25s ease;
}
.ac-story-dot:hover { background: var(--qa-violet); }
.ac-story-dot.is-active { background: var(--qa-grad); transform: scale(1.25); }

/* ── Step 1: Chrome Web Store install card ── */
.ac-story-webstore {
    display: flex; align-items: center; gap: 12px; padding: 16px 18px; width: 300px; max-width: 100%; box-sizing: border-box;
    border-radius: var(--qa-radius-sm); border: 1px solid var(--qa-line); background: rgba(255, 255, 255, .04);
}
.ac-story-webstore-icon { width: 40px; height: 40px; border-radius: 9px; flex: 0 0 auto; }
.ac-story-webstore-info { flex: 1; min-width: 0; }
.ac-story-webstore-name { font-weight: 700; font-size: 13px; color: var(--qa-ink); }
.ac-story-webstore-sub { font-size: 11px; color: var(--qa-muted); }
.ac-story-webstore-btn {
    flex: 0 0 auto; border: 0; border-radius: 8px; padding: 8px 14px; font-weight: 700; font-size: 12px;
    color: #fff; background: var(--qa-cyan); transition: background .2s ease, color .2s ease;
}
.ac-story-webstore-btn.is-added { background: var(--qa-ok); color: #06210f; }

/* ── Step 2: realistic light Chrome toolbar + "Extensions" dropdown + pin ──
   Intentionally a LIGHT, authentic-Chrome surface (not the cosmic-dark
   theme the other 3 steps use) so it reads as "the real browser", not a
   themed mock. Colors below are therefore Chrome-like light-UI values,
   hardcoded on purpose; only the pinned-state accent and focus ring borrow
   the cosmic palette. The dropdown's layout space is always reserved (shown
   via opacity/transform, never display:none) so the cursor's percentage
   coordinates stay valid whether the menu is open or closed. */
.ac-story-chrome { position: relative; width: 320px; max-width: 100%; box-sizing: border-box; }
.ac-story-chrome-toolbar {
    position: relative; z-index: 2; display: flex; align-items: center; gap: 8px;
    padding: 8px 10px; background: #fdf7f5; border: 1px solid rgba(0, 0, 0, .08);
    border-radius: var(--qa-radius-sm); box-shadow: 0 2px 10px -4px rgba(0, 0, 0, .25);
}
.ac-story-chrome-home { flex: 0 0 auto; font-size: 13px; color: #5f6368; }
.ac-story-chrome-address {
    flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px;
    height: 22px; padding: 0 10px; border-radius: var(--qa-radius-pill);
    background: #fff; border: 1px solid rgba(0, 0, 0, .1);
}
.ac-story-chrome-g { flex: 0 0 auto; font-weight: 700; font-size: 11px; color: #4285f4; }
.ac-story-chrome-url-text {
    flex: 1; min-width: 0; font-size: 10.5px; color: #5f6368;
    overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.ac-story-chrome-star { flex: 0 0 auto; font-size: 13px; color: #5f6368; }
.ac-story-chrome-puzzle { flex: 0 0 auto; border: 0; background: transparent; font-size: 14px; line-height: 1; padding: 3px 5px; border-radius: 6px; color: #5f6368; }
/* Optional thin bookmarks-bar row, purely decorative, for extra realism. */
.ac-story-chrome-bookmarks { display: flex; align-items: center; gap: 10px; padding: 4px 12px 0; }
.ac-story-chrome-bookmarks span { width: 30px; height: 4px; border-radius: 2px; background: rgba(0, 0, 0, .12); }
.ac-story-chrome-menu-wrap { display: flex; justify-content: flex-end; padding: 0 4px; }
.ac-story-chrome-menu {
    width: 250px; max-width: 100%; margin-top: 8px; box-sizing: border-box; overflow: hidden;
    background: #fff; color: #202124; border-radius: 12px; box-shadow: 0 16px 40px -12px rgba(0, 0, 0, .45);
    opacity: 0; transform: scale(.92) translateY(-6px); transform-origin: top right; pointer-events: none;
    transition: opacity .22s ease, transform .22s ease;
}
.ac-story-chrome-menu.is-open { opacity: 1; transform: scale(1) translateY(0); pointer-events: auto; }
.ac-story-chrome-menu-hd { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px 6px; }
.ac-story-chrome-menu-title { font-weight: 700; font-size: 13px; }
.ac-story-chrome-menu-close { font-size: 12px; color: #5f6368; }
.ac-story-chrome-menu-note { padding: 4px 14px 10px; border-bottom: 1px solid rgba(0, 0, 0, .08); }
.ac-story-chrome-menu-note-label { font-weight: 700; font-size: 11.5px; color: #202124; }
.ac-story-chrome-menu-note-hint { margin-top: 2px; font-size: 10.5px; line-height: 1.35; color: #5f6368; }
.ac-story-chrome-menu-row { display: flex; align-items: center; gap: 8px; padding: 10px 14px; }
.ac-story-chrome-menu-icon { width: 20px; height: 20px; border-radius: 5px; flex: 0 0 auto; }
.ac-story-chrome-menu-name { flex: 1; min-width: 0; font-size: 12px; color: #202124; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.ac-story-chrome-menu-kebab { flex: 0 0 auto; font-size: 13px; color: #5f6368; }
.ac-story-chrome-menu-ft { padding: 10px 14px; font-size: 11.5px; font-weight: 600; color: #5f6368; border-top: 1px solid rgba(0, 0, 0, .08); }

/* Pinned extension icon slot, now living in the light toolbar, beside the
   puzzle button. */
.ac-story-toolbar-slot { display: inline-flex; width: 18px; height: 18px; border-radius: 5px; align-items: center; justify-content: center; overflow: hidden; flex: 0 0 auto; }
.ac-story-toolbar-slot img { width: 100%; height: 100%; opacity: 0; transform: scale(.4); transition: opacity .25s ease, transform .25s ease; }
.ac-story-toolbar-slot.is-popped img { opacity: 1; transform: scale(1); }

.ac-story-pin { flex: 0 0 auto; border: 0; background: transparent; font-size: 14px; color: #9aa0a6; border-radius: 5px; padding: 2px 5px; transition: color .2s ease, background .2s ease, transform .15s ease; }
.ac-story-pin.is-pinned { color: var(--qa-cyan); background: rgba(48, 193, 255, .16); transform: scale(1.1); }

/* This one scene is a light surface — the cosmic near-white cursor tip
   (var(--qa-ink), the default in .ac-demo-cursor::before) would be nearly
   invisible against the cream toolbar / white dropdown, so darken it here. */
.ac-demo-cursor--dark::before { color: #202124; }

/* ── Steps 3/4: reuse the .ac-demo-* mock page/panel pieces below; the panel
   now lives INSIDE the mock page as a floating overlay (see .ac-demo-panel),
   the way the real extension panel overlays the page it's on. ── */
.ac-story-scene { position: relative; width: 100%; min-width: 0; }
.ac-demo-panel-steps { padding: 0 9px; }
.ac-demo-panel-step { display: flex; align-items: center; gap: 6px; padding: 4px 0; font-size: 11px; color: var(--qa-muted); border-top: 1px solid var(--qa-line-soft); }
.ac-demo-panel-step-n {
    display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; flex: 0 0 auto;
    border-radius: 4px; background: rgba(255, 255, 255, .1); font-size: 9px; font-weight: 700; color: var(--qa-ink);
}

/* ── Shared click-ripple affordance — any element that should visibly react
   to the demo cursor "clicking" it gets this class (targets, and now also
   the webstore/panel buttons at each storyboard step). ── */
.ac-fx-ripple { position: relative; }
.ac-fx-ripple::after {
    content: ""; position: absolute; inset: -6px; border-radius: 12px; border: 2px solid var(--qa-violet);
    opacity: 0; pointer-events: none;
}
.ac-fx-ripple.is-ripple::after { animation: ac-demo-target-ripple .6s ease-out; }

/* ── Self-playing setup demo: a big mock browser window, the mini panel
   floating INSIDE it as an overlay, and a fake cursor. ── */
.ac-demo-browser { width: 100%; min-width: 0; border: 1px solid var(--qa-line); border-radius: var(--qa-radius); overflow: hidden; background: rgba(255, 255, 255, .03); box-shadow: var(--qa-shadow); }
.ac-demo-browser-bar { display: flex; align-items: center; gap: 8px; padding: 8px 10px; background: rgba(255, 255, 255, .04); }
.ac-demo-browser-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--qa-line); flex: 0 0 auto; }
.ac-demo-browser-url {
    flex: 1; height: 18px; border-radius: 9px; background: var(--qa-line-soft); margin-left: 4px;
    display: flex; align-items: center; padding: 0 10px; font-size: 10.5px; color: var(--qa-muted); min-width: 0;
    overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.ac-demo-page {
    position: relative; height: 360px; overflow: hidden;
    background: linear-gradient(160deg, rgba(40, 20, 80, .35), rgba(20, 10, 40, .35));
}
.ac-demo-page-header {
    display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px;
    background: rgba(255, 255, 255, .05); border-bottom: 1px solid var(--qa-line-soft);
    font-size: 11px; font-weight: 700; color: var(--qa-muted);
}
.ac-demo-page-header span.ac-demo-page-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--qa-violet); flex: 0 0 auto; }
.ac-demo-page-card {
    position: absolute; inset: 40px 14px 14px; border-radius: 10px;
    background: rgba(255, 255, 255, .025); border: 1px solid var(--qa-line-soft);
}
.ac-demo-target {
    position: absolute; transform: translate(-50%, -50%); padding: 7px 14px; border-radius: 8px;
    background: rgba(255, 255, 255, .08); border: 1px solid var(--qa-line); font-weight: 700; font-size: 12.5px;
    color: var(--qa-ink); transition: background .18s ease, transform .18s ease, box-shadow .18s ease; z-index: 2;
}
/* Ripple affordance itself lives on the shared .ac-fx-ripple class above;
   .ac-demo-target keeps working automatically since it's always paired with
   .ac-fx-ripple in the markup (see autoclick-demo.js). */
.ac-demo-target.is-pressed { background: var(--qa-grad); color: #fff; transform: translate(-50%, -50%) scale(.92); box-shadow: 0 0 18px -4px var(--qa-violet); }
/* Kept clear of the floating panel, which overlays the top-right corner. */
.ac-demo-target-a { left: 16%; top: 30%; }
.ac-demo-target-b { left: 34%; top: 72%; }
.ac-demo-target-badge {
    position: absolute; top: -6px; right: -6px; width: 16px; height: 16px; border-radius: 50%;
    background: var(--qa-cyan); color: #04121c; font-size: 10px; font-weight: 700;
    display: flex; align-items: center; justify-content: center; box-shadow: 0 0 0 2px var(--qa-panel);
}
.ac-demo-target-badge[hidden] { display: none; }
.ac-demo-cursor {
    position: absolute; width: 16px; height: 16px; left: 6%; top: 6%;
    transform: translate(-4px, -2px); transition: left .55s ease, top .55s ease, opacity .3s ease;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .5)); z-index: 3; font-size: 15px; line-height: 1; opacity: 1;
}
.ac-demo-cursor::before { content: "\25B2"; display: block; transform: rotate(315deg); color: var(--qa-ink); }
.ac-demo-cursor.is-hidden { opacity: 0; }
.ac-demo-cursor.is-clicking::before { animation: ac-demo-press .25s ease; }

/* Floats INSIDE the mock page, overlaying its top-right corner — like the
   real extension's draggable panel overlays whatever page it's open on.
   max-width is a % of the page (its containing block), so it can never
   overflow the page horizontally even as the browser scales down; it just
   shrinks proportionally instead of forcing a breakpoint layout swap. */
.ac-demo-panel {
    position: absolute; top: 12px; right: 12px; z-index: 5; width: 190px; max-width: 46%;
    font-size: 11.5px; color: var(--qa-ink);
    background: linear-gradient(160deg, rgba(40, 20, 80, .82), rgba(20, 10, 40, .82));
    border: 1px solid var(--qa-line); border-radius: var(--qa-radius-sm);
    box-shadow: var(--qa-shadow), 0 0 34px -10px var(--qa-violet); backdrop-filter: blur(8px); overflow: hidden;
}
.ac-demo-panel-hd { padding: 7px 9px; background: var(--qa-grad); font-weight: 700; color: #fff; }
.ac-demo-panel-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 6px 9px; border-top: 1px solid var(--qa-line-soft); }
.ac-demo-panel-val { font-weight: 700; color: var(--qa-cyan); min-width: 2ch; text-align: right; }
.ac-demo-panel-btn { flex: 1; text-align: center; padding: 5px 6px; border-radius: 6px; background: rgba(255, 255, 255, .08); font-weight: 700; transition: background .2s, transform .15s; }
/* Generalized from .ac-demo-panel-btn-start so "Add click point" flashes the
   same way as "Start" when the demo cursor presses it. */
.ac-demo-panel-btn.is-pressed { background: var(--qa-ok); color: #06210f; transform: scale(.97); }
.ac-demo-panel-badge { padding: 1px 8px; border-radius: var(--qa-radius-pill); font-weight: 700; background: rgba(255, 255, 255, .08); color: var(--qa-muted); }
.ac-demo-panel-badge.is-running { background: rgba(59, 214, 122, .18); color: var(--qa-ok); animation: ac-demo-pulse 1.6s ease-in-out infinite; }

@keyframes ac-demo-target-ripple {
    0% { opacity: .9; transform: scale(.75); }
    100% { opacity: 0; transform: scale(1.9); }
}
@keyframes ac-demo-press {
    0%, 100% { transform: rotate(315deg) scale(1); }
    50% { transform: rotate(315deg) scale(.7); }
}
@keyframes ac-demo-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(59, 214, 122, .45); }
    50% { box-shadow: 0 0 0 4px rgba(59, 214, 122, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .ac-demo-cursor { transition: none; }
    .ac-demo-cursor.is-clicking::before { animation: none; }
    .ac-fx-ripple.is-ripple::after { animation: none; opacity: 0; }
    .ac-demo-target { transition: none; }
    .ac-demo-panel-btn { transition: none; }
    .ac-demo-panel-badge.is-running { animation: none; }
    /* Storyboard: no cross-fade between steps, no pin/webstore/toolbar-slot
       transitions — the reduced-motion branch renders one static frame and
       never re-touches these classes again, but this keeps that frame's
       first paint from doing a one-off fade-in too. */
    .ac-story-stage-item { transition: none; }
    .ac-story-dot { transition: none; }
    .ac-story-webstore-btn { transition: none; }
    .ac-story-chrome-menu { transition: none; }
    .ac-story-pin { transition: none; }
    .ac-story-toolbar-slot img { transition: none; }
    /* Static base tilt only — the mouse-parallax JS already no-ops here,
       this just removes the (harmless but pointless) settle transition. */
    .ac-replica { transition: none; }
}
