/* NavTech product showcase v12 — "quiet analytics"
   Scoped to .products[data-showcase-v2]; the rest of the site is untouched.
   The design language is a white void with one dark object: hairline
   borders instead of shadows, everything interactive is a pill, numbers
   are plain and deltas are tiny tinted chips, status is a dot, charts are
   soft and axis-less. Periwinkle is the brand and primary series; green =
   money, red = bad, amber = warning, teal = tail ends. Nothing else is
   colored.
   Scale: 1em inside .q-app == --q-fs, so the whole mockup densifies
   fluidly with viewport. Spec sizes are quoted at a 1400px canvas —
   divide by 13 to get em (13px body == 1em).
   Theming: LIGHT by default, flipping to a dark grade under the device's
   prefers-color-scheme: dark. Under dark the signature move inverts with
   it — a dark void with one LIGHT object — so the dock stays the single
   contrast anchor. Scene rules never hardcode ink; everything runs
   through the --q-* tokens. */
/* ------------------------------------------------------------------ */
/* IBM Plex Mono — the showcase code voice (self-hosted, 400/500)      */
/* ------------------------------------------------------------------ */

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/plex-mono-400-cyrillic-ext.woff2') format('woff2');
    unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/plex-mono-400-cyrillic.woff2') format('woff2');
    unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/plex-mono-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/plex-mono-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/plex-mono-500-cyrillic-ext.woff2') format('woff2');
    unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/plex-mono-500-cyrillic.woff2') format('woff2');
    unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/plex-mono-500-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/plex-mono-500-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ------------------------------------------------------------------ */
/* Section + design tokens                                             */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] {
    /* section chrome: matches the rest of the site (white, ink) */
    --prod-bg: #ffffff;
    --prod-ink: #1d1d1f;
    --prod-muted: rgba(29, 29, 31, 0.55);
    --prod-hairline: rgba(29, 29, 31, 0.11);
    --prod-wash: rgba(29, 29, 31, 0.038);
    --prod-accent: #f97316;
    --prod-accent-deep: #dd5f07;

    /* ---------------------------------------------------------------- */
    /* "Quiet analytics" window system — LIGHT grade (default)           */
    /* A white void with one dark object. Hairlines, never shadows.      */
    /* Every scene rule reads --q-*; nothing hardcodes ink.              */
    /* ---------------------------------------------------------------- */

    /* the em scale: 1em inside .q-app == --q-fs, so the whole mockup
       densifies fluidly with viewport. Spec sizes are quoted at a
       1400px canvas; divide by 13 to get em (13px body == 1em). */
    --q-fs: clamp(9.5px, 0.62vw + 2.9px, 11.75px);

    /* neutrals — the workhorses */
    --q-bg: #ffffff;
    --q-bg-subtle: #f6f6f7;
    --q-bg-hover: #f0f0f2;
    --q-border: #ececee;
    --q-border-strong: #e2e2e5;
    --q-text: #1a1b1e;
    --q-text-2: #8a8d93;
    --q-text-3: #b3b6bc;

    /* the one dark object */
    --q-dock-bg: rgba(20, 20, 23, 0.96);
    --q-dock-icon: #8e9096;
    --q-dock-on-ink: #ffffff;
    --q-dock-on-bg: rgba(255, 255, 255, 0.1);

    /* accents — data & semantics only */
    --q-brand: #8b8cf6;
    --q-brand-strong: #3e6ff6;
    --q-brand-soft: #c9cafb;
    --q-positive: #22c55e;
    --q-positive-text: #16a34a;
    --q-negative: #ef4444;
    --q-warning: #f59e0b;
    --q-tail: #7de8e0;
    --q-chip-pos-bg: #e8f9ee;
    --q-chip-neg-bg: #fdecec;
    --q-chip-neu-bg: #f3f3f4;
    --q-chip-warn-bg: #fef4e6;
    --q-chip-brand-bg: #eeeefe;

    /* chart furniture */
    --q-grid-dot: #e5e5e7;
    --q-ring-track: #efeff1;
    --q-context: #d9dade;
    --q-fill-top: 0.14;

    /* shape */
    --q-r-full: 999px;
    --q-r-card: 1.2em;
    --q-r-row: 0.75em;
    --q-r-chip: 0.46em;
    --q-r-frame: 22px;

    /* shadows: floating elements only */
    --q-sh-float: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.06);
    --q-sh-dock: 0 12px 32px rgba(0, 0, 0, 0.18);
    --q-sh-frame:
        0 30px 70px -18px rgba(24, 22, 38, 0.3),
        0 14px 34px -14px rgba(24, 22, 38, 0.18),
        0 3px 8px rgba(24, 22, 38, 0.07);
    --q-bezel: linear-gradient(135deg, #e4d5fe 0%, #f0d8f8 48%, #f6cfec 100%);
    --q-bezel-glow: 0 0 46px -6px rgba(200, 170, 250, 0.5);

    --mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;

    --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
    --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
    --ease-spring: cubic-bezier(0.34, 1.45, 0.44, 1);

    min-height: 100svh;
    display: block;
    padding: clamp(7rem, 9.5vw, 8.75rem) var(--page-edge) clamp(5.5rem, 8vw, 7rem);
    border-top: 1px solid var(--prod-hairline);
    background: var(--prod-bg);
    color: var(--prod-ink);
    overflow: hidden;
}

/* Dark grade: kicks in with the device theme; only the demo windows flip.
   The signature move inverts with it — a dark void with one LIGHT object,
   so the dock stays the single contrast anchor instead of vanishing. */
@media (prefers-color-scheme: dark) {
    .products[data-showcase-v2] {
        --q-bg: #101013;
        --q-bg-subtle: #17171b;
        --q-bg-hover: #1e1e23;
        --q-border: #26262c;
        --q-border-strong: #33333a;
        --q-text: #f2f2f4;
        --q-text-2: #8f929a;
        --q-text-3: #6b6e77;

        --q-dock-bg: rgba(244, 244, 246, 0.96);
        --q-dock-icon: #6e7076;
        --q-dock-on-ink: #141417;
        --q-dock-on-bg: rgba(20, 20, 23, 0.09);

        --q-brand: #a3a4f9;
        --q-brand-strong: #6b91ff;
        --q-brand-soft: #4a4b8c;
        --q-positive: #4ade80;
        --q-positive-text: #4ade80;
        --q-negative: #f87171;
        --q-warning: #fbbf24;
        --q-tail: #7de8e0;
        --q-chip-pos-bg: rgba(74, 222, 128, 0.14);
        --q-chip-neg-bg: rgba(248, 113, 113, 0.14);
        --q-chip-neu-bg: rgba(242, 242, 244, 0.07);
        --q-chip-warn-bg: rgba(251, 191, 36, 0.14);
        --q-chip-brand-bg: rgba(163, 164, 249, 0.14);

        --q-grid-dot: #2b2b32;
        --q-ring-track: #24242a;
        --q-context: #3a3a42;
        --q-fill-top: 0.22;

        --q-sh-float: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.34);
        --q-sh-dock: 0 12px 32px rgba(0, 0, 0, 0.5);
        --q-sh-frame:
            0 42px 90px -18px rgba(6, 6, 10, 0.5),
            0 18px 40px -12px rgba(6, 6, 10, 0.36),
            0 3px 9px rgba(6, 6, 10, 0.2);
        --q-bezel: linear-gradient(135deg, #6a5a92 0%, #7d5e88 48%, #8c5f80 100%);
        --q-bezel-glow: 0 0 46px -10px rgba(120, 90, 170, 0.45);
    }

    .products[data-showcase-v2] .prod-stage-backdrop img {
        filter: saturate(0.98) brightness(0.9) contrast(1.02);
    }

    .products[data-showcase-v2] .prod-stage-backdrop::after {
        background:
            radial-gradient(115% 85% at 50% 36%, rgba(10, 12, 10, 0) 48%, rgba(10, 12, 10, 0.3) 100%),
            linear-gradient(180deg, rgba(16, 17, 14, 0.12), rgba(16, 17, 14, 0.03) 42%, rgba(14, 14, 11, 0.16));
    }
}

.products[data-showcase-v2]::before {
    border-color: rgba(29, 29, 31, 0.12);
}
/* ------------------------------------------------------------------ */
/* Section header                                                      */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .prod-head {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(18rem, 0.65fr);
    align-items: end;
    gap: clamp(2rem, 5vw, 6rem);
    margin: 0 0 clamp(2.25rem, 4.5vw, 4rem);
}

.products[data-showcase-v2] .prod-head-copy { min-width: 0; }

.products[data-showcase-v2] .prod-eyebrow {
    margin: 0 0 0.85rem;
    font-family: var(--sans, 'Google Sans', system-ui, sans-serif);
    font-size: var(--section-tag-size, 0.8rem);
    font-weight: var(--section-tag-weight, 500);
    font-variation-settings: 'wdth' 500;
    letter-spacing: var(--section-tag-spacing, 0.01em);
    text-transform: none;
    color: var(--section-tag-color, rgba(17, 17, 17, 0.8));
}

/* same type ramp as .section-title on the rest of the site */
.products[data-showcase-v2] .prod-heading {
    max-width: 14em;
    margin: 0;
    font-family: var(--sans-titles, 'Google Sans', system-ui, sans-serif);
    font-size: clamp(1.9rem, 4vw, 3rem);
    font-weight: 600;
    font-variation-settings: 'wdth' 550;
    line-height: 1.12;
    letter-spacing: -0.025em;
    color: var(--prod-ink);
}

.products[data-showcase-v2] .prod-lede {
    max-width: 44ch;
    margin: 0 0 0.3rem;
    padding: 0;
    font-family: var(--sans, 'Google Sans', system-ui, sans-serif);
    font-size: clamp(0.92rem, 1.15vw, 1.05rem);
    font-weight: 400;
    line-height: 1.55;
    letter-spacing: -0.015em;
    color: var(--prod-muted);
}

/* ------------------------------------------------------------------ */
/* Layout: product list + stage                                        */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .prod-layout {
    display: grid;
    grid-template-columns: minmax(19rem, 0.74fr) minmax(31rem, 1.38fr);
    gap: clamp(2.5rem, 5vw, 5.5rem);
    align-items: center;
    min-height: 0;
}

.products[data-showcase-v2] .prod-list {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 0;
}

.products[data-showcase-v2] .prod-item {
    position: relative;
    margin: 0;
    border-top: 1px solid var(--prod-hairline);
    opacity: 1;
    transform: none;
    transition: border-color 180ms ease;
}

.products[data-showcase-v2] .prod-item:first-of-type { margin-top: 0; }
.products[data-showcase-v2] .prod-item:last-of-type { border-bottom: 1px solid var(--prod-hairline); }

.products[data-showcase-v2] .prod-trigger {
    width: calc(100% + 1.6rem);
    margin: 0 -0.8rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        'name marker'
        'kicker marker';
    align-items: center;
    gap: 0.2rem 0.85rem;
    padding: clamp(1rem, 1.8vw, 1.35rem) 0.8rem;
    border: 0;
    border-radius: 12px;
    background: transparent;
    color: inherit;
    text-align: left;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 170ms ease, transform 140ms var(--ease-out);
}

.products[data-showcase-v2] .prod-trigger:hover { background: var(--prod-wash); }

.products[data-showcase-v2] .prod-trigger:active { transform: scale(0.99); }

.products[data-showcase-v2] .prod-trigger:focus-visible {
    outline: 2px solid var(--prod-accent);
    outline-offset: 2px;
}

.products[data-showcase-v2] .prod-index { display: none; }

.products[data-showcase-v2] .prod-name {
    grid-area: name;
    min-width: 0;
    font-family: var(--sans-titles, 'Google Sans', system-ui, sans-serif);
    font-size: clamp(1.22rem, 1.85vw, 1.6rem);
    font-weight: 600;
    font-variation-settings: 'wdth' 540;
    line-height: 1.08;
    letter-spacing: -0.03em;
    color: var(--prod-ink);
    opacity: 0.44;
    transform: none;
    transition: opacity 180ms ease, color 180ms ease;
}

.products[data-showcase-v2] .prod-name .nt {
    font-weight: 400;
    opacity: 0.6;
}

.products[data-showcase-v2] .prod-kicker {
    grid-area: kicker;
    display: block;
    max-width: 30ch;
    font-family: var(--sans, 'Google Sans', system-ui, sans-serif);
    font-size: 0.76rem;
    font-weight: 500;
    font-variation-settings: 'wdth' 500;
    line-height: 1.35;
    letter-spacing: 0;
    white-space: normal;
    color: var(--prod-muted);
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 180ms ease, transform 220ms var(--ease-out);
}

.products[data-showcase-v2] .prod-marker {
    grid-area: marker;
    position: relative;
    width: 1.55rem;
    height: 1.55rem;
    border: 1px solid rgba(29, 29, 31, 0.18);
    border-radius: 999px;
    color: var(--prod-ink);
    transition: border-color 180ms ease, background-color 180ms ease, color 180ms ease, transform 220ms var(--ease-out);
}

.products[data-showcase-v2] .prod-marker::before,
.products[data-showcase-v2] .prod-marker::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0.46rem;
    height: 1px;
    background: currentColor;
    opacity: 0.6;
    transform: translate(-50%, -50%);
    transition: opacity 180ms ease, transform 220ms var(--ease-out);
}

.products[data-showcase-v2] .prod-marker::after {
    transform: translate(-50%, -50%) rotate(90deg);
}

.products[data-showcase-v2] .prod-item.is-active .prod-marker {
    border-color: var(--prod-ink);
    background: var(--prod-ink);
    color: #ffffff;
    transform: rotate(45deg);
}

.products[data-showcase-v2] .prod-item.is-active .prod-marker::before,
.products[data-showcase-v2] .prod-item.is-active .prod-marker::after { opacity: 0.95; }

.products[data-showcase-v2] .prod-item.is-active .prod-name,
.products[data-showcase-v2] .prod-trigger:hover .prod-name {
    color: var(--prod-ink);
    opacity: 1;
    transform: none;
}

.products[data-showcase-v2] .prod-trigger:hover .prod-kicker { opacity: 0.6; transform: none; }

.products[data-showcase-v2] .prod-item.is-active .prod-kicker { opacity: 1; transform: none; }

.products[data-showcase-v2] .prod-reveal {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 300ms var(--ease-out);
}

.products[data-showcase-v2] .prod-item.is-active .prod-reveal { grid-template-rows: 1fr; }

.products[data-showcase-v2] .prod-reveal-inner {
    min-height: 0;
    overflow: hidden;
    padding: 0;
}

.products[data-showcase-v2] .prod-desc {
    max-width: 52ch;
    margin: 0;
    padding: 0.05rem 2.2rem clamp(1.1rem, 2vw, 1.45rem) 0;
    font-family: var(--sans, 'Google Sans', system-ui, sans-serif);
    font-size: clamp(0.88rem, 1.1vw, 0.96rem);
    font-weight: 400;
    line-height: 1.58;
    letter-spacing: -0.012em;
    color: var(--prod-muted);
    opacity: 0;
    transform: translateY(5px);
    transition: opacity 180ms ease 40ms, transform 220ms var(--ease-out) 40ms;
}

.products[data-showcase-v2] .prod-item.is-active .prod-desc { opacity: 1; transform: none; }

.products[data-showcase-v2] .prod-slot { display: none; }

.products[data-showcase-v2] .prod-foot {
    margin: clamp(1.5rem, 3vw, 2.5rem) 0 0;
    padding: 0;
}

.products[data-showcase-v2] .prod-foot-cta {
    display: inline-flex;
    width: auto;
    align-items: center;
    justify-content: flex-start;
    gap: 0.65rem;
    padding: 0.25rem 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: var(--prod-accent);
    font-family: var(--sans, 'Google Sans', system-ui, sans-serif);
    font-size: 0.98rem;
    font-weight: 500;
    text-decoration: none;
    opacity: 1;
    transform: none;
    transition: color 180ms ease, transform 140ms var(--ease-out);
}

.products[data-showcase-v2] .prod-foot-cta:hover { background: transparent; color: var(--prod-accent-deep); }
.products[data-showcase-v2] .prod-foot-cta:active { transform: scale(0.98); }
.products[data-showcase-v2] .prod-foot-cta .arr { transition: transform 180ms var(--ease-out); }
.products[data-showcase-v2] .prod-foot-cta:hover .arr { transform: translate(3px, -2px); }

/* ------------------------------------------------------------------ */
/* Stage                                                               */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .prod-visual-home {
    position: relative;
    display: block;
    min-width: 0;
    min-height: 0;
}

.products[data-showcase-v2] .prod-stage-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin: 0 0 0.8rem;
    font-family: var(--mono);
    font-size: 0.64rem;
    line-height: 1.2;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(29, 29, 31, 0.45);
}

.products[data-showcase-v2] .prod-stage-live {
    display: inline-flex;
    align-items: center;
    gap: 0.48rem;
}

.products[data-showcase-v2] .prod-stage-live::before {
    content: '';
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: #2fae67;
    box-shadow: 0 0 0 3px rgba(47, 174, 103, 0.14);
    animation: pvLivePulse 2.6s ease-in-out infinite;
}

.products[data-showcase-v2] .prod-visual {
    position: relative;
    isolation: isolate;
    width: 100%;
    height: clamp(34rem, 50vw, 41.5rem);
    min-height: 0;
    overflow: hidden;
    border: 1px solid rgba(29, 29, 31, 0.12);
    border-radius: 8px;
    background: #a9b6c4;
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.65) inset,
        0 24px 60px -30px rgba(29, 29, 31, 0.28);
    opacity: 1;
    transform: none;
}

.products[data-showcase-v2] .prod-visual:focus-visible {
    outline: 2px solid var(--prod-accent);
    outline-offset: 4px;
}

/* backdrop art: brand gradient painting, graded per product */
.products[data-showcase-v2] .prod-stage-backdrop {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
}

.products[data-showcase-v2] .prod-stage-backdrop img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    object-position: 64% 82%;
    filter: saturate(1.04) brightness(1.05) contrast(1.01);
    transform: scale(1.08);
    transition: object-position 900ms var(--ease-in-out), filter 900ms ease;
}

/* fine grain: turns the smooth gradient into a print-like surface */
.products[data-showcase-v2] .prod-stage-backdrop::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size: 140px 140px;
    mix-blend-mode: overlay;
    opacity: 0.35;
    pointer-events: none;
}

/* soft veil + vignette to seat the windows */
.products[data-showcase-v2] .prod-stage-backdrop::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    background:
        radial-gradient(115% 85% at 50% 36%, rgba(14, 16, 13, 0) 52%, rgba(14, 16, 13, 0.18) 100%),
        linear-gradient(180deg, rgba(247, 246, 240, 0.1), rgba(247, 246, 240, 0.02) 42%, rgba(240, 230, 216, 0.08));
    pointer-events: none;
    transition: background 600ms ease;
}

.products[data-showcase-v2][data-active-product='prism'] .prod-stage-backdrop img { object-position: 36% 76%; }
.products[data-showcase-v2][data-active-product='studio'] .prod-stage-backdrop img { object-position: 80% 88%; }
.products[data-showcase-v2][data-active-product='flow'] .prod-stage-backdrop img { object-position: 20% 80%; }
.products[data-showcase-v2][data-active-product='grid'] .prod-stage-backdrop img {
    object-position: 50% 46%;
    filter: saturate(0.94) brightness(0.9) contrast(1.03);
}
.products[data-showcase-v2][data-active-product='speech'] .prod-stage-backdrop img { object-position: 64% 30%; }
.products[data-showcase-v2][data-active-product='hr'] .prod-stage-backdrop img { object-position: 30% 42%; }

.products[data-showcase-v2] .prod-scene-mount {
    position: absolute;
    inset: 0;
    z-index: 3;
}

/* interactive hint pill (dark glass over the art in both schemes) */
.products[data-showcase-v2] .prod-stage-hint {
    position: absolute;
    z-index: 9;
    left: 50%;
    bottom: 0.9rem;
    display: inline-flex;
    align-items: center;
    gap: 0.42rem;
    padding: 0.34rem 0.72rem 0.36rem;
    border: 1px solid rgba(243, 240, 230, 0.14);
    border-radius: 999px;
    background: rgba(18, 18, 13, 0.78);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: rgba(237, 234, 223, 0.85);
    font-family: var(--sans, 'Google Sans', system-ui, sans-serif);
    font-size: 0.66rem;
    letter-spacing: 0.01em;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transform: translate(-50%, 8px);
    transition: opacity 420ms ease, transform 460ms var(--ease-out);
}

.products[data-showcase-v2] .prod-stage-hint::before {
    content: '';
    width: 0.86em;
    height: 0.86em;
    border-radius: 50%;
    background:
        radial-gradient(circle at 50% 50%, rgba(241, 111, 50, 0.95) 0 32%, rgba(241, 111, 50, 0.28) 33% 58%, transparent 59%);
    animation: pvLivePulse 2.2s ease-in-out infinite;
}

.products[data-showcase-v2] .prod-stage-hint.is-on { opacity: 1; transform: translate(-50%, 0); }
.products[data-showcase-v2] .prod-stage-hint.is-gone { opacity: 0; transform: translate(-50%, 6px); }

/* legacy inline scenes (removed by JS; hidden here to avoid any flash) */
.products[data-showcase-v2] .prod-visual > .prod-scene { display: none !important; }

/* scene crossfade */
.products[data-showcase-v2] .prod-scene-v2 {
    position: absolute;
    inset: 0;
    font-size: var(--q-fs);
    opacity: 1;
    filter: blur(0);
    transform: translateY(0) scale(1);
    transition: opacity 260ms ease, transform 300ms var(--ease-out), filter 260ms ease;
}

.products[data-showcase-v2] .prod-scene-v2.is-entering {
    opacity: 0;
    filter: blur(3px);
    transform: translateY(10px) scale(0.985);
}

.products[data-showcase-v2] .prod-scene-v2.is-leaving {
    opacity: 0;
    filter: blur(3px);
    transform: translateY(-6px) scale(0.992);
    pointer-events: none;
}

.products[data-showcase-v2] .prod-visual-alt {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ================================================================== */
/* Quiet-analytics component library                                   */
/* Everything the seven scenes are built from. Rules here are          */
/* scene-agnostic; a scene section may only compose and position.      */
/* ================================================================== */

/* ------------------------------------------------------------------ */
/* Showcase frame + app shell                                          */
/* ------------------------------------------------------------------ */

/* The marketing frame: a rounded window with a pastel gradient bezel
   and a faint outer glow of the same gradient. The bezel is a 1.5px
   padding box, so the app inside keeps a true hairline edge. */
.products[data-showcase-v2] .q-frame {
    position: absolute;
    inset: 4.5% 4% 5% 4%;
    padding: 1.5px;
    border-radius: var(--q-r-frame);
    background: var(--q-bezel);
    box-shadow: var(--q-bezel-glow), var(--q-sh-frame);
}

.products[data-showcase-v2] .q-app {
    position: relative;
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-rows: auto auto minmax(0, 1fr);
    overflow: hidden;
    border-radius: calc(var(--q-r-frame) - 1.5px);
    background: var(--q-bg);
    color: var(--q-text);
    font-family: var(--sans, 'Google Sans', system-ui, sans-serif);
    font-weight: 400;
    font-size: 1em;
    line-height: 1.45;
    letter-spacing: 0.004em;
}

/* Page chrome: floats on white — no border, no background */
.products[data-showcase-v2] .q-top {
    display: flex;
    align-items: center;
    gap: 0.75em;
    min-height: 4.2em;
    padding: 0 1.5em;
}

.products[data-showcase-v2] .q-mark {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 1.85em;
    height: 1.85em;
    border-radius: 0.42em;
    background: var(--q-text);
    color: var(--q-bg);
    font-size: 0.82em;
    font-weight: 600;
    letter-spacing: -0.02em;
}

/* project switcher: ghost button, no border until hover */
.products[data-showcase-v2] .q-proj {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    height: 2.3em;
    padding: 0 0.6em;
    border: 0;
    border-radius: var(--q-r-full);
    background: transparent;
    color: var(--q-text);
    font: inherit;
    font-size: 1.08em;
    font-weight: 600;
    cursor: default;
    transition: background 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-proj-ic {
    width: 1.5em;
    height: 1.5em;
    border-radius: 50%;
    background: var(--q-brand-soft);
}

.products[data-showcase-v2] .q-proj-ch {
    display: grid;
    gap: 0.15em;
    color: var(--q-text-3);
    line-height: 0;
}

.products[data-showcase-v2] .q-proj-ch svg { width: 0.62em; height: 0.62em; }

.products[data-showcase-v2] .q-spacer { flex: 1 1 auto; }

.products[data-showcase-v2] .q-ava {
    flex: 0 0 auto;
    width: 2.3em;
    height: 2.3em;
    border-radius: 50%;
    background: radial-gradient(120% 120% at 28% 22%, var(--q-brand-soft), var(--q-brand) 74%);
}

/* Control row: left group = the "what", right group = the "when/how" */
.products[data-showcase-v2] .q-ctl {
    display: flex;
    align-items: center;
    gap: 0.55em;
    padding: 0 1.5em 0.95em;
}

.products[data-showcase-v2] .q-ctl-r {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.55em;
}

/* Content zone: scrolls under the dock */
.products[data-showcase-v2] .q-view {
    position: relative;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 1.15em;
    padding: 0.35em 1.5em 1.5em;
}

/* charts break the gutter and run full-bleed */
.products[data-showcase-v2] .q-bleed {
    margin-left: -1.5em;
    margin-right: -1.5em;
}

/* ------------------------------------------------------------------ */
/* Pill select — everything interactive is a pill                      */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
    height: 2.6em;
    padding: 0 1.05em;
    border: 1px solid var(--q-border);
    border-radius: var(--q-r-full);
    background: var(--q-bg);
    color: var(--q-text);
    font: inherit;
    font-size: 1em;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    box-shadow: var(--q-sh-float);
    cursor: pointer;
    transition:
        background 180ms var(--ease-out),
        border-color 180ms var(--ease-out),
        color 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-pill svg {
    width: 1.25em;
    height: 1.25em;
    color: var(--q-text-2);
}

/* trailing chevron pair — the "this is a select" tell */
.products[data-showcase-v2] .q-pill-ch {
    display: grid;
    gap: 0.15em;
    margin-left: 0.1em;
    color: var(--q-text-3);
    line-height: 0;
}

.products[data-showcase-v2] .q-pill-ch svg { width: 0.62em; height: 0.62em; color: inherit; }

.products[data-showcase-v2] .q-pill.is-icon {
    width: 2.6em;
    height: 2.6em;
    padding: 0;
    justify-content: center;
}

.products[data-showcase-v2] .q-pill.is-ghost {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
}

.products[data-showcase-v2] .q-pill.is-quiet {
    height: 2.15em;
    padding: 0 0.8em;
    font-size: 0.92em;
    box-shadow: none;
}

/* a pill group behaves as one control: shared track, one lit segment */
.products[data-showcase-v2] .q-seg {
    display: inline-flex;
    align-items: center;
    gap: 0.2em;
    padding: 0.25em;
    border: 1px solid var(--q-border);
    border-radius: var(--q-r-full);
    background: var(--q-bg-subtle);
}

.products[data-showcase-v2] .q-seg .q-pill {
    height: 2.1em;
    padding: 0 0.85em;
    border-color: transparent;
    background: transparent;
    color: var(--q-text-2);
    box-shadow: none;
    font-size: 0.94em;
}

.products[data-showcase-v2] .q-seg .q-pill[aria-pressed='true'] {
    background: var(--q-bg);
    border-color: var(--q-border);
    color: var(--q-text);
    box-shadow: var(--q-sh-float);
}

/* link pill — "Realtime ›" */
.products[data-showcase-v2] .q-link {
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
    height: 1.95em;
    padding: 0 0.7em;
    border: 0;
    border-radius: var(--q-r-full);
    background: transparent;
    color: var(--q-text-2);
    font: inherit;
    font-size: 0.92em;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background 180ms var(--ease-out), color 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-link::after {
    content: '›';
    color: var(--q-text-3);
    font-size: 1.1em;
    line-height: 0.9;
}

/* ------------------------------------------------------------------ */
/* Delta chip — semantics beat direction                               */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-delta {
    display: inline-flex;
    align-items: center;
    padding: 0.18em 0.46em;
    border-radius: var(--q-r-chip);
    background: var(--q-chip-neu-bg);
    color: var(--q-text-2);
    font-size: 0.85em;
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-delta.is-up {
    background: var(--q-chip-pos-bg);
    color: var(--q-positive-text);
}

.products[data-showcase-v2] .q-delta.is-down {
    background: var(--q-chip-neg-bg);
    color: var(--q-negative);
}

.products[data-showcase-v2] .q-delta.is-warn {
    background: var(--q-chip-warn-bg);
    color: var(--q-warning);
}

.products[data-showcase-v2] .q-delta.is-brand {
    background: var(--q-chip-brand-bg);
    color: var(--q-brand-strong);
}

/* ------------------------------------------------------------------ */
/* Status & series dots — a dot, never a badge                         */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-dot {
    flex: 0 0 auto;
    display: inline-block;
    width: 0.5em;
    height: 0.5em;
    border-radius: 50%;
    background: var(--q-text-3);
}

.products[data-showcase-v2] .q-dot.is-good { background: var(--q-positive); }
.products[data-showcase-v2] .q-dot.is-warn { background: var(--q-warning); }
.products[data-showcase-v2] .q-dot.is-bad { background: var(--q-negative); }
.products[data-showcase-v2] .q-dot.is-brand { background: var(--q-brand); }
.products[data-showcase-v2] .q-dot.is-tail { background: var(--q-tail); }
.products[data-showcase-v2] .q-dot.is-ctx { background: var(--q-context); }

.products[data-showcase-v2] .q-dot.is-live {
    animation: qPulse 3s ease-in-out infinite;
}

/* legend row: dot + range text */
.products[data-showcase-v2] .q-legend {
    display: flex;
    align-items: center;
    gap: 1.2em;
    color: var(--q-text-2);
    font-size: 0.92em;
}

.products[data-showcase-v2] .q-legend span {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
}

/* ------------------------------------------------------------------ */
/* KPI cluster — label / value / delta, no boxes, no dividers          */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-kpis {
    display: flex;
    align-items: flex-start;
    gap: 2.9em;
    flex-wrap: wrap;
}

.products[data-showcase-v2] .q-kpi {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25em;
    min-width: 0;
}

.products[data-showcase-v2] .q-kpi-l {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    color: var(--q-text-2);
    font-size: 0.92em;
    line-height: 1.2;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-kpi-v {
    color: var(--q-text);
    font-size: 1.5em;
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.012em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-kpi-v.is-hero {
    font-size: 2.05em;
    letter-spacing: -0.018em;
}

.products[data-showcase-v2] .q-kpi-v.is-money { color: var(--q-positive-text); }

/* ------------------------------------------------------------------ */
/* Cards — border only, never a shadow                                 */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.8em;
    min-width: 0;
    padding: 1.15em 1.25em;
    border: 1px solid var(--q-border);
    border-radius: var(--q-r-card);
    background: var(--q-bg);
}

/* sparklines may bleed to the card's bottom edge */
.products[data-showcase-v2] .q-card.is-flush { padding-bottom: 0; overflow: hidden; }

.products[data-showcase-v2] .q-card-h {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8em;
}

.products[data-showcase-v2] .q-card-t {
    color: var(--q-text);
    font-size: 1.15em;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.008em;
}

.products[data-showcase-v2] .q-card-sub {
    color: var(--q-text-2);
    font-size: 0.92em;
    line-height: 1.5;
}

.products[data-showcase-v2] .q-grid2 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.1em;
}

/* body copy: gray text for 70% of words */
.products[data-showcase-v2] .q-body {
    color: var(--q-text-2);
    font-size: 1em;
    line-height: 1.55;
}

.products[data-showcase-v2] .q-body b,
.products[data-showcase-v2] .q-body strong {
    color: var(--q-text);
    font-weight: 500;
}

.products[data-showcase-v2] .q-body em {
    color: var(--q-warning);
    font-style: normal;
    font-weight: 500;
}

/* technical terms with a definition */
.products[data-showcase-v2] .q-term {
    border-bottom: 1px dotted var(--q-text-3);
    cursor: help;
}

/* raw paths and ids are the only mono in the system */
.products[data-showcase-v2] .q-raw {
    font-family: var(--mono);
    font-size: 0.9em;
    letter-spacing: 0;
}

.products[data-showcase-v2] .num { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ */
/* List tables — rounded zebra strips, no gridlines anywhere           */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-tbl {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.products[data-showcase-v2] .q-tr {
    display: grid;
    align-items: center;
    gap: 0.8em;
    min-height: 2.9em;
    padding: 0 0.8em;
    border-radius: var(--q-r-row);
    font-size: 1em;
    transition: background 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-tbl .q-tr:nth-of-type(odd) { background: var(--q-bg-subtle); }

.products[data-showcase-v2] .q-tr.is-head {
    min-height: 2.2em;
    background: none !important;
    color: var(--q-text-2);
    font-size: 0.92em;
}

.products[data-showcase-v2] .q-tr-n {
    display: flex;
    align-items: center;
    gap: 0.6em;
    min-width: 0;
    color: var(--q-text);
}

.products[data-showcase-v2] .q-tr-n > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* favicon chip: rounded square. flag: circle. */
.products[data-showcase-v2] .q-fav {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 1.4em;
    height: 1.4em;
    border-radius: 0.34em;
    background: var(--q-bg-hover);
    color: var(--q-text-2);
    font-size: 0.92em;
    font-weight: 600;
    line-height: 1;
    overflow: hidden;
}

.products[data-showcase-v2] .q-fav.is-flag { border-radius: 50%; }

.products[data-showcase-v2] .q-fav svg { width: 0.95em; height: 0.95em; }

.products[data-showcase-v2] .q-num-c {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--q-text);
    white-space: nowrap;
}

.products[data-showcase-v2] .q-num-c.is-mut { color: var(--q-text-2); }

/* ------------------------------------------------------------------ */
/* Score ring                                                          */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-ring {
    position: relative;
    flex: 0 0 auto;
    width: 7.4em;
    height: 7.4em;
}

.products[data-showcase-v2] .q-ring.is-sm { width: 4.6em; height: 4.6em; }

.products[data-showcase-v2] .q-ring svg {
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}

.products[data-showcase-v2] .q-ring-track {
    fill: none;
    stroke: var(--q-ring-track);
    stroke-width: 3.4;
}

.products[data-showcase-v2] .q-ring-arc {
    fill: none;
    stroke: var(--q-positive);
    stroke-width: 3.4;
    stroke-linecap: round;
    stroke-dasharray: 0 100;
    transition: stroke-dasharray 900ms var(--ease-out), stroke 300ms ease;
}

.products[data-showcase-v2] .q-ring-arc.is-warn { stroke: var(--q-warning); }
.products[data-showcase-v2] .q-ring-arc.is-bad { stroke: var(--q-negative); }
.products[data-showcase-v2] .q-ring-arc.is-brand { stroke: var(--q-brand); }

.products[data-showcase-v2] .q-ring-c {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: var(--q-text);
    font-size: 3em;
    font-weight: 600;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-ring.is-sm .q-ring-c { font-size: 1.9em; }

.products[data-showcase-v2] .q-verdict {
    color: var(--q-text);
    font-size: 1.75em;
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.018em;
}

/* ------------------------------------------------------------------ */
/* Charts — no plot borders, no axis lines, no chart backgrounds       */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-chart {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
}

.products[data-showcase-v2] .q-plot {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
}

/* 1–3 dotted gridlines, each labeled by a tiny number above its left end */
.products[data-showcase-v2] .q-gl {
    position: absolute;
    left: 0;
    right: 0;
    border-top: 1px dotted var(--q-grid-dot);
}

.products[data-showcase-v2] .q-gl b {
    position: absolute;
    left: 1.5em;
    bottom: 0.3em;
    color: var(--q-text-3);
    font-size: 0.78em;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-xaxis {
    position: absolute;
    left: 1.5em;
    right: 1.5em;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: var(--q-text-3);
    font-size: 0.78em;
    font-variant-numeric: tabular-nums;
}

/* the "current" time label is a chip; every other label is bare text */
.products[data-showcase-v2] .q-xaxis .is-now {
    padding: 0.2em 0.5em;
    border-radius: var(--q-r-full);
    background: var(--q-bg-subtle);
    color: var(--q-text-2);
}

/* a thin light vertical line marks "now" */
.products[data-showcase-v2] .q-nowline {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--q-border-strong);
    pointer-events: none;
}

.products[data-showcase-v2] .q-line {
    fill: none;
    stroke: var(--q-brand);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.products[data-showcase-v2] .q-line.is-ctx { stroke: var(--q-context); }
.products[data-showcase-v2] .q-line.is-pos { stroke: var(--q-positive); }

/* the fill is mist, not paint */
.products[data-showcase-v2] .q-area { stroke: none; }

/* chart lines draw in once */
.products[data-showcase-v2] .q-line.q-draw {
    stroke-dasharray: var(--q-len, 400);
    stroke-dashoffset: var(--q-len, 400);
}

.products[data-showcase-v2] .q-line.q-draw.in {
    transition: stroke-dashoffset 1100ms var(--ease-out);
    stroke-dashoffset: 0;
}

.products[data-showcase-v2] .q-area.q-fade { opacity: 0; transition: opacity 700ms ease 320ms; }
.products[data-showcase-v2] .q-area.q-fade.in { opacity: 1; }

/* money on the timeline: green rounded-cap bars sharing the baseline */
.products[data-showcase-v2] .q-bar {
    fill: var(--q-positive);
    rx: 3;
}

/* ------------------------------------------------------------------ */
/* Annotation markers — icon-in-circle on a dashed vertical rule       */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-annot {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    pointer-events: none;
}

.products[data-showcase-v2] .q-annot::before {
    content: '';
    position: absolute;
    top: 1.6em;
    bottom: 0;
    left: 0;
    border-left: 1px dashed var(--q-context);
}

.products[data-showcase-v2] .q-annot i {
    position: absolute;
    top: 0;
    left: 0;
    display: grid;
    place-items: center;
    width: 1.85em;
    height: 1.85em;
    border: 1px solid var(--q-border);
    border-radius: 50%;
    background: var(--q-bg);
    color: var(--q-text-2);
    box-shadow: var(--q-sh-float);
    transform: translateX(-50%);
}

.products[data-showcase-v2] .q-annot i svg { width: 0.92em; height: 0.92em; }

.products[data-showcase-v2] .q-annot.is-live::before { border-left-color: var(--q-warning); }
.products[data-showcase-v2] .q-annot.is-live i { color: var(--q-warning); }

/* ------------------------------------------------------------------ */
/* Floating label chips — they sit ON TOP of the visualization         */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-chipf {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    padding: 0.4em 0.65em;
    border: 1px solid var(--q-border);
    border-radius: var(--q-r-full);
    background: var(--q-bg);
    box-shadow: var(--q-sh-float);
    font-size: 0.92em;
    line-height: 1;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-chipf b {
    color: var(--q-text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-chipf span { color: var(--q-text-2); font-variant-numeric: tabular-nums; }

.products[data-showcase-v2] .q-chipf svg { width: 1em; height: 1em; color: var(--q-text-2); }

/* tooltip: white card, soft shadow */
.products[data-showcase-v2] .q-tip {
    position: absolute;
    z-index: 4;
    display: flex;
    flex-direction: column;
    gap: 0.15em;
    padding: 0.5em 0.7em;
    border: 1px solid var(--q-border);
    border-radius: 0.77em;
    background: var(--q-bg);
    box-shadow: var(--q-sh-float);
    font-size: 0.92em;
    line-height: 1.3;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transform: translate(-50%, calc(-100% - 1em)) scale(0.96);
    transition: opacity 180ms ease, transform 220ms var(--ease-out);
}

.products[data-showcase-v2] .q-tip.in { opacity: 1; transform: translate(-50%, calc(-100% - 0.7em)) scale(1); }

.products[data-showcase-v2] .q-tip b { color: var(--q-text); font-weight: 600; font-variant-numeric: tabular-nums; }
.products[data-showcase-v2] .q-tip span { color: var(--q-text-2); }

/* the marker dot that rides the line */
.products[data-showcase-v2] .q-mark-dot {
    position: absolute;
    z-index: 3;
    width: 0.62em;
    height: 0.62em;
    border-radius: 50%;
    background: var(--q-brand);
    box-shadow: 0 0 0 0.25em color-mix(in srgb, var(--q-brand) 18%, transparent);
    transform: translate(-50%, -50%) scale(0.5);
    opacity: 0;
    transition: opacity 180ms ease, transform 220ms var(--ease-out), left 260ms var(--ease-out), top 260ms var(--ease-out);
    pointer-events: none;
}

.products[data-showcase-v2] .q-mark-dot.in { opacity: 1; transform: translate(-50%, -50%) scale(1); }

/* ------------------------------------------------------------------ */
/* Activity dot grid — hollow circles, filled where something happened */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-dots {
    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(5, auto);
    gap: 0.42em;
    justify-content: start;
}

.products[data-showcase-v2] .q-dots i {
    width: 0.5em;
    height: 0.5em;
    border: 1px solid var(--q-grid-dot);
    border-radius: 50%;
    transition: background 260ms var(--ease-out), border-color 260ms var(--ease-out);
}

.products[data-showcase-v2] .q-dots i.on {
    background: var(--q-positive);
    border-color: var(--q-positive);
}

.products[data-showcase-v2] .q-dots i.on.is-brand {
    background: var(--q-brand);
    border-color: var(--q-brand);
}

.products[data-showcase-v2] .q-dots i.on.is-warn {
    background: var(--q-warning);
    border-color: var(--q-warning);
}

/* ------------------------------------------------------------------ */
/* Realtime strip — dense rounded bars, conversions get a green dot    */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-rt {
    display: flex;
    align-items: flex-end;
    gap: 0.24em;
    height: 3.4em;
}

.products[data-showcase-v2] .q-rt i {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    border-radius: var(--q-r-full);
    background: color-mix(in srgb, var(--q-brand) 70%, transparent);
    transform-origin: 50% 100%;
    transform: scaleY(0);
    transition: transform 420ms var(--ease-out);
}

.products[data-showcase-v2] .q-rt i.in { transform: scaleY(1); }

.products[data-showcase-v2] .q-rt i.has-cv::after {
    content: '';
    position: absolute;
    left: 50%;
    top: -0.75em;
    width: 0.42em;
    height: 0.42em;
    border-radius: 50%;
    background: var(--q-positive);
    transform: translateX(-50%);
}

/* ------------------------------------------------------------------ */
/* Empty states — a thin-line icon and a tiny story                    */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.7em;
    padding: 2em 1em;
    text-align: center;
    color: var(--q-text-2);
    font-size: 1em;
    line-height: 1.5;
}

.products[data-showcase-v2] .q-empty svg {
    width: 1.7em;
    height: 1.7em;
    color: var(--q-text-3);
}

/* ------------------------------------------------------------------ */
/* The floating dock — the one dark object                             */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-dock {
    position: absolute;
    z-index: 6;
    bottom: 1.15em;
    left: 50%;
    display: flex;
    align-items: center;
    gap: 0.3em;
    padding: 0.45em;
    border-radius: var(--q-r-full);
    background: var(--q-dock-bg);
    box-shadow: var(--q-sh-dock);
    transform: translateX(-50%);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
}

.products[data-showcase-v2] .q-dock button {
    display: grid;
    place-items: center;
    /* `font: inherit` is load-bearing, not tidiness: without it a button falls
       back to the UA's own font-size (13.33px in Chrome, 16px elsewhere) while
       the dock's padding around it stays em — making the dock's height a px/em
       mixture that no em constant can reserve space for. A scene's dock floor
       then collides with its content on any UA whose button font differs from
       the one it was measured on. */
    font: inherit;
    width: 2.7em;
    height: 2.7em;
    padding: 0;
    border: 0;
    border-radius: var(--q-r-full);
    background: none;
    color: var(--q-dock-icon);
    cursor: pointer;
    transition: color 180ms var(--ease-out), background 180ms var(--ease-out), transform 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-dock button svg { width: 1.35em; height: 1.35em; }

.products[data-showcase-v2] .q-dock button[aria-pressed='true'] {
    color: var(--q-dock-on-ink);
    background: var(--q-dock-on-bg);
}

/* the one colored thing in the dock — it makes the product feel alive */
.products[data-showcase-v2] .q-live {
    display: flex;
    align-items: center;
    gap: 0.45em;
    padding: 0 0.9em 0 0.7em;
    color: var(--q-brand);
    font-size: 1em;
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-live svg {
    width: 1.15em;
    height: 1.15em;
    animation: qPulse 3s ease-in-out infinite;
}

/* ------------------------------------------------------------------ */
/* Focus + motion                                                      */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-app :focus-visible {
    outline: 2px solid var(--q-brand-strong);
    outline-offset: 2px;
    border-radius: 4px;
}

/* engine-driven reveals: nothing bounces, nothing slides far */
.products[data-showcase-v2] [data-rise] {
    opacity: 0;
    transform: translateY(5px);
    transition: opacity 340ms ease, transform 420ms var(--ease-out);
}

.products[data-showcase-v2] [data-rise].in {
    opacity: 1;
    transform: none;
}

.products[data-showcase-v2] .prod-scene-v2.steady [data-rise] {
    transition: none;
    opacity: 1;
    transform: none;
}

.products[data-showcase-v2] .caret {
    display: inline-block;
    width: 1px;
    height: 1.15em;
    margin-left: 1px;
    background: var(--q-brand);
    vertical-align: text-bottom;
    animation: qCaret 1.05s steps(2, start) infinite;
}

/* thinking dots */
.products[data-showcase-v2] .think {
    display: inline-flex;
    align-items: center;
    gap: 0.24em;
}

.products[data-showcase-v2] .think i {
    width: 0.32em;
    height: 0.32em;
    border-radius: 50%;
    background: var(--q-text-3);
    animation: qThink 1.25s ease-in-out infinite;
}

.products[data-showcase-v2] .think i:nth-child(2) { animation-delay: 0.16s; }
.products[data-showcase-v2] .think i:nth-child(3) { animation-delay: 0.32s; }

@media (hover: hover) and (pointer: fine) {
    .products[data-showcase-v2] .q-pill:hover { background: var(--q-bg-hover); border-color: var(--q-border-strong); }
    .products[data-showcase-v2] .q-seg .q-pill:hover:not([aria-pressed='true']) { background: var(--q-bg-hover); border-color: transparent; }
    .products[data-showcase-v2] .q-proj:hover { background: var(--q-bg-subtle); }
    .products[data-showcase-v2] .q-link:hover { background: var(--q-bg-subtle); color: var(--q-text); }
    .products[data-showcase-v2] .q-tbl .q-tr:not(.is-head):hover { background: var(--q-bg-hover); }
    .products[data-showcase-v2] .q-dock button:hover { color: var(--q-dock-on-ink); transform: scale(1.05); }
}
/* ================================================================== */
/* CORTEX — evidence view                                             */
/* ================================================================== */

/* the mode line, quiet, before the avatar */
.products[data-showcase-v2] .q-cx-mode {
    margin-right: 0.35em;
    color: var(--q-text-2);
    font-size: 0.92em;
    white-space: nowrap;
}

/* the question select: a long string, so it truncates instead of pushing */
.products[data-showcase-v2] .q-cx-qpill {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 30em;
}

.products[data-showcase-v2] .q-cx-qpill > span:not(.q-pill-ch) {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-cx-qpill.is-typing > span:not(.q-pill-ch)::after {
    content: '';
    display: inline-block;
    width: 1px;
    height: 1.05em;
    margin-left: 1px;
    background: var(--q-brand);
    vertical-align: text-bottom;
    animation: qCaret 1.05s steps(2, start) infinite;
}

/* permissions: a status chip, not a control. The glyph stays gray per the
   icon system (§2.6) — the earned green lives in the sync dot (status) and
   the done check, and three greens in one view is noise. */
.products[data-showcase-v2] .q-cx-perm {
    flex: 0 0 auto;
    height: 2.6em;
    padding: 0 0.9em;
}

.products[data-showcase-v2] .q-cx-perm > span { color: var(--q-text-2); }

/* the evidence filter is a real toggle, so it has to look pressed */
.products[data-showcase-v2] .q-cx-only[aria-pressed='true'] {
    background: var(--q-chip-brand-bg);
    border-color: var(--q-brand-soft);
}

.products[data-showcase-v2] .q-cx-only[aria-pressed='true'] svg { color: var(--q-brand-strong); }

/* ---- the answer zone: the empty state holds its space ------------- */

.products[data-showcase-v2] .q-cx-top {
    position: relative;
    min-height: 10.5em;
}

/* .q-empty's own 2em block padding overflows this box once the story copy
   wraps to three lines — trim it rather than let it sit under the table */
.products[data-showcase-v2] .q-cx-empty {
    position: absolute;
    inset: 0;
    max-width: 26em;
    margin: 0 auto;
    padding: 1.2em 1em;
    transition: opacity 300ms ease;
}

.products[data-showcase-v2] .q-cx-top.is-live .q-cx-empty {
    opacity: 0;
    pointer-events: none;
}

.products[data-showcase-v2] .q-cx-live {
    display: flex;
    flex-direction: column;
    gap: 0.85em;
    opacity: 0;
    transition: opacity 320ms ease;
}

.products[data-showcase-v2] .q-cx-top.is-live .q-cx-live { opacity: 1; }

/* the process line — one line, never a log */
.products[data-showcase-v2] .q-cx-stream {
    display: flex;
    align-items: center;
    gap: 0.5em;
    min-height: 1.7em;
    color: var(--q-text-2);
    font-size: 0.92em;
}

/* the slot keeps its width when the shared reduced-motion block
   display:none's .think — otherwise the step text jumps sideways */
.products[data-showcase-v2] .q-cx-ic {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15em;
}

.products[data-showcase-v2] .q-cx-ic.is-ok svg {
    width: 1.05em;
    height: 1.05em;
    color: var(--q-positive);
}

.products[data-showcase-v2] [data-cx-step].is-set { animation: qCxStep 260ms var(--ease-out); }

@keyframes qCxStep {
    from { opacity: 0; transform: translateY(2px); }
    to { opacity: 1; transform: none; }
}

/* the answer: gray explainer voice, near-black claims */
.products[data-showcase-v2] .q-cx-ans {
    margin: 0;
    color: var(--q-text-2);
    font-size: 1.15em;
    line-height: 1.58;
    letter-spacing: -0.002em;
}

.products[data-showcase-v2] .q-cx-ans b {
    color: var(--q-text-2);
    font-weight: 400;
    border-radius: 0.3em;
    transition: color 320ms var(--ease-out), background 180ms var(--ease-out), box-shadow 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-cx-ans.is-ink b {
    color: var(--q-text);
    font-weight: 500;
}

.products[data-showcase-v2] .q-cx-ans b.is-on {
    background: var(--q-chip-brand-bg);
    box-shadow: 0 0 0 0.16em var(--q-chip-brand-bg);
}

/* the citation itself: a real, hoverable, focusable mark */
.products[data-showcase-v2] .q-cx-ans sup {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.45em;
    height: 1.45em;
    margin: 0 0.1em;
    padding: 0 0.3em;
    border-radius: var(--q-r-full);
    background: var(--q-chip-brand-bg);
    color: var(--q-brand-strong);
    font-size: 0.68em;
    font-weight: 600;
    line-height: 1;
    vertical-align: super;
    font-variant-numeric: tabular-nums;
    transition: background 180ms var(--ease-out), color 180ms var(--ease-out), transform 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-cx-ans sup.is-on,
.products[data-showcase-v2] .q-cx-ans sup:hover,
.products[data-showcase-v2] .q-cx-ans sup:focus-within {
    background: var(--q-brand);
    color: var(--q-bg);
    transform: translateY(-0.06em) scale(1.06);
}

.products[data-showcase-v2] .q-cx-sup {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    line-height: 1;
    cursor: pointer;
}

/* ---- the evidence: rounded zebra + the chip that flies to a row --- */

.products[data-showcase-v2] .q-cx-ev { position: relative; }

.products[data-showcase-v2] .q-cx-tr { grid-template-columns: minmax(0, 1fr) auto; }

.products[data-showcase-v2] .q-cx-tbl .q-cx-tr {
    transition: background 180ms var(--ease-out), opacity 220ms var(--ease-out);
}

/* a source the answer leaned on keeps a quiet mark at rest */
.products[data-showcase-v2] .q-cx-tr.is-cited .q-fav {
    background: var(--q-chip-brand-bg);
    color: var(--q-brand-strong);
}

.products[data-showcase-v2] .q-cx-tbl .q-cx-tr.is-lit { background: var(--q-bg-hover); }

/* must stay after the is-cited rule — equal specificity, lit has to win */
.products[data-showcase-v2] .q-cx-tr.is-lit .q-fav {
    background: var(--q-brand);
    color: var(--q-bg);
}

.products[data-showcase-v2] .q-cx-tr.is-off { opacity: 0.32; }

.products[data-showcase-v2] .q-cx-tr.is-pulse { animation: qCxPulse 780ms var(--ease-out); }

@keyframes qCxPulse {
    from { box-shadow: inset 0 0 0 1px var(--q-brand); }
    to { box-shadow: inset 0 0 0 1px transparent; }
}

.products[data-showcase-v2] .q-cx-fchip {
    position: absolute;
    z-index: 4;
    top: 0;
    left: 56%;
    max-width: 58%;
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.94);
    transition: opacity 180ms ease, transform 220ms var(--ease-out), top 240ms var(--ease-out);
    pointer-events: none;
}

.products[data-showcase-v2] .q-cx-fchip.in {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
}

.products[data-showcase-v2] .q-cx-fchip svg { flex: 0 0 auto; }

/* an inline <b> ignores overflow — it has to be a block flex item with
   min-width:0 before text-overflow can do anything */
.products[data-showcase-v2] .q-cx-fchip b {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---- the corpus signal ------------------------------------------- */

.products[data-showcase-v2] .q-cx-idx {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 0.7em;
}

.products[data-showcase-v2] .q-cx-idxh {
    display: flex;
    align-items: center;
    gap: 0.8em;
    color: var(--q-text-2);
    font-size: 0.92em;
}

.products[data-showcase-v2] .q-cx-idxh b {
    color: var(--q-text);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-cx-sync {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    margin-left: auto;
    color: var(--q-text-3);
}

.products[data-showcase-v2] .q-cx-idx .q-dots i.is-fresh { animation: qCxFresh 900ms var(--ease-out); }

@keyframes qCxFresh {
    from { box-shadow: 0 0 0 0 var(--q-brand); }
    to { box-shadow: 0 0 0 0.42em transparent; }
}

/* the permission story, quiet: a footer line, not a banner */
.products[data-showcase-v2] .q-cx-foot {
    padding-top: 0.15em;
    color: var(--q-text-3);
    font-size: 0.85em;
    line-height: 1.4;
}

/* ================================================================== */
/* PRISM — overview                                                    */
/* The archetype: a KPI row, a full-bleed time-series that owns the    */
/* screen, and a 2x2 of cards under it. Everything here positions and  */
/* composes the library; the scene-specific anatomy is the plot box    */
/* the deals and the annotation hang in, the lens menu, and the        */
/* report chip that floats over the whole thing.                       */
/* ================================================================== */

/* The dock floats over the view, so the content keeps a floor clear of it.
   That floor is not expressible in em. `.q-dock button` never sets
   `font: inherit`, so its 2.7em box is 2.7 x the UA's own button font — a px
   constant the app's em scale knows nothing about — while the dock's padding
   around it IS em. prismInit() measures the dock and publishes its real height
   here as --q-pr-dock, so this reserves exactly what the dock takes at any
   --q-fs, in any browser.
   Budget: the dock's top sits (--q-pr-dock + 1.15em) above the app's floor and
   .q-view already pays 1.5em of that, so this owes the rest plus 0.6em of air
   → --q-pr-dock + 1.15em - 1.5em + 0.6em. The fallback only ever paints the
   first frame, before fitFloor() lands. */
.products[data-showcase-v2] .q-pr-wrap {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 1.05em;
    min-height: 0;
    padding-bottom: calc(var(--q-pr-dock, 4.7em) + 0.25em);
}

/* "updated 09:42" is meta, not chrome: it sits quiet next to the avatar */
.products[data-showcase-v2] .q-pr-upd {
    color: var(--q-text-3);
    font-size: 0.92em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ------------------------------------------------------------------ */
/* The lens select — the "what" of the control row                     */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-pr-mwrap {
    position: relative;
    display: inline-flex;
}

.products[data-showcase-v2] .q-pr-menu {
    position: absolute;
    z-index: 7;
    top: calc(100% + 0.4em);
    left: 0;
    display: flex;
    flex-direction: column;
    gap: 0.1em;
    min-width: 100%;
    padding: 0.35em;
    border: 1px solid var(--q-border);
    border-radius: 0.9em;
    background: var(--q-bg);
    box-shadow: var(--q-sh-float);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-4px);
    transition:
        opacity 160ms ease,
        transform 200ms var(--ease-out),
        visibility 0s linear 200ms;
}

.products[data-showcase-v2] .q-pr-menu.is-open {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
}

.products[data-showcase-v2] .q-pr-mi {
    display: flex;
    align-items: center;
    gap: 0.55em;
    padding: 0.5em 0.7em;
    border: 0;
    border-radius: var(--q-r-full);
    background: none;
    color: var(--q-text-2);
    font: inherit;
    font-size: 1em;
    line-height: 1;
    white-space: nowrap;
    text-align: left;
    cursor: pointer;
    transition: background 160ms var(--ease-out), color 160ms var(--ease-out);
}

.products[data-showcase-v2] .q-pr-mi-ic {
    display: grid;
    place-items: center;
    line-height: 0;
}

.products[data-showcase-v2] .q-pr-mi-ic svg {
    width: 1.15em;
    height: 1.15em;
    color: inherit;
}

.products[data-showcase-v2] .q-pr-mi[aria-current='true'] {
    background: var(--q-chip-brand-bg);
    color: var(--q-brand-strong);
}

/* off = the comparison line is hidden; the pill reads as unlit, not broken */
.products[data-showcase-v2] .q-pr-cmp[aria-pressed='false'] {
    background: var(--q-bg-subtle);
    box-shadow: none;
}

.products[data-showcase-v2] .q-pr-cmp[aria-pressed='false'] svg { color: var(--q-text-3); }

/* ------------------------------------------------------------------ */
/* KPI row — five readings, one of them drawn                          */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-pr-kpis {
    flex: 0 0 auto;
    flex-wrap: nowrap;
    gap: 0;
    justify-content: space-between;
}

.products[data-showcase-v2] .q-pr-kpi { gap: 0.2em; }

/* §4.3's series dot is a promise about the chart, so only the lens that
   is actually drawn wears one — hidden, not removed, so the four others
   keep the same baseline instead of shuffling on every switch */
.products[data-showcase-v2] .q-pr-kpi .q-kpi-l .q-dot {
    opacity: 0;
    transition: opacity 200ms var(--ease-out);
}

.products[data-showcase-v2] .q-pr-kpi.is-on .q-kpi-l .q-dot { opacity: 1; }

/* ------------------------------------------------------------------ */
/* The hero chart — the tallest thing on the screen                    */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-pr-chart {
    flex: 1 1 auto;
    min-height: 8em;
}

/* the plot stops above the axis so the deals rise from the line's own
   baseline instead of out from under the tick labels */
.products[data-showcase-v2] .q-pr-plot {
    position: absolute;
    inset: 0 0 1.6em 0;
}

/* scoped to the scene: grid draws a context series out of the same
   primitive, and an unscoped rule here would reach into it */
.products[data-showcase-v2] .q-pr-chart .q-line.is-ctx {
    opacity: 1;
    transition: opacity 220ms ease;
}

.products[data-showcase-v2] .q-pr-chart.no-ctx .q-line.is-ctx { opacity: 0; }

/* §5.3 money on the timeline. Rounded-cap bars have to be boxes, not
   <rect>s: the plot's viewBox is preserveAspectRatio="none", which would
   squash rx into an ellipse and melt the cap the spec asks for. */
.products[data-showcase-v2] .q-pr-bars {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.products[data-showcase-v2] .q-pr-bars i {
    position: absolute;
    bottom: 0;
    width: 0.42em;
    border-radius: var(--q-r-full);
    background: var(--q-positive);
    transform: translateX(-50%) scaleY(0);
    transform-origin: 50% 100%;
    transition: transform 420ms var(--ease-out);
}

.products[data-showcase-v2] .q-pr-bars i.in { transform: translateX(-50%) scaleY(1); }

/* the peak is the last slot in every period, so this amber rule is also
   the "now" line — one moment deserves one mark */
.products[data-showcase-v2] .q-pr-annot { z-index: 2; }

/* High points sit right under the band the marker hangs in, so the card
   flips below the dot there instead of climbing out of the plot. */
.products[data-showcase-v2] .q-pr-chart .q-tip.is-under {
    transform: translate(-50%, 1em) scale(0.96);
}

.products[data-showcase-v2] .q-pr-chart .q-tip.is-under.in {
    transform: translate(-50%, 0.7em) scale(1);
}

/* ------------------------------------------------------------------ */
/* The 2x2 — the questions the line raises                             */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-pr-cards {
    flex: 0 0 auto;
    grid-template-rows: auto auto;
    gap: 0.85em;
}

.products[data-showcase-v2] .q-pr-card {
    gap: 0.4em;
    padding: 0.7em 0.9em;
}

.products[data-showcase-v2] .q-pr-card .q-card-t { font-size: 1em; }

/* the directions table and the directions lens are the same fact */
.products[data-showcase-v2] .q-pr-card.is-rg.is-lens { border-color: var(--q-brand-soft); }

.products[data-showcase-v2] .q-pr-rg .q-tr {
    grid-template-columns: minmax(0, 1fr) auto 2.6em;
    min-height: 1.6em;
    gap: 0.5em;
    padding: 0 0.5em;
    font-size: 0.92em;
}

.products[data-showcase-v2] .q-pr-rg .q-fav {
    width: 1.25em;
    height: 1.25em;
    font-size: 0.85em;
}

/* the sparkline bleeds to the card's bottom edge (§4.5) */
.products[data-showcase-v2] .q-pr-card.is-flush { justify-content: space-between; }

.products[data-showcase-v2] .q-pr-spark {
    display: block;
    width: calc(100% + 1.8em);
    height: 2.8em;
    margin: 0 -0.9em -0.05em;
}

.products[data-showcase-v2] .q-pr-card.is-flush .q-kpi-v { font-size: 1.35em; }

/* §5.6 the realtime strip */
.products[data-showcase-v2] .q-pr-rt-t {
    display: flex;
    align-items: baseline;
    gap: 0.3em;
    min-width: 0;
}

.products[data-showcase-v2] .q-pr-rt-t b {
    color: var(--q-text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-pr-rt-t > span {
    overflow: hidden;
    color: var(--q-text-2);
    font-size: 0.92em;
    font-weight: 400;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-pr-card.is-rt .q-rt {
    height: 2.2em;
    margin-top: auto;
}

/* the hero number: one card, one reading, money-green (§4.5) */
.products[data-showcase-v2] .q-pr-hero-t {
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
}

.products[data-showcase-v2] .q-pr-card.is-hero .q-kpi-v {
    margin-top: auto;
    font-size: 1.85em;
}

/* ------------------------------------------------------------------ */
/* The report — a quiet chip that floats off, never a toast            */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-pr-exp {
    position: absolute;
    z-index: 5;
    top: 0.2em;
    /* clear of the annotation marker, which owns the far right of this band */
    right: 3.4em;
    max-width: calc(100% - 5em);
    align-items: center;
    gap: 0.55em;
    padding: 0.55em 0.8em;
    opacity: 0;
    transform: translateY(0.5em);
    transition: opacity 220ms ease, transform 300ms var(--ease-out);
    pointer-events: none;
}

.products[data-showcase-v2] .q-pr-exp.in { opacity: 1; transform: none; }

.products[data-showcase-v2] .q-pr-exp-ic {
    display: grid;
    place-items: center;
    line-height: 0;
    color: var(--q-text-2);
}

.products[data-showcase-v2] .q-pr-exp-ic svg { width: 1.15em; height: 1.15em; }

.products[data-showcase-v2] .q-pr-exp-tx {
    display: flex;
    flex-direction: column;
    gap: 0.15em;
    min-width: 0;
}

.products[data-showcase-v2] .q-pr-exp-tx b {
    overflow: hidden;
    color: var(--q-text);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-pr-exp-tx > span {
    color: var(--q-text-2);
    font-size: 0.85em;
}

@media (hover: hover) and (pointer: fine) {
    .products[data-showcase-v2] .q-pr-mi:hover { background: var(--q-bg-subtle); color: var(--q-text); }
    .products[data-showcase-v2] .q-pr-mi[aria-current='true']:hover { background: var(--q-chip-brand-bg); color: var(--q-brand-strong); }
}

/* ================================================================== */
/* STUDIO — builder                                                    */
/* The canvas holds a real quiet-analytics page assembled out of the    */
/* library above; this section only positions the builder's own         */
/* anatomy — palette, work canvas, page sheet, inspector.               */
/* ================================================================== */

/* the palette is the widest control row in the set; let it wrap rather
   than overflow if a locale runs long. Measured: it does not wrap in
   ru/en/tg (row is 3.59-3.63em at every viewport) — this is a valve. */
.products[data-showcase-v2] [data-scene='studio'] .q-ctl { flex-wrap: wrap; row-gap: 0.5em; }

.products[data-showcase-v2] .q-st-palette {
    display: flex;
    align-items: center;
    gap: 0.35em;
    min-width: 0;
    flex-wrap: wrap;
}

/* Palette pill, three states read left to right: available (all gray),
   on the page (name darkens, glyph turns brand), selected (brand ring —
   the same ring its block wears out on the canvas). */
.products[data-showcase-v2] .q-pill.q-st-tool {
    padding: 0 0.7em;
    color: var(--q-text-2);
}

.products[data-showcase-v2] .q-pill.q-st-tool svg { width: 1.05em; height: 1.05em; }

.products[data-showcase-v2] .q-pill.q-st-tool.is-on { color: var(--q-text); }
.products[data-showcase-v2] .q-pill.q-st-tool.is-on svg { color: var(--q-brand); }

.products[data-showcase-v2] .q-pill.q-st-tool[aria-pressed='true'] {
    border-color: var(--q-brand);
    color: var(--q-text);
}

.products[data-showcase-v2] .q-pill.q-st-tool.is-press { background: var(--q-bg-hover); }

/* glyph-only device switch — .q-seg .q-pill already sets the height, so
   the icon variant only needs its own square footprint */
.products[data-showcase-v2] .q-seg .q-pill.q-st-dev {
    width: 2.5em;
    padding: 0;
    justify-content: center;
}

.products[data-showcase-v2] .q-seg .q-pill.q-st-dev svg { width: 1.15em; height: 1.15em; }
.products[data-showcase-v2] .q-seg .q-pill.q-st-dev[aria-pressed='true'] svg { color: var(--q-text); }

/* "saved" is the scene's quiet live detail: a dot, never a badge */
.products[data-showcase-v2] .q-st-save {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    margin-right: 0.2em;
    color: var(--q-text-2);
    font-size: 0.92em;
    white-space: nowrap;
}

/* the top bar carries the document chrome; it is the only row in the set
   with three controls in it, so it keeps its own tighter rhythm */
.products[data-showcase-v2] [data-scene='studio'] .q-top { gap: 0.55em; }

/* publish: one pill whose glyph slot carries the state — cloud, then a
   live amber dot, then a green one */
.products[data-showcase-v2] .q-st-pub-ic {
    display: grid;
    place-items: center;
    width: 1.25em;
    height: 1.25em;
    line-height: 0;
}

.products[data-showcase-v2] .q-pill.q-st-pub[aria-disabled='true'] {
    color: var(--q-text-2);
    cursor: default;
}

/* ------------------------------------------------------------------ */
/* The stage: a recessed work canvas + a small properties card         */
/* ------------------------------------------------------------------ */

/* The work canvas takes the whole width and the inspector sits under it as
   a strip — a side rail would have left a 14em column of dead white beside
   a 44em canvas, and would have squeezed the page sheet to phone width in
   "desktop" mode, which is the one thing this scene cannot afford: the
   device toggle has to read as a real reflow. */
.products[data-showcase-v2] .q-st-stage {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 1.05em;
}

.products[data-showcase-v2] .q-st-work {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
}

/* the one recessed surface in the scene — the page sheet floats on it */
.products[data-showcase-v2] .q-st-canvas {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    padding: 0.95em;
    border-radius: var(--q-r-card);
    background: var(--q-bg-subtle);
    /* Clipped, never user-scrollable: a scroll container inside a marketing
       page is a scroll trap, and the page sheet is meant to run past the
       fold anyway — that is what a page taller than its viewport looks
       like. It still scrolls programmatically, which is how the canvas
       follows a block that lands below the fold — on the timeline, not on
       CSS smooth-scroll, which nothing here could cancel. */
    overflow: hidden;
}

.products[data-showcase-v2] .q-st-page {
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.95em;
    width: 100%;
    max-width: 64em;
    margin: 0 auto;
    padding: 0.95em 1.1em 1em;
    border: 1px solid var(--q-border);
    border-radius: 0.92em;
    background: var(--q-bg);
    font-size: 0.92em;
    transition: max-width 340ms var(--ease-out);
}

/* the device toggle really reflows the page into a narrow column
   (measured: 43.4em -> 20.2em of real page width, not a scale trick) */
.products[data-showcase-v2] .q-st-canvas.is-mobile .q-st-page { max-width: 22em; }

.products[data-showcase-v2] .q-st-nav {
    display: flex;
    align-items: center;
    gap: 0.6em;
    min-width: 0;
    padding-bottom: 0.85em;
    border-bottom: 1px solid var(--q-border);
}

.products[data-showcase-v2] .q-st-nav-m {
    flex: 0 0 auto;
    width: 1.1em;
    height: 1.1em;
    border-radius: 50%;
    background: var(--q-brand-soft);
}

.products[data-showcase-v2] .q-st-nav-b {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--q-text);
    font-weight: 600;
}

.products[data-showcase-v2] .q-st-nav-l {
    display: flex;
    gap: 0.85em;
    min-width: 0;
    margin-left: 0.35em;
    overflow: hidden;
    color: var(--q-text-2);
    font-size: 0.92em;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-st-nav-a {
    flex: 0 0 auto;
    margin-left: auto;
    width: 1.5em;
    height: 1.5em;
    border-radius: 50%;
    background: var(--q-bg-hover);
}

.products[data-showcase-v2] .q-st-blocks {
    display: flex;
    flex-direction: column;
    gap: 0.6em;
}

/* ------------------------------------------------------------------ */
/* Blocks — they land, and they take a hairline ring                   */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-st-blk {
    position: relative;
    padding: 0.42em 0.6em;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 240ms ease, transform 260ms var(--ease-out);
}

.products[data-showcase-v2] .q-st-blk.on { opacity: 1; transform: none; }

/* the selection hit area: a real button, laid over the block */
.products[data-showcase-v2] .q-st-pick {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--q-r-row);
    background: none;
    cursor: pointer;
    transition: border-color 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-st-pick[aria-pressed='true'] { border-color: var(--q-brand); }

.products[data-showcase-v2] .q-st-h {
    margin: 0;
    color: var(--q-text);
    font-size: 1.5em;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.014em;
}

.products[data-showcase-v2] .q-st-sub {
    margin: 0.3em 0 0;
    max-width: 34em;
    font-size: 0.92em;
}

/* when the narrow column wraps the row, the clusters must not fall an
   inter-column gap apart */
.products[data-showcase-v2] .q-st-blk .q-kpis { gap: 0.9em 2.2em; }

.products[data-showcase-v2] .q-st-lb {
    display: block;
    color: var(--q-text-2);
    font-size: 0.92em;
    line-height: 1.2;
}

.products[data-showcase-v2] .q-chart.q-st-chart {
    flex: 0 0 auto;
    height: 4.7em;
    margin-top: 0.45em;
}

/* table: rounded zebra, raw ids in mono, status as a dot. Every column but
   the name is auto — it takes exactly what its longest string needs, in
   any locale — and the name absorbs the rest and ellipsizes, which is what
   a name column is for. At the narrow end of --q-fs the page sheet is only
   ~29em wide, so something has to give, and a clipped id or a clipped
   status would read as broken where a clipped name reads as a table. */
.products[data-showcase-v2] .q-st-tbl .q-tr {
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    gap: 0.55em;
    min-height: 2.42em;
    padding: 0 0.7em;
}

/* the row rule above ties the library's .q-tr.is-head on specificity and
   wins on source order, which silently fattened the header to a data row's
   height. Give the head its own reading back. */
.products[data-showcase-v2] .q-st-tbl .q-tr.is-head { min-height: 2.2em; }

.products[data-showcase-v2] .q-st-id { color: var(--q-text-2); }

.products[data-showcase-v2] .q-st-nm {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--q-text);
}

.products[data-showcase-v2] .q-st-st {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    min-width: 0;
    color: var(--q-text-2);
}

.products[data-showcase-v2] .q-st-st > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* narrow column: the id drops and the status keeps only its dot — which
   is all this language ever needed it to be */
.products[data-showcase-v2] .q-st-canvas.is-mobile .q-st-tbl .q-tr {
    grid-template-columns: minmax(0, 1fr) auto auto;
}

.products[data-showcase-v2] .q-st-canvas.is-mobile .q-st-id { display: none; }
.products[data-showcase-v2] .q-st-canvas.is-mobile .q-st-st > span { display: none; }

.products[data-showcase-v2] .q-st-form {
    display: flex;
    align-items: center;
    gap: 0.5em;
    flex-wrap: wrap;
    margin-top: 0.45em;
}

.products[data-showcase-v2] .q-st-field {
    display: flex;
    align-items: center;
    flex: 1 1 8em;
    min-width: 0;
    height: 2.4em;
    padding: 0 0.95em;
    border: 1px solid var(--q-border);
    border-radius: var(--q-r-full);
    color: var(--q-text-3);
    font-size: 0.92em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* the page's own submit — page content, so it never takes focus. The pick
   button lies over it, so it never takes a hover either. */
.products[data-showcase-v2] .q-pill.q-st-submit { flex: 0 0 auto; }

/* ------------------------------------------------------------------ */
/* Inspector — a small card, never a sidebar                           */
/* ------------------------------------------------------------------ */

/* the card, laid on its side: title left, properties strip right. Its
   header stays the library's header — only the axis changes. */
.products[data-showcase-v2] .q-card.q-st-ins {
    flex: 0 0 auto;
    flex-direction: row;
    align-items: center;
    gap: 1.6em;
    padding: 0.85em 1.15em;
}

.products[data-showcase-v2] .q-card.q-st-ins .q-card-h { flex: 0 0 auto; }

/* Four label-over-value clusters on the KPI cluster's rhythm: no boxes, no
   dividers, wide gaps. NEVER wraps: this strip is the canvas's landlord —
   every row it gains, the page sheet loses, and the sheet has under 2em of
   slack. Wrapping cost 3.2em and clipped the story's OWN last table row at
   the narrow end of --q-fs (measured in Chrome at the real stage geometry:
   the app is 48.3em wide at viewport ~965px, and there ru overflowed the
   canvas by 20px, tg by 8px). Nowrap makes the strip a fixed ~4.5em in
   every locale, so the canvas budget is knowable; a long locale ellipsizes
   one property instead of eating a row of the page. */
.products[data-showcase-v2] .q-st-ins-b {
    display: flex;
    align-items: flex-start;
    flex: 1 1 auto;
    min-width: 0;
    gap: 1.8em;
    flex-wrap: nowrap;
}

.products[data-showcase-v2] .q-st-ins-r {
    display: flex;
    flex-direction: column;
    gap: 0.1em;
    flex: 0 1 auto;
    min-width: 0;
}

.products[data-showcase-v2] .q-st-ins-l {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--q-text-2);
    font-size: 0.92em;
    line-height: 1.2;
}

.products[data-showcase-v2] .q-st-ins-v {
    min-height: 1.4em;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--q-text);
    line-height: 1.4;
    opacity: 0;
    transform: translateY(3px);
}

.products[data-showcase-v2] .q-st-ins-v.is-set {
    opacity: 1;
    transform: none;
    transition: opacity 220ms ease, transform 260ms var(--ease-out);
}

.products[data-showcase-v2] .q-st-ins-v[data-ins='1'].is-set { transition-delay: 55ms; }
.products[data-showcase-v2] .q-st-ins-v[data-ins='2'].is-set { transition-delay: 110ms; }
.products[data-showcase-v2] .q-st-ins-v[data-ins='3'].is-set { transition-delay: 165ms; }

/* ------------------------------------------------------------------ */
/* Published — a quiet floating chip carrying the raw URL              */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-chipf.q-st-url {
    position: absolute;
    z-index: 3;
    right: 1em;
    bottom: 1em;
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 240ms ease, transform 280ms var(--ease-out);
    pointer-events: none;
}

.products[data-showcase-v2] .q-chipf.q-st-url.in { opacity: 1; transform: none; }

@media (hover: hover) and (pointer: fine) {
    .products[data-showcase-v2] .q-st-pick:hover:not([aria-pressed='true']) { border-color: var(--q-border-strong); }

    .products[data-showcase-v2] .q-pill.q-st-pub[aria-disabled='true']:hover {
        background: var(--q-bg);
        border-color: var(--q-border);
    }
}

/* ------------------------------------------------------------------ */
/* FLOW — funnel (sankey ribbon)                                       */
/* ------------------------------------------------------------------ */

/* The ribbon zone is one box, edge to edge: the SVG, the column rules,
   the focus scrims, the boundary chips, the focus card and the step
   pills all stack on it, so every horizontal position is a percentage
   of the same width and the SVG can stay in raw pixels. */
.products[data-showcase-v2] .q-fl-zone {
    position: relative;
    flex: 1 1 auto;
    min-height: 11em;
    isolation: isolate;
}

.products[data-showcase-v2] .q-fl-svg {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
}

/* The flow and its halos are painted by the gradient the template hangs on
   them, so neither stroke nor fill may be set here: a CSS paint would beat
   the inline attribute and flatten the ribbon back to one colour. */
.products[data-showcase-v2] .q-fl-halo {
    fill: none;
    stroke-linejoin: round;
}

.products[data-showcase-v2] .q-fl-halo.is-3 { stroke-width: 17; opacity: 0.13; }
.products[data-showcase-v2] .q-fl-halo.is-2 { stroke-width: 9; opacity: 0.2; }
.products[data-showcase-v2] .q-fl-halo.is-1 { stroke-width: 3; opacity: 0.28; }

.products[data-showcase-v2] .q-fl-body {
    fill-opacity: 0.85;
    stroke: none;
}

/* equal-width stage columns, separated by full-height hairlines */
.products[data-showcase-v2] .q-fl-rules {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
}

.products[data-showcase-v2] .q-fl-rules i {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    border-left: 1px solid var(--q-border);
}

/* focusing a stage sinks the ribbon outside it under a wash of the page —
   the rules and the chips ride above the wash and stay crisp */
.products[data-showcase-v2] .q-fl-scrim {
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 1;
    width: 0;
    background: var(--q-bg);
    opacity: 0;
    pointer-events: none;
    transition: opacity 240ms var(--ease-out), width 320ms var(--ease-out);
}

.products[data-showcase-v2] .q-fl-scrim.is-l { left: 0; }
.products[data-showcase-v2] .q-fl-scrim.is-r { right: 0; }
.products[data-showcase-v2] .q-fl-zone.is-focused .q-fl-scrim { opacity: 0.72; }

/* count + conversion, floating on the ribbon at each stage boundary.
   `top` tracks FL_CY in the scene JS; they run a size down so five of them
   clear each other on the narrowest frame. */
.products[data-showcase-v2] .q-chipf.q-fl-chip {
    font-size: 0.85em;
}

.products[data-showcase-v2] .q-fl-chip {
    position: absolute;
    top: 57.5%;
    z-index: 3;
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.94);
    transition:
        opacity 240ms ease,
        transform 300ms var(--ease-out),
        border-color 180ms var(--ease-out),
        box-shadow 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-fl-chip.in {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
}

/* the exit chip hugs the bleed edge instead of straddling it */
.products[data-showcase-v2] .q-fl-chip.is-end { right: 0.5em; transform: translate(0, -50%) scale(0.94); }
.products[data-showcase-v2] .q-fl-chip.is-end.in { transform: translate(0, -50%) scale(1); }

.products[data-showcase-v2] .q-fl-chip.in.is-mut { opacity: 0.32; }

.products[data-showcase-v2] .q-fl-chip.is-hot {
    border-color: var(--q-brand-soft);
    box-shadow: 0 0 0 0.28em var(--q-chip-brand-bg), var(--q-sh-float);
}

/* the focus card: what this step does, and what it costs the cohort.
   It lands in the headroom the ribbon deliberately leaves above itself.
   The cap is min(design, zone) so the card can never be wider than the
   box it is clamped inside, whatever a locale throws at it. */
.products[data-showcase-v2] .q-fl-detail {
    position: absolute;
    top: 0.15em;
    left: 0;
    z-index: 4;
    display: flex;
    flex-direction: column;
    gap: 0.35em;
    width: max-content;
    max-width: min(24em, calc(100% - 1.2em));
    padding: 0.7em 0.85em;
    border: 1px solid var(--q-border);
    border-radius: var(--q-r-card);
    background: var(--q-bg);
    box-shadow: var(--q-sh-float);
    opacity: 0;
    transform: translateY(-4px);
    pointer-events: none;
    transition: opacity 200ms ease, transform 260ms var(--ease-out);
}

/* Only a card that is already on screen travels between columns; a card
   being shown for the first time must land at its stage, not slide the
   width of the zone to reach it. */
.products[data-showcase-v2] .q-fl-detail.in {
    opacity: 1;
    transform: none;
    transition: opacity 200ms ease, transform 260ms var(--ease-out), left 340ms var(--ease-out);
}

/* The row wraps and the node title may break; the readings never do — a number
   split across two lines is worse than a card one line taller. Without this the
   cap above cannot hold and long copy runs out through the card's own border. */
.products[data-showcase-v2] .q-fl-d-r {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5em;
    min-width: 0;
}

.products[data-showcase-v2] .q-fl-d-tag { color: var(--q-text-2); font-size: 0.85em; }

.products[data-showcase-v2] .q-fl-d-tag,
.products[data-showcase-v2] .q-fl-d-m,
.products[data-showcase-v2] .q-fl-d-n { white-space: nowrap; }

.products[data-showcase-v2] .q-fl-d-t {
    color: var(--q-text);
    font-weight: 600;
    letter-spacing: -0.006em;
}

.products[data-showcase-v2] .q-fl-d-m,
.products[data-showcase-v2] .q-fl-d-n {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    color: var(--q-text-2);
    font-size: 0.85em;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-fl-d-n b { color: var(--q-text); font-weight: 600; }
.products[data-showcase-v2] .q-fl-d-n svg { width: 0.95em; height: 0.95em; color: var(--q-text-3); }

.products[data-showcase-v2] .q-fl-d-sep {
    flex: 0 0 auto;
    width: 1px;
    height: 0.9em;
    background: var(--q-border);
}

/* one step pill at the foot of each column. The column count tracks
   FL_STAGES in the scene JS. */
.products[data-showcase-v2] .q-fl-steps {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
}

.products[data-showcase-v2] .q-fl-col {
    display: grid;
    justify-items: center;
    min-width: 0;
    padding: 0 0.2em;
}

.products[data-showcase-v2] .q-fl-step { max-width: 100%; }

.products[data-showcase-v2] .q-fl-step span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.products[data-showcase-v2] .q-fl-step[aria-pressed='true'] {
    border-color: var(--q-brand-soft);
    background: var(--q-chip-brand-bg);
    color: var(--q-text);
}

.products[data-showcase-v2] .q-fl-step[aria-pressed='true'] svg { color: var(--q-brand-strong); }

/* the run log: rounded zebra, newest on top, four rows and no more.
   The list reserves its full height from mount so arriving rows never
   resize the ribbon underneath them. */
.products[data-showcase-v2] .q-fl-log {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.3em;
}

.products[data-showcase-v2] .q-fl-log-h { padding: 0 0.8em; }

.products[data-showcase-v2] .q-fl-rows { min-height: 10.8em; }

.products[data-showcase-v2] .q-fl-lrow {
    grid-template-columns: auto minmax(0, 1fr) auto;
    min-height: 2.7em;
    opacity: 0;
    transform: translateY(-5px);
    transition:
        opacity 260ms ease,
        transform 300ms var(--ease-out),
        background 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-fl-lrow.in { opacity: 1; transform: none; }

.products[data-showcase-v2] .q-fl-lt {
    color: var(--q-text-3);
    font-family: var(--mono);
    font-size: 0.85em;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
}

.products[data-showcase-v2] .q-fl-lx {
    min-width: 0;
    overflow: hidden;
    color: var(--q-text-2);
    font-size: 0.92em;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-fl-ld { font-size: 0.85em; }

@media (hover: hover) and (pointer: fine) {
    .products[data-showcase-v2] .q-fl-step[aria-pressed='true']:hover {
        background: var(--q-chip-brand-bg);
        border-color: var(--q-brand-soft);
    }
}

/* ------------------------------------------------------------------ */
/* GRID — managed cloud & DevOps (annotated deep-dive, with the dock)   */
/* Positions the library: KPI row → annotated latency plot → the 90-day */
/* activity grid, with five sections the dock really swaps. Everything  */
/* here is scene anatomy or a scoped placement of a shared primitive.   */
/* ------------------------------------------------------------------ */

/* the five sections share the view; the dock swaps which one is on */
.products[data-showcase-v2] .q-gr-stack {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
}

.products[data-showcase-v2] .q-gr-panel {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 1.15em;
    /* content clears the floating dock instead of sliding under it: the
       dock's own box is 1.15em + 3.6em tall and the view already pads
       1.5em, so this leaves a measured ~2.7em of air under the last card */
    padding-bottom: 6em;
}

.products[data-showcase-v2] .q-gr-panel[hidden] { display: none; }

.products[data-showcase-v2] .q-gr-panel.is-in {
    animation: qGrPanel 260ms var(--ease-out) both;
}

@keyframes qGrPanel {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: none; }
}

/* a section-owning card: it takes the height the dock leaves it */
.products[data-showcase-v2] .q-gr-fill {
    flex: 1 1 auto;
    min-height: 0;
}

/* ---- KPI row ------------------------------------------------------ */

/* health is a dot AFTER the value, never a badge */
.products[data-showcase-v2] .q-gr-kv {
    display: flex;
    align-items: center;
    gap: 0.5em;
}

/* the series key rides the free end of the KPI row */
.products[data-showcase-v2] .q-gr-legend {
    margin-left: auto;
    align-self: center;
}

.products[data-showcase-v2] .q-gr-legend.is-off .q-gr-legend-ctx { display: none; }

.products[data-showcase-v2] .q-gr-ctxb[aria-pressed='false'] svg {
    color: var(--q-text-3);
    opacity: 0.5;
}

/* ---- The plot ----------------------------------------------------- */

.products[data-showcase-v2] .q-gr-chart { min-height: 9em; }

/* The plot and the axis share one coordinate space, so a time label sits
   exactly over the tick it names and the now chip meets the now line.
   z-index makes this the stacking context the plot's furniture is ordered
   in, so the ordering below is declared rather than inherited from the
   order the nodes happen to be written in. */
.products[data-showcase-v2] .q-gr-plot {
    position: absolute;
    inset: 0 0 2.1em 0;
    z-index: 0;
}

/* back to front: gridlines · series · gridline readings · now · markers.
   The dotted rules are furniture and belong UNDER the series; their tiny
   readings belong over the mist that would otherwise wash them out. */
.products[data-showcase-v2] .q-gr-chart .q-plot { z-index: 1; }
.products[data-showcase-v2] .q-gr-chart .q-gl b { z-index: 2; }
.products[data-showcase-v2] .q-gr-chart .q-nowline { z-index: 3; }
.products[data-showcase-v2] .q-gr-chart .q-annot { z-index: 4; }

.products[data-showcase-v2] .q-gr-chart .q-xaxis {
    left: 0;
    right: 0;
    display: block;
    height: 1.5em;
}

.products[data-showcase-v2] .q-gr-chart .q-xaxis span {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    white-space: nowrap;
}

.products[data-showcase-v2] .q-gr-chart .q-line.is-ctx { transition: opacity 220ms ease; }

/* the story walks the head dot frame by frame — it must not also
   transition its own position or it would trail the line it rides */
.products[data-showcase-v2] .q-gr-chart .q-mark-dot {
    z-index: 5;
    transition: opacity 180ms ease, transform 220ms var(--ease-out);
}

/* ---- Annotation markers ------------------------------------------- */

.products[data-showcase-v2] .q-gr-anns {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.products[data-showcase-v2] .q-gr-chart .q-annot i {
    transition: transform 180ms var(--ease-out), border-color 180ms var(--ease-out);
}

.products[data-showcase-v2] .q-gr-chart .q-annot.is-hot i {
    transform: translateX(-50%) scale(1.12);
    border-color: var(--q-border-strong);
}

.products[data-showcase-v2] .q-gr-chart .q-annot.is-drop {
    animation: qGrDrop 320ms var(--ease-out) both;
}

@keyframes qGrDrop {
    from { opacity: 0; transform: translateY(-7px); }
    to { opacity: 1; transform: none; }
}

/* an invisible, focusable hit target: the circle stays the library's */
.products[data-showcase-v2] .q-gr-hit {
    position: absolute;
    top: -0.32em;
    left: 0;
    width: 2.5em;
    height: 2.5em;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    transform: translateX(-50%);
    pointer-events: auto;
    cursor: pointer;
}

/* The release chip hangs UNDER its marker — above it there is no plot.
   Doubled up on .q-tip so this wins on specificity rather than on the
   order the scene sections happen to be concatenated in. */
.products[data-showcase-v2] .q-tip.q-gr-tip {
    z-index: 6;
    top: 1.85em;
    transform: translate(-50%, 0.5em) scale(0.96);
}

.products[data-showcase-v2] .q-tip.q-gr-tip.in { transform: translate(-50%, 0.85em) scale(1); }

/* ---- Incidents section -------------------------------------------- */

/* the record on the left, the tiny story it adds up to on the right */
.products[data-showcase-v2] .q-gr-inc {
    flex: 1 1 auto;
    min-height: 0;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 2.4em;
}

.products[data-showcase-v2] .q-gr-inc-l {
    display: flex;
    flex-direction: column;
    gap: 1.1em;
}

/* ---- Sheets ------------------------------------------------------- */

/* the sheet spreads its rows over the section instead of stacking them
   at the top of a tall card */
.products[data-showcase-v2] .q-gr-sheet { flex: 1 1 auto; }
.products[data-showcase-v2] .q-gr-sheet .q-tr { flex: 1 1 auto; max-height: 4.6em; }

/* ---- Activity dot grid -------------------------------------------- */

.products[data-showcase-v2] .q-gr-cal-h {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.8em;
    margin-bottom: 0.75em;
}

.products[data-showcase-v2] .q-gr-cal-h p { margin: 0; }

.products[data-showcase-v2] .q-gr-cal-r {
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
    color: var(--q-text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* the incidents section gets the full-size grid; the overview a strip */
.products[data-showcase-v2] .q-gr-cal.is-big .q-dots { gap: 0.95em; }
.products[data-showcase-v2] .q-gr-cal.is-big .q-dots i { width: 0.85em; height: 0.85em; }

/* ---- Latency section ---------------------------------------------- */

.products[data-showcase-v2] .q-gr-cards {
    flex: 1 1 auto;
    min-height: 0;
    grid-template-rows: repeat(2, minmax(0, 1fr));
}

.products[data-showcase-v2] .q-gr-svc-v {
    display: flex;
    align-items: center;
    gap: 0.6em;
}

.products[data-showcase-v2] .q-gr-svc-v .q-fav {
    width: 1.9em;
    height: 1.9em;
    border-radius: 0.5em;
}

.products[data-showcase-v2] .q-gr-svc-v .q-fav svg { width: 1.1em; height: 1.1em; }

/* the sparkline bleeds to the card's own bottom edge */
.products[data-showcase-v2] .q-gr-spark {
    width: calc(100% + 2.5em);
    height: 7.4em;
    margin: auto -1.25em 0;
}

/* ---- Deploys section ---------------------------------------------- */

.products[data-showcase-v2] .q-gr-hd {
    display: inline-flex;
    align-items: center;
    gap: 0.85em;
}

.products[data-showcase-v2] .q-gr-status {
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
    color: var(--q-text-2);
    font-size: 0.92em;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-gr-status .q-raw { color: var(--q-text); }

.products[data-showcase-v2] .q-gr-cmd {
    display: flex;
    align-items: center;
    gap: 0.5em;
    min-height: 1.6em;
    color: var(--q-text-2);
}

.products[data-showcase-v2] .q-gr-cmd svg {
    flex: 0 0 auto;
    width: 1.05em;
    height: 1.05em;
    color: var(--q-text-3);
}

.products[data-showcase-v2] .q-gr-cmd .caret { display: none; }
.products[data-showcase-v2] .q-gr-cmd.is-typing .caret { display: inline-block; }

.products[data-showcase-v2] .q-gr-steps {
    display: flex;
    flex-direction: column;
}

/* a quiet process row: thin-line state, step, right-aligned duration */
.products[data-showcase-v2] .q-gr-step {
    display: grid;
    grid-template-columns: 1.2em minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.7em;
    min-height: 2.4em;
    color: var(--q-text-3);
    transition: color 220ms var(--ease-out);
}

.products[data-showcase-v2] .q-gr-step.is-run,
.products[data-showcase-v2] .q-gr-step.is-done { color: var(--q-text); }

.products[data-showcase-v2] .q-gr-step-ic {
    display: grid;
    place-items: center;
    width: 1.2em;
    height: 1.2em;
    line-height: 0;
}

.products[data-showcase-v2] .q-gr-step-ic::before {
    content: '';
    width: 0.64em;
    height: 0.64em;
    border: 1px solid var(--q-border-strong);
    border-radius: 50%;
}

.products[data-showcase-v2] .q-gr-step.is-run .q-gr-step-ic::before {
    border-color: var(--q-warning);
    animation: qGrRun 1.5s ease-in-out infinite;
}

.products[data-showcase-v2] .q-gr-step.is-done .q-gr-step-ic::before { display: none; }

.products[data-showcase-v2] .q-gr-step-ic svg {
    width: 1.05em;
    height: 1.05em;
    color: var(--q-positive);
}

@keyframes qGrRun {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--q-warning) 32%, transparent); }
    60% { box-shadow: 0 0 0 0.3em color-mix(in srgb, var(--q-warning) 0%, transparent); }
}

.products[data-showcase-v2] .q-gr-step-r {
    color: var(--q-text-2);
    font-size: 0.92em;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-gr-rel { grid-template-columns: minmax(0, 1fr) auto 3.4em; }

/* ---- Environment sheet -------------------------------------------- */

.products[data-showcase-v2] .q-gr-env { grid-template-columns: minmax(0, 1fr) auto; }

.products[data-showcase-v2] .q-gr-env .q-tr-n { color: var(--q-text-2); }

/* ------------------------------------------------------------------ */
/* SPEECH KIT — score-ring deep-dive                                   */
/* ------------------------------------------------------------------ */

/* Two-column intro: the verdict story on the left, the raw numbers on the
   right. The note and the legend sit under the whole left column rather than
   beside the dial — they are footnotes to the verdict, and the strip left
   over next to a 7.4em ring is too narrow to set a sentence in. */
.products[data-showcase-v2] .q-sk-intro {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 2.4em;
    align-items: start;
    flex: 0 0 auto;
}

.products[data-showcase-v2] .q-sk-score {
    display: flex;
    flex-direction: column;
    gap: 1.05em;
    min-width: 0;
}

.products[data-showcase-v2] .q-sk-score-r {
    display: flex;
    align-items: center;
    gap: 1.2em;
    min-width: 0;
}

.products[data-showcase-v2] .q-sk-verdict {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2em;
    min-width: 0;
}

.products[data-showcase-v2] .q-sk-note { font-size: 0.92em; }

/* the score is quoted back inside the sentence — it is still a reading */
.products[data-showcase-v2] .q-sk-note b { font-variant-numeric: tabular-nums; }

.products[data-showcase-v2] .q-sk-about {
    display: flex;
    flex-direction: column;
    gap: 1.4em;
    min-width: 0;
}

/* the mini-metric grid is a KPI cluster row folded into two columns —
   still no boxes, no dividers, just wider gutters between the readings */
.products[data-showcase-v2] .q-sk-mets { gap: 1.15em 1.7em; }

/* A KPI value never wraps by design: in a KPI row it has the whole gutter to
   breathe into. Folded into a half-width column it must be allowed to, or a
   long reading ("4 800 соат аудио") runs under the cell beside it. The
   template binds each value's digit groups with a non-breaking space first,
   so a wrap can only fall between words — never through a number. */
.products[data-showcase-v2] .q-sk-mets .q-kpi-v { white-space: normal; }

/* ------------------------------------------------------------------ */
/* The waveform — the chart                                            */
/* ------------------------------------------------------------------ */

/* One box, edge to edge. The bar field, the playhead and the axis all sit
   on the same percentage grid, so the chip at the playhead lands exactly
   under it without anything being measured. */
.products[data-showcase-v2] .q-sk-wave {
    position: relative;
    display: flex;
    flex: 1 1 auto;
    min-height: 8.5em;
    padding-bottom: 1.9em;
}

.products[data-showcase-v2] .q-sk-plot { min-width: 0; }

/* 46 rods mirrored around the silence line, rounded caps, no baseline of
   their own — the dotted rule behind them is the baseline.
   The rods are a fixed em width and the gaps absorb the app's width, rather
   than the other way round: a rod that grew with the container would read as
   a bar chart by the time the stage is wide, and this is a waveform. */
.products[data-showcase-v2] .q-sk-bars {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.products[data-showcase-v2] .q-sk-bars i {
    flex: 0 0 0.46em;
    border-radius: var(--q-r-full);
    background: var(--q-context);
    transform-origin: 50% 50%;
    transition: background 240ms var(--ease-out), transform 240ms var(--ease-out);
}

/* heard: periwinkle at full. Ahead of the playhead: context gray. */
.products[data-showcase-v2] .q-sk-bars i.on { background: var(--q-brand); }

/* Synth builds the waveform instead of consuming it — ahead of the playhead
   there is no audio yet, because the model has not made it. */
.products[data-showcase-v2] .q-sk-wave.is-tts .q-sk-bars i { transform: scaleY(0); }
.products[data-showcase-v2] .q-sk-wave.is-tts .q-sk-bars i.on { transform: scaleY(1); }

/* The playhead IS the "now" line: the boundary between what has been heard
   and what has not. It keeps the spec's thin light rule and earns a small
   brand cap, because unlike a static "now" this one moves and the eye has
   to be able to find it. Its x is written by seek() and rides the rod
   centres, so the cap never reaches the frame's clip. */
.products[data-showcase-v2] .q-sk-head {
    left: 0;
    z-index: 2;
    background: var(--q-brand-soft);
}

.products[data-showcase-v2] .q-sk-head::after {
    content: '';
    position: absolute;
    top: -0.16em;
    left: 50%;
    width: 0.42em;
    height: 0.42em;
    border-radius: 50%;
    background: var(--q-brand);
    transform: translateX(-50%);
}

/* the axis shares the bars' full-bleed span, not the content gutter, or the
   chip would drift off the playhead it is naming */
.products[data-showcase-v2] .q-sk-axis {
    left: 0;
    right: 0;
    height: 1.5em;
}

.products[data-showcase-v2] .q-sk-axis span { position: absolute; }

/* bare ticks: one per transcript row, plus the run's length */
.products[data-showcase-v2] .q-sk-tick {
    transform: translateX(-50%);
    transition: opacity 160ms var(--ease-out);
}

/* the run's two ends are pinned inside the gutter — a centred label there
   would hang half of itself off the app's edge */
.products[data-showcase-v2] .q-sk-tick:first-child {
    transform: none;
    margin-left: 1.5em;
}

.products[data-showcase-v2] .q-sk-tick.is-end {
    transform: translateX(-100%);
    margin-left: -1.5em;
}

/* a tick the moving chip is about to sit on gets out of its way */
.products[data-showcase-v2] .q-sk-tick.is-dim { opacity: 0; }

/* The clock at the playhead — the only chip on the axis. Its left and its
   translate are written by seek(): left takes the playhead's exact x, and the
   translate winds 0 -> -100% across the run so the chip hugs it yet never
   crosses the app's edge. */
.products[data-showcase-v2] .q-sk-now { left: 0; }

/* the pass's receipt floats over the waveform it is about */
.products[data-showcase-v2] .q-sk-rcpt {
    position: absolute;
    top: 0;
    right: 1.5em;
    z-index: 3;
    max-width: calc(100% - 3em);
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 220ms ease, transform 300ms var(--ease-out);
}

.products[data-showcase-v2] .q-sk-rcpt.in {
    opacity: 1;
    transform: none;
}

.products[data-showcase-v2] .q-sk-rcpt svg { color: var(--q-positive); }

.products[data-showcase-v2] .q-sk-rcpt b,
.products[data-showcase-v2] .q-sk-rcpt span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ------------------------------------------------------------------ */
/* The transcript                                                      */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-sk-tx {
    display: flex;
    flex-direction: column;
    gap: 0.45em;
    flex: 0 0 auto;
}

.products[data-showcase-v2] .q-sk-tx-h {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.8em;
}

/* confidence dot · the words · the timestamp, right-aligned */
.products[data-showcase-v2] .q-sk-row { grid-template-columns: auto minmax(0, 1fr) auto; }

.products[data-showcase-v2] .q-sk-ws {
    min-width: 0;
    color: var(--q-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A word lands only once the playhead has passed it. It fades in where it
   already sits — reserving the line means the transcript never reflows out
   from under the eye that is reading it. */
.products[data-showcase-v2] .q-sk-w {
    opacity: 0;
    transition: opacity 200ms var(--ease-out), color 260ms var(--ease-out);
}

.products[data-showcase-v2] .q-sk-w.in { opacity: 1; }

/* the token the pass's note is about: it arrives warm like any other, then
   settles into amber instead of ink — this is the one the model worked for,
   and the receipt is about to say so */
.products[data-showcase-v2] .q-sk-w.is-key {
    color: var(--q-warning);
    font-weight: 500;
}

/* the freshest word is still warm — declared last so it wins while hot */
.products[data-showcase-v2] .q-sk-w.is-hot { color: var(--q-brand); }

/* ------------------------------------------------------------------ */
/* Transport                                                           */
/* ------------------------------------------------------------------ */

/* .q-seg sets display, so [hidden] alone cannot take the picker out */
.products[data-showcase-v2] .q-sk-voices[hidden] { display: none; }

.products[data-showcase-v2] .q-sk-play.is-on svg { color: var(--q-brand); }

/* ================================================================== */
/* HR-AGENT — profile timeline, with the dock                          */
/* The archetype: an identity rail that is one candidate, and a right   */
/* column the dock swaps between five sections. Everything here         */
/* positions and composes the library; the scene-specific anatomy is    */
/* the gradient-blob avatar, the pending row, the step timeline's       */
/* hairline, and the confirmation chip that floats over the lot.        */
/* ================================================================== */

.products[data-showcase-v2] .q-hr-wrap {
    display: flex;
    flex: 1 1 auto;
    gap: 1.5em;
    min-height: 0;
}

/* the agent's own state is meta, not chrome: it sits quiet by the avatar */
.products[data-showcase-v2] .q-hr-status {
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
    color: var(--q-text-3);
    font-size: 0.92em;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-hr-vac { max-width: 20em; }
.products[data-showcase-v2] .q-hr-vac span { overflow: hidden; text-overflow: ellipsis; }

/* off = the applications nobody has read yet are out of the list; the pill
   reads as unlit, not broken */
.products[data-showcase-v2] .q-hr-pend[aria-pressed='false'] {
    background: var(--q-bg-subtle);
    box-shadow: none;
}

.products[data-showcase-v2] .q-hr-pend[aria-pressed='false'] svg { color: var(--q-text-3); }

/* ------------------------------------------------------------------ */
/* The rail — §4.10, one candidate seen five ways                      */
/* ------------------------------------------------------------------ */

/* The dock's buttons size themselves in their own UA font, not the app's, so
   the one dark object is ~4.7em tall at the smallest --q-fs and stands 1.15em
   off the app's floor. .q-view already pays 1.5em of that, leaving 5.4em that
   every column in here owes before its last row. Measured, not assumed: at
   --q-fs 9.5px the dock's top edge sits 5.84em above the app's floor. */
.products[data-showcase-v2] .q-hr-rail {
    flex: 0 0 16em;
    display: flex;
    flex-direction: column;
    gap: 1.8em;
    min-width: 0;
    padding-bottom: 5.4em;
}

.products[data-showcase-v2] .q-hr-id {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5em;
    min-width: 0;
}

/* the gradient blob (§4.10). 3.74em of its own 1.15em type == 4.3em of the
   rail's, which is the spec's 56px avatar at this scale. */
.products[data-showcase-v2] .q-hr-blob {
    --q-hr-a: var(--q-brand-soft);
    --q-hr-b: var(--q-brand);
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 3.74em;
    height: 3.74em;
    border-radius: 50%;
    background: radial-gradient(120% 120% at 28% 22%, var(--q-hr-a), var(--q-hr-b) 76%);
    color: var(--q-bg);
    font-size: 1.15em;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.01em;
}

.products[data-showcase-v2] .q-hr-blob.is-sm {
    width: 2.83em;
    height: 2.83em;
    font-size: 0.92em;
}

/* the row chip carries the same identity mark, square per §4.6; a pending
   row has no name yet, so it keeps the primitive's plain gray */
.products[data-showcase-v2] .q-hr-chip {
    --q-hr-a: var(--q-bg-hover);
    --q-hr-b: var(--q-bg-hover);
    width: 1.68em;
    height: 1.68em;
    background: radial-gradient(120% 120% at 28% 22%, var(--q-hr-a), var(--q-hr-b) 76%);
    color: var(--q-bg);
    font-size: 0.78em;
    letter-spacing: -0.03em;
}

.products[data-showcase-v2] .q-hr-blob.is-t0,
.products[data-showcase-v2] .q-hr-chip.is-t0 { --q-hr-a: var(--q-brand-soft); --q-hr-b: var(--q-brand); }
.products[data-showcase-v2] .q-hr-blob.is-t1,
.products[data-showcase-v2] .q-hr-chip.is-t1 { --q-hr-a: var(--q-tail); --q-hr-b: var(--q-brand-strong); }
.products[data-showcase-v2] .q-hr-blob.is-t2,
.products[data-showcase-v2] .q-hr-chip.is-t2 { --q-hr-a: var(--q-brand-soft); --q-hr-b: var(--q-brand-strong); }
.products[data-showcase-v2] .q-hr-blob.is-t3,
.products[data-showcase-v2] .q-hr-chip.is-t3 { --q-hr-a: var(--q-tail); --q-hr-b: var(--q-brand); }

.products[data-showcase-v2] .q-hr-name {
    max-width: 100%;
    overflow: hidden;
    color: var(--q-text);
    font-size: 1.5em;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.014em;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* "{n} ч · Оператор колл-центра" — the hours are a reading, so they line up */
.products[data-showcase-v2] .q-hr-when {
    display: flex;
    align-items: center;
    gap: 0.4em;
    max-width: 100%;
    min-width: 0;
    color: var(--q-text-2);
    font-size: 0.92em;
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-hr-when svg {
    flex: 0 0 auto;
    width: 1.05em;
    height: 1.05em;
    color: var(--q-text-3);
}

.products[data-showcase-v2] .q-hr-when span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-hr-from {
    display: flex;
    align-items: center;
    gap: 0.5em;
    max-width: 100%;
    min-width: 0;
    margin-top: 0.15em;
}

.products[data-showcase-v2] .q-hr-geo {
    color: var(--q-text-2);
    font-size: 0.92em;
    white-space: nowrap;
}

/* §4.10's referrer pill: it is a chip in the identity row, so it keeps the
   primitive's border and soft shadow */
.products[data-showcase-v2] .q-hr-src {
    min-width: 0;
    padding: 0.32em 0.6em;
}

.products[data-showcase-v2] .q-hr-src b {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* three readings that live nowhere else on the screen: what they did, what
   they know, and which section they are in */
.products[data-showcase-v2] .q-hr-stats {
    display: grid;
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 0.82fr) minmax(0, 1.23fr);
    gap: 0.55em;
    width: 100%;
    margin-top: 0.8em;
}

.products[data-showcase-v2] .q-hr-stat {
    display: flex;
    flex-direction: column;
    gap: 0.15em;
    min-width: 0;
}

.products[data-showcase-v2] .q-hr-stat-l,
.products[data-showcase-v2] .q-hr-stat-v {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-hr-stat-l {
    color: var(--q-text-2);
    font-size: 0.8em;
    line-height: 1.3;
}

.products[data-showcase-v2] .q-hr-stat-v {
    color: var(--q-text);
    font-size: 0.98em;
    font-weight: 500;
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
}

/* §4.7's card-sized variant: the ring, the verdict word beside it */
.products[data-showcase-v2] .q-hr-vd {
    display: flex;
    align-items: center;
    gap: 1em;
    min-width: 0;
}

/* the sweep is a tween, so the primitive's own dasharray transition would
   fight it frame by frame; the colour still eases when the band changes */
.products[data-showcase-v2] .q-hr-vd .q-ring-arc { transition: stroke 300ms ease; }

.products[data-showcase-v2] .q-hr-word {
    min-width: 0;
    font-size: 1.35em;
    transition: opacity 200ms ease;
}

/* while the agent is still scoring, the ring has no word yet */
.products[data-showcase-v2] .q-hr-vd.is-wait .q-hr-word { opacity: 0; }

.products[data-showcase-v2] .q-hr-acts {
    display: flex;
    flex-direction: column;
    gap: 0.7em;
    min-width: 0;
}

/* §4.9's header: the count is dark, the sentence around it is not */
.products[data-showcase-v2] .q-hr-acts-h {
    display: flex;
    align-items: baseline;
    gap: 0.35em;
    min-width: 0;
    color: var(--q-text-2);
    font-size: 0.92em;
}

.products[data-showcase-v2] .q-hr-acts-h b {
    flex: 0 0 auto;
    color: var(--q-text);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-hr-acts-h span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ------------------------------------------------------------------ */
/* Section stack — the dock's five destinations, crossfading in place  */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-hr-stack {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
}

/* every section stops above the dock: these panels do not scroll, so a label
   that slid under the one dark object would simply be gone */
.products[data-showcase-v2] .q-hr-panel {
    position: absolute;
    inset: 0 0 5.4em 0;
    display: flex;
    flex-direction: column;
    gap: 0.9em;
    min-height: 0;
    opacity: 0;
    visibility: hidden;
    transform: translateY(4px);
    transition:
        opacity 220ms ease,
        transform 300ms var(--ease-out),
        visibility 0s linear 300ms;
}

.products[data-showcase-v2] .q-hr-panel.is-on {
    z-index: 1;
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s, 0s, 0s;
}

.products[data-showcase-v2] .q-hr-lb {
    display: flex;
    flex: 0 0 auto;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.55em;
    min-width: 0;
}

/* a section title and its count share one line, and the longest of these
   titles is a whole sentence: it sits at the bottom of §2.3's title band */
.products[data-showcase-v2] .q-hr-lb .q-card-t {
    overflow: hidden;
    font-size: 1.1em;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* the score label is a lowercase noun in every locale — as a section title
   it takes the capital any sentence would */
.products[data-showcase-v2] .q-hr-cap::first-letter { text-transform: uppercase; }

.products[data-showcase-v2] .q-hr-qn {
    flex: 0 0 auto;
    color: var(--q-text-2);
    font-size: 0.92em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ------------------------------------------------------------------ */
/* The queue — §4.6, and the screen's one real decision                */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-hr-q {
    flex: 0 0 auto;
    min-width: 0;
}

/* the verdict column is sized for the longest chip any locale ships
   ("на интервью"), so nothing spills into the row's padding */
.products[data-showcase-v2] .q-hr-q .q-tr {
    grid-template-columns: minmax(0, 1fr) 3.4em 6.4em;
    gap: 0.6em;
    padding: 0 0.6em;
}

/* the primitive shrinks a head row's type, which would shrink its em-based
   columns out of line with the rows beneath it — keep the grid at 1em and
   shrink the label itself. Its two neighbours are empty, so it is free to
   overflow into them rather than ellipsise inside its own column. */
.products[data-showcase-v2] .q-hr-q .q-tr.is-head { font-size: 1em; }

.products[data-showcase-v2] .q-hr-q .q-tr.is-head .q-num-c {
    overflow: visible;
    color: var(--q-text-2);
    font-size: 0.92em;
    white-space: nowrap;
}

/* the rows are buttons so that picking one is a keyboard operation and not
   a mouse trick; the zebra still comes from the primitive. 3.05em == 40px at
   the spec's canvas, the top of §4.6's 36–40px band. */
.products[data-showcase-v2] .q-hr-q .q-hr-row { min-height: 3.05em; }

.products[data-showcase-v2] .q-hr-row {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.products[data-showcase-v2] .q-hr-row .q-tr-n > span:last-child {
    flex: 1 1 auto;
    min-width: 0;
}

.products[data-showcase-v2] .q-hr-row.is-pend {
    cursor: default;
    pointer-events: none;
}

.products[data-showcase-v2] .q-hr-q.no-pend .q-hr-row.is-pend { display: none; }

/* the rail follows the row you pick, and the row says so */
.products[data-showcase-v2] .q-hr-q .q-tr.q-hr-row.is-sel { background: var(--q-chip-brand-bg); }
.products[data-showcase-v2] .q-hr-q .q-tr.q-hr-row.is-sel .q-tr-n { font-weight: 500; }

/* filtering the unread out before the agent has read anything leaves nothing
   to list: §4.12 says that gets a story, not a bare column header */
.products[data-showcase-v2] .q-hr-empty { display: none; }
.products[data-showcase-v2] .q-hr-panel.is-empty .q-hr-q { display: none; }
.products[data-showcase-v2] .q-hr-panel.is-empty .q-hr-empty { display: flex; }

/* an application nobody has read yet: a mark with no letters in it and a
   bar where the name will be */
.products[data-showcase-v2] .q-hr-bar {
    display: inline-block;
    height: 0.55em;
    border-radius: var(--q-r-full);
    background: var(--q-bg-hover);
    vertical-align: middle;
    animation: qPulse 2.6s ease-in-out infinite;
}

.products[data-showcase-v2] .q-hr-bar.is-n { width: 1.7em; }

.products[data-showcase-v2] .q-hr-v {
    display: flex;
    align-items: center;
    min-width: 0;
}

.products[data-showcase-v2] .q-hr-v .q-delta {
    opacity: 0;
    transform: translateY(2px);
    transition: opacity 200ms ease, transform 240ms var(--ease-out);
}

.products[data-showcase-v2] .q-hr-v .q-delta.in {
    opacity: 1;
    transform: none;
}

/* ------------------------------------------------------------------ */
/* The vacancy — where the eight in the queue came from                */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-hr-kpis {
    flex: 0 0 auto;
    gap: 2.2em;
}

.products[data-showcase-v2] .q-hr-ch-h {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 0.6em;
    min-width: 0;
}

.products[data-showcase-v2] .q-hr-ch-t {
    overflow: hidden;
    color: var(--q-text-2);
    font-size: 0.92em;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-hr-chart {
    flex: 1 1 auto;
    min-height: 7em;
}

/* the plot stops above the axis, and the labels line up with its edges
   instead of the page gutter this chart does not have */
.products[data-showcase-v2] .q-hr-plot {
    position: absolute;
    inset: 0 0 1.6em 0;
}

.products[data-showcase-v2] .q-hr-chart .q-xaxis { left: 0; right: 0; }
.products[data-showcase-v2] .q-hr-chart .q-gl b { left: 0; }

/* ------------------------------------------------------------------ */
/* Onboarding — §4.8, steps hanging off a hairline                     */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-hr-sess {
    flex: 0 0 auto;
    gap: 1em;
}

.products[data-showcase-v2] .q-hr-sess-h {
    display: flex;
    align-items: center;
    gap: 0.7em;
    min-width: 0;
}

.products[data-showcase-v2] .q-hr-sess-id {
    display: flex;
    flex-direction: column;
    gap: 0.1em;
    min-width: 0;
}

.products[data-showcase-v2] .q-hr-sess-id b {
    overflow: hidden;
    color: var(--q-text);
    font-size: 1.15em;
    font-weight: 600;
    line-height: 1.25;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-hr-sess-id > span {
    color: var(--q-text-2);
    font-size: 0.92em;
    font-variant-numeric: tabular-nums;
}

.products[data-showcase-v2] .q-hr-tl {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.45em;
    padding-left: 1.6em;
}

.products[data-showcase-v2] .q-hr-tl::before {
    content: '';
    position: absolute;
    top: 1.25em;
    bottom: 1.25em;
    left: 0.35em;
    border-left: 1px solid var(--q-border);
}

.products[data-showcase-v2] .q-hr-step {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.6em;
    min-height: 2.5em;
    padding: 0 0.8em;
    border-radius: var(--q-r-row);
    background: var(--q-bg-subtle);
}

/* the node on the line fills in when the step is done — a dot, not a badge */
.products[data-showcase-v2] .q-hr-step::before {
    content: '';
    position: absolute;
    top: 50%;
    left: -1.6em;
    width: 0.62em;
    height: 0.62em;
    border: 1px solid var(--q-border-strong);
    border-radius: 50%;
    background: var(--q-bg);
    transform: translateY(-50%);
    transition: background 220ms var(--ease-out), border-color 220ms var(--ease-out);
}

.products[data-showcase-v2] .q-hr-step.is-done::before {
    background: var(--q-positive);
    border-color: var(--q-positive);
}

.products[data-showcase-v2] .q-hr-step-ic {
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    color: var(--q-text-3);
    line-height: 0;
    transition: color 220ms ease;
}

.products[data-showcase-v2] .q-hr-step-ic svg { width: 1.15em; height: 1.15em; }

.products[data-showcase-v2] .q-hr-step-t {
    flex: 1 1 auto;
    overflow: hidden;
    min-width: 0;
    color: var(--q-text-2);
    font-size: 0.92em;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color 220ms ease;
}

.products[data-showcase-v2] .q-hr-step.is-done .q-hr-step-t { color: var(--q-text); }
.products[data-showcase-v2] .q-hr-step.is-done .q-hr-step-ic { color: var(--q-text-2); }

.products[data-showcase-v2] .q-hr-prog {
    display: flex;
    align-items: center;
    gap: 0.7em;
}

.products[data-showcase-v2] .q-hr-prog-t {
    flex: 1 1 auto;
    overflow: hidden;
    height: 0.3em;
    border-radius: var(--q-r-full);
    background: var(--q-bg-subtle);
}

.products[data-showcase-v2] .q-hr-prog-t i {
    display: block;
    width: 0;
    height: 100%;
    border-radius: var(--q-r-full);
    background: var(--q-brand);
    transition: width 420ms var(--ease-out);
}

.products[data-showcase-v2] .q-hr-prog-n {
    flex: 0 0 auto;
    color: var(--q-text-2);
    font-size: 0.92em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ------------------------------------------------------------------ */
/* Alerts — the invitations that actually went out                     */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-hr-feed {
    display: flex;
    flex: 0 0 auto;
    flex-direction: column;
    gap: 0.5em;
    min-width: 0;
}

.products[data-showcase-v2] .q-hr-al {
    display: flex;
    align-items: center;
    gap: 0.7em;
    min-height: 3.1em;
    padding: 0.55em 0.9em;
    border-radius: var(--q-r-row);
    background: var(--q-bg-subtle);
    opacity: 0;
    transform: translateY(-3px);
    transition: opacity 240ms ease, transform 300ms var(--ease-out);
}

.products[data-showcase-v2] .q-hr-al.in { opacity: 1; transform: none; }

.products[data-showcase-v2] .q-hr-al-ic,
.products[data-showcase-v2] .q-hr-alert-ic {
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    width: 1.6em;
    height: 1.6em;
    border-radius: 50%;
    background: var(--q-chip-pos-bg);
    color: var(--q-positive-text);
    line-height: 0;
}

.products[data-showcase-v2] .q-hr-al-ic svg,
.products[data-showcase-v2] .q-hr-alert-ic svg { width: 1em; height: 1em; }

.products[data-showcase-v2] .q-hr-al-tx,
.products[data-showcase-v2] .q-hr-alert-tx {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.1em;
    min-width: 0;
}

.products[data-showcase-v2] .q-hr-al-tx b {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    color: var(--q-text);
    font-weight: 500;
    line-height: 1.35;
}

.products[data-showcase-v2] .q-hr-al-tx > span,
.products[data-showcase-v2] .q-hr-alert-tx > span {
    color: var(--q-text-2);
    font-size: 0.85em;
    line-height: 1.35;
}

.products[data-showcase-v2] .q-hr-al-w {
    flex: 0 0 auto;
    color: var(--q-text-3);
    font-size: 0.85em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ------------------------------------------------------------------ */
/* The bands — the rule every verdict on this screen came out of       */
/* ------------------------------------------------------------------ */

.products[data-showcase-v2] .q-hr-bands { flex: 0 0 auto; }

.products[data-showcase-v2] .q-hr-bands .q-tr {
    grid-template-columns: minmax(0, 1fr) 3.6em minmax(2em, 4em) 2em;
    gap: 0.6em;
    min-height: 3.2em;
}

.products[data-showcase-v2] .q-hr-bands .q-tr-n > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.products[data-showcase-v2] .q-hr-share {
    overflow: hidden;
    height: 0.3em;
    border-radius: var(--q-r-full);
    background: var(--q-bg-hover);
}

.products[data-showcase-v2] .q-hr-share i {
    display: block;
    width: 0;
    height: 100%;
    border-radius: var(--q-r-full);
    background: var(--q-text-3);
    transition: width 420ms var(--ease-out);
}

.products[data-showcase-v2] .q-hr-share i.is-good { background: var(--q-positive); }
.products[data-showcase-v2] .q-hr-share i.is-warn { background: var(--q-warning); }
.products[data-showcase-v2] .q-hr-share i.is-bad { background: var(--q-negative); }

/* ------------------------------------------------------------------ */
/* The confirmation — a quiet chip that floats off, and says so aloud  */
/* ------------------------------------------------------------------ */

/* The chip carries the primitive's 0.92em, and `bottom` resolves against an
   element's OWN font-size — so the clearance lives on a wrapper that still
   counts in the app's em. It floats over a section (§4.11) but must not sit
   ON a reading: the dock's top is 5.84em up and the inflow chart's axis row
   (the "now" chip included) ends 8.5em up, so this clears the taller of the
   two. Measured at both ends of --q-fs: 9.4em keeps ~0.9em over the now chip
   and still leaves ~1.6em of air above the queue table it usually sits by. */
.products[data-showcase-v2] .q-hr-alert-w {
    position: absolute;
    z-index: 5;
    right: 1.5em;
    bottom: 9.4em;
    display: flex;
    justify-content: flex-end;
    max-width: calc(100% - 3em);
    pointer-events: none;
}

.products[data-showcase-v2] .q-hr-alert {
    min-width: 0;
    align-items: center;
    gap: 0.6em;
    padding: 0.55em 0.85em;
    opacity: 0;
    transform: translateY(0.5em);
    transition: opacity 220ms ease, transform 300ms var(--ease-out);
}

.products[data-showcase-v2] .q-hr-alert.in { opacity: 1; transform: none; }

.products[data-showcase-v2] .q-hr-alert-tx b {
    overflow: hidden;
    color: var(--q-text);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* ================================================================== */
/* Keyframes                                                           */
/* ================================================================== */

@keyframes qPulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.45; }
}

@keyframes qCaret {
    0%, 100% { opacity: 1; }
    50% { opacity: 0; }
}

@keyframes qThink {
    0%, 100% { opacity: 0.28; transform: translateY(0); }
    50% { opacity: 1; transform: translateY(-0.16em); }
}

@keyframes qSpin {
    to { transform: rotate(360deg); }
}

@keyframes qLiveRing {
    0% { transform: scale(0.7); opacity: 0.5; }
    100% { transform: scale(2.2); opacity: 0; }
}

/* ================================================================== */
/* Responsive                                                          */
/* ================================================================== */

@media (max-width: 1120px) {
    .products[data-showcase-v2] .prod-layout {
        grid-template-columns: minmax(17.5rem, 0.72fr) minmax(28rem, 1.28fr);
        gap: 2rem;
    }

    .products[data-showcase-v2] .prod-desc { padding-right: 1rem; }

    .products[data-showcase-v2] .q-frame { inset: 3.5% 3% 4% 3%; }
    .products[data-showcase-v2] .q-top { min-height: 3.6em; padding: 0 1.15em; }
    .products[data-showcase-v2] .q-ctl { padding: 0 1.15em 0.8em; }
    .products[data-showcase-v2] .q-view { padding: 0.3em 1.15em 1.15em; }
    .products[data-showcase-v2] .q-bleed { margin-left: -1.15em; margin-right: -1.15em; }
    .products[data-showcase-v2] .q-kpis { gap: 2em; }
}

@media (max-width: 960px) {
    .products[data-showcase-v2] {
        min-height: 0;
        padding-top: 6.25rem;
    }

    .products[data-showcase-v2] .prod-head {
        grid-template-columns: 1fr;
        gap: 1.4rem;
        margin-bottom: 2.5rem;
    }

    .products[data-showcase-v2] .prod-lede { max-width: 52ch; }

    .products[data-showcase-v2] .prod-layout {
        display: grid;
        grid-template-columns: 1fr;
        gap: 2.5rem;
    }

    .products[data-showcase-v2] .prod-visual-home { display: block; }

    .products[data-showcase-v2] .prod-visual {
        height: clamp(30rem, 84vw, 38rem);
        margin: 0;
    }

    /* stacked layout: the stage is full-width again */
    .products[data-showcase-v2] .q-frame { inset: 4.5% 4% 5% 4%; }

    .products[data-showcase-v2] .prod-foot { margin-top: 1.7rem; }
}

@media (max-width: 640px) {
    .products[data-showcase-v2] { padding: 5.5rem 1.25rem 4.5rem; }

    .products[data-showcase-v2] .prod-heading {
        font-size: clamp(1.7rem, 7.6vw, 2.2rem);
        max-width: 12em;
    }

    .products[data-showcase-v2] .prod-head { margin-bottom: 2rem; }

    .products[data-showcase-v2] .prod-trigger {
        width: calc(100% + 1.2rem);
        margin: 0 -0.6rem;
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 0.18rem 0.55rem;
        padding: 1rem 0.6rem;
    }

    .products[data-showcase-v2] .prod-name { font-size: 1.22rem; }
    .products[data-showcase-v2] .prod-kicker { font-size: 0.69rem; }

    .products[data-showcase-v2] .prod-desc {
        padding: 0.05rem 0.25rem 1.2rem 0;
        font-size: 0.86rem;
    }

    .products[data-showcase-v2] .prod-stage-meta { font-size: 0.56rem; }

    .products[data-showcase-v2] .prod-visual { height: 30rem; }

    .products[data-showcase-v2] .prod-stage-hint { display: none; }

    /* the frame goes nearly edge-to-edge and the app tightens up */
    .products[data-showcase-v2] .q-frame { inset: 3% 2.5%; --q-r-frame: 16px; }
    .products[data-showcase-v2] .q-top { min-height: 3.2em; padding: 0 0.9em; gap: 0.5em; }
    .products[data-showcase-v2] .q-ctl { padding: 0 0.9em 0.65em; gap: 0.4em; }
    .products[data-showcase-v2] .q-view { gap: 0.85em; padding: 0.25em 0.9em 0.9em; }
    .products[data-showcase-v2] .q-bleed { margin-left: -0.9em; margin-right: -0.9em; }
    .products[data-showcase-v2] .q-kpis { gap: 1.3em; }
    .products[data-showcase-v2] .q-grid2 { grid-template-columns: minmax(0, 1fr); }
    .products[data-showcase-v2] .q-ava,
    .products[data-showcase-v2] .q-proj-ch { display: none; }
    .products[data-showcase-v2] .q-dock { bottom: 0.8em; }
    .products[data-showcase-v2] .q-dock button { width: 2.35em; height: 2.35em; }
}

@media (hover: hover) and (pointer: fine) {
    .products[data-showcase-v2] .prod-trigger:hover .prod-marker {
        border-color: rgba(29, 29, 31, 0.4);
    }
}

/* ================================================================== */
/* Reduced motion                                                      */
/* ================================================================== */

@media (prefers-reduced-motion: reduce) {
    .products[data-showcase-v2] *,
    .products[data-showcase-v2] *::before,
    .products[data-showcase-v2] *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        transition-delay: 0s !important;
        scroll-behavior: auto !important;
    }

    .products[data-showcase-v2] [data-rise],
    .products[data-showcase-v2] .q-tip,
    .products[data-showcase-v2] .q-mark-dot,
    .products[data-showcase-v2] .q-area.q-fade,
    .products[data-showcase-v2] .q-rt i {
        opacity: 1 !important;
        transform: none !important;
    }

    .products[data-showcase-v2] .q-mark-dot { transform: translate(-50%, -50%) !important; }
    .products[data-showcase-v2] .q-tip { transform: translate(-50%, calc(-100% - 0.7em)) !important; }
    .products[data-showcase-v2] .q-rt i { transform: scaleY(1) !important; }

    .products[data-showcase-v2] .q-line.q-draw { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }

    .products[data-showcase-v2] .caret,
    .products[data-showcase-v2] .think,
    .products[data-showcase-v2] .spin { display: none !important; }
}
