﻿/* ---------------------------------------------------------------------------
   `hidden` has to actually hide.

   The UA stylesheet gives [hidden] display:none with normal weight, and every
   Bootstrap display utility (.d-flex, .d-block, .d-grid) is !important — so a
   hidden .d-flex stays on screen, and reading el.hidden in the console says
   `true` while the thing is plainly visible. That is exactly how the guest
   checkout's delivery-quote banner shipped showing on a pickup order.

   Loaded after bootstrap.min.css, same specificity, so source order wins.
--------------------------------------------------------------------------- */
[hidden] {
    display: none !important;
}

/* ---------------------------------------------------------------------------
   Address suggestions (address-suggest.js). The list is appended inside the
   input's parent, which the script makes the positioning host; everything is
   themed ink on a themed surface, so it reads in both modes.
--------------------------------------------------------------------------- */
.qq-addr-host { position: relative; }
.qq-addr-list {
    position: absolute; z-index: 30; box-sizing: border-box;
    margin: .25rem 0 0; padding: .25rem 0; list-style: none;
    background: var(--qq-card); border: 1px solid var(--qq-border);
    border-radius: 12px; box-shadow: 0 8px 24px rgba(23, 21, 18, .12);
}
.qq-addr-item { padding: .55rem .85rem; cursor: pointer; display: flex; flex-direction: column; gap: .1rem; }
.qq-addr-item .m { font-weight: 600; color: var(--qq-text); font-size: .92rem; }
.qq-addr-item .s { color: var(--qq-text-muted); font-size: .8rem; }
.qq-addr-item.is-active, .qq-addr-item:hover { background: var(--qq-shell); }
.qq-addr-none { padding: .55rem .85rem; color: var(--qq-text-faint); font-size: .85rem; }
.qq-addr-credit { padding: .3rem .85rem .15rem; text-align: right; color: var(--qq-text-faint); font-size: .72rem; letter-spacing: .02em; }

/* ---------------------------------------------------------------------------
   QuickQuick design tokens — Modern UI
   Warm neutrals + single brass accent. The old gold gradient is retired.
   Store pages still override the --sf-* variables with each seller's branding.
--------------------------------------------------------------------------- */
:root {
    /* neutrals (warm) */
    --qq-ink: #171512;
    --qq-paper: #faf8f4;
    --qq-shell: #f5f2ec;
    --qq-card: #ffffff;
    --qq-border: #e7e2d8;
    --qq-border-soft: #f2eee6;
    --qq-text: #171512;
    --qq-text-body: #4f483d;
    --qq-text-muted: #7a7264;
    --qq-text-faint: #a39a88;

    /* brass accent */
    --qq-brass: #9a6b1e;
    --qq-brass-deep: #6d4b12;
    --qq-brass-tint: #f0e6d2;
    --qq-brass-soft: #e9e2d2;
    --qq-gold-bright: #d9a94e;

    /* status pairs */
    --qq-ok-bg: #e5f2ea;    --qq-ok-fg: #1f7a4d;
    --qq-warn-bg: #faf0d8;  --qq-warn-fg: #96690d;
    --qq-info-bg: #e5eff5;  --qq-info-fg: #2f6b8f;
    --qq-ready-bg: #efe6f2; --qq-ready-fg: #6b4a7a;
    --qq-bad-bg: #f9e8e5;   --qq-bad-fg: #b2483c;
    --qq-mute-bg: #eeeae2;  --qq-mute-fg: #7a7264;

    /* Inactive control surfaces: toggle/radio tracks and dropzone edges. Sits
       a shade heavier than --qq-border so an off control reads as a control
       rather than a hairline, and inverts with the theme like one. */
    --qq-track-off: #cfc7b8;

    /* admin chrome — v3 "editorial back-office": warm ivory paper, espresso
       sidebar, one terracotta accent, mono meta labels */
    --qq-admin-bar: #232019;
    --qq-admin-bar-active: #332e24;
    --qq-admin-accent: #bf4c2e;
    --qq-admin-shell: #f4f0e8;
    --qq-admin-border: #e4ddcf;
    /* Was #8b8272, which read 3.73:1 on --qq-admin-card — under AA for the
       sub-lines it carries all over the console (the "trial ends …" line under
       a store name, row meta, hints). Sized against the *worst* surface it lands
       on rather than the card: --qq-admin-shell is darker than the card, and a
       hovered row darker still, so a value that just cleared 4.5 on the card
       still failed on both. This is the storefront's --sf-muted, an existing app
       value, and clears AA on all three. Dark is already 6.39:1, left alone. */
    --qq-admin-muted: #6f685c;
    --qq-admin-faint: #a89f8d;
    --qq-admin-input: #f6f2e9;
    --qq-admin-flag: #faf1ec;
    --qq-admin-divider: #f2ede2;
    --qq-admin-card: #fffdf8;
    --qq-admin-ink: #211d18;
    --qq-admin-btn-fg: #fbf8f1;
    --qq-admin-btn-hover: #332e24;
    --qq-admin-mono: 'Space Mono', Consolas, monospace;

    /* Seller schedule (day rail) — values the palette had no name for.
       --qq-on-ink-accent is the one that matters: an ink-filled surface
       INVERTS in dark, so an accent drawn on it cannot be --qq-gold-bright
       (identical in both themes, ~1.9:1 on a light block). */
    --qq-row-hover: #fdfcf9;
    --qq-text-ghost: #c4bbaa;
    --qq-gold-soft: #d9c9a4;
    --qq-on-ink-accent: #d9a94e;
    --qq-ink-hover: #332e24;
    --qq-ok-btn: #1f7a4d;
    --qq-ok-btn-hover: #19653f;
    --qq-warn-border: #eee0bd;
    --qq-bad-fg-hover: #8d3529;
    --qq-bad-bg-soft: #fdf6f4;
    --qq-bad-border: #f0d9d4;
    --qq-bad-border-2: #e6b8ad;

    /* per-store theme hooks (defaults = QuickQuick brand) */
    --qq-store-primary: var(--qq-brass);
    --qq-store-accent: var(--qq-gold-bright);

    color-scheme: light;
}

/* Dark mode: the same 43 tokens re-pointed at a warm charcoal palette. Applied
   via data-theme on <html> (set before paint by the inline script in App.razor;
   toggled by [data-theme-toggle] in nav-drawer.js). Storefront pages are NOT
   affected — .sf-page colors come from each seller's own tone choice. */
html[data-theme="dark"] {
    color-scheme: dark;

    /* neutrals — ink and paper swap roles, so ink-filled buttons invert to
       light-on-dark like the storefront's dark segmented tab */
    --qq-ink: #f2ede4;
    --qq-paper: #161310;
    --qq-shell: #1d1913;
    --qq-card: #221e19;
    --qq-border: #3a342b;
    --qq-border-soft: #2b2721;
    --qq-text: #f2ede4;
    --qq-text-body: #d8d0c2;
    --qq-text-muted: #a89f8d;
    --qq-text-faint: #7d7565;

    /* brass accent — brighter for contrast on dark surfaces */
    --qq-brass: #d9a94e;
    --qq-brass-deep: #e7c078;
    --qq-brass-tint: #33291a;
    --qq-brass-soft: #2e281d;
    --qq-gold-bright: #d9a94e;

    /* status pairs */
    --qq-ok-bg: #1c2e24;    --qq-ok-fg: #7fc9a2;
    --qq-warn-bg: #33290f;  --qq-warn-fg: #d9b25c;
    --qq-info-bg: #17272f;  --qq-info-fg: #7db3d1;
    --qq-ready-bg: #281f2c; --qq-ready-fg: #b493c4;
    --qq-bad-bg: #331d19;   --qq-bad-fg: #e08578;
    --qq-mute-bg: #2a251f;  --qq-mute-fg: #a89f8d;
    /* The light value glared on a dark card. Kept in step with --qq-border
       (#3a342b) so off controls sit with the rest of the dark chrome; the knob
       flips to --qq-ink to stay legible against it. */
    --qq-track-off: #3d372e;

    /* Seller schedule — see the light block. --qq-ok-btn goes LIGHT green
       here, so anything filled with it takes dark text, not white. */
    --qq-row-hover: #2a251f;
    --qq-text-ghost: #5f5850;
    --qq-gold-soft: #6b5528;
    --qq-on-ink-accent: #8a5f14;
    --qq-ink-hover: #dcd3c3;
    --qq-ok-btn: #7fc9a2;
    --qq-ok-btn-hover: #96d6b3;
    --qq-warn-border: #4a3a14;
    --qq-bad-fg-hover: #f0a99e;
    --qq-bad-bg-soft: #2a1a16;
    --qq-bad-border: #4a2a23;
    --qq-bad-border-2: #6b3a30;

    /* admin chrome — the espresso sidebar already reads dark; the ivory shell
       flips to charcoal */
    --qq-admin-bar: #191611;
    --qq-admin-bar-active: #2b2620;
    --qq-admin-shell: #191611;
    --qq-admin-border: #383228;
    --qq-admin-muted: #a89f8d;
    --qq-admin-faint: #857c6b;
    --qq-admin-input: #262119;
    --qq-admin-flag: #2e211b;
    --qq-admin-divider: #2b2620;
    --qq-admin-card: #211d17;
    --qq-admin-ink: #efe8db;
    /* ink-filled admin buttons invert to ivory-on-dark, so their text and
       hover state flip with them */
    --qq-admin-btn-fg: #191611;
    --qq-admin-btn-hover: #fdfaf2;
    --qq-admin-accent: #e0705a;
}

html, body {
    font-family: 'Space Grotesk', Helvetica, Arial, sans-serif;
    background-color: var(--qq-paper);
    color: var(--qq-text);
}

h1, h2, h3, h4, h5 {
    font-weight: 700;
    letter-spacing: -0.03em;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: var(--qq-brass);
    text-decoration: none;
}

a:hover, .btn-link:hover {
    color: var(--qq-brass-deep);
    text-decoration: underline;
}

.content {
    padding-top: 1.5rem;
}

/* --- Buttons ---------------------------------------------------------------- */
.qq-btn,
.qq-btn-gold,
.qq-btn-outline,
.qq-btn-danger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    font-family: inherit;
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.2;
    padding: 0.62rem 1.4rem;
    border-radius: 999px;
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    transition: background-color 140ms ease, border-color 140ms ease, filter 140ms ease;
    white-space: nowrap;
}

.qq-btn {
    background: var(--qq-ink);
    color: var(--qq-paper);
}

.qq-btn:hover {
    filter: brightness(1.35);
    color: var(--qq-paper);
    text-decoration: none;
}

.qq-btn-gold {
    background: var(--qq-gold-bright);
    /* Fixed ink, not var(--qq-ink): unlike ok-fg below, gold-bright is the same
       #d9a94e in both themes, so a flipping label turned ivory-on-gold (1.9:1)
       in dark mode and the primary CTA lost its text. */
    color: #171512;
    font-weight: 700;
}

.qq-btn-gold:hover {
    filter: brightness(0.94);
    color: #171512;
    text-decoration: none;
}

.qq-btn-outline {
    background: var(--qq-card);
    border-color: var(--qq-border);
    color: var(--qq-ink);
}

.qq-btn-outline:hover {
    background: var(--qq-paper);
    color: var(--qq-ink);
    text-decoration: none;
}

.qq-btn-danger {
    background: transparent;
    border-color: color-mix(in srgb, var(--qq-bad-fg) 30%, transparent);
    color: var(--qq-bad-fg);
}

.qq-btn-danger:hover {
    background: var(--qq-bad-bg);
    color: var(--qq-bad-fg);
    text-decoration: none;
}

.qq-btn-ok {
    background: var(--qq-ok-fg);
    /* Paper, not #fff: dark mode flips ok-fg to a light green, so the label
       has to flip dark with the paper token. */
    color: var(--qq-paper, #fff);
}

.qq-btn-ok:hover {
    filter: brightness(1.1);
    color: var(--qq-paper, #fff);
}

.qq-btn-lg {
    font-size: 1rem;
    padding: 0.85rem 1.8rem;
}

.qq-btn-sm {
    font-size: 0.84rem;
    padding: 0.45rem 1.1rem;
}

.qq-btn-block {
    display: flex;
    width: 100%;
}

.qq-btn:disabled, .qq-btn-gold:disabled, .qq-btn-outline:disabled, .qq-btn-danger:disabled, .qq-btn-ok:disabled {
    opacity: 0.45;
    pointer-events: none;
}

/* Tertiary actions ("Manage schedule", "Chat", "Cancel"): pill-shaped ghost
   buttons — quieter than qq-btn-outline, but still clearly tappable. */
.qq-link,
.qq-link-danger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    background: none;
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 0.3rem 0.85rem;
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
}

.qq-link {
    color: var(--qq-brass);
}

.qq-link:hover {
    background: var(--qq-brass-tint);
    border-color: var(--qq-brass-soft);
    color: var(--qq-brass-deep);
    text-decoration: none;
}

.qq-link-danger {
    color: var(--qq-bad-fg);
}

.qq-link-danger:hover {
    background: var(--qq-bad-bg);
    border-color: color-mix(in srgb, var(--qq-bad-fg) 30%, transparent);
    color: var(--qq-bad-fg);
    text-decoration: none;
}

.qq-link:focus-visible,
.qq-link-danger:focus-visible {
    outline: 2px solid var(--qq-gold-bright);
    outline-offset: 2px;
}

.qq-link:disabled,
.qq-link-danger:disabled {
    opacity: 0.45;
    pointer-events: none;
}

/* --- Status pills ------------------------------------------------------------ */
.qq-pill {
    display: inline-block;
    padding: 0.2rem 0.75rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 700;
    line-height: 1.4;
    white-space: nowrap;
}

.qq-pill-ok    { background: var(--qq-ok-bg);    color: var(--qq-ok-fg); }
.qq-pill-warn  { background: var(--qq-warn-bg);  color: var(--qq-warn-fg); }
.qq-pill-info  { background: var(--qq-info-bg);  color: var(--qq-info-fg); }
.qq-pill-ready { background: var(--qq-ready-bg); color: var(--qq-ready-fg); }
.qq-pill-bad   { background: var(--qq-bad-bg);   color: var(--qq-bad-fg); }
.qq-pill-mute  { background: var(--qq-mute-bg);  color: var(--qq-mute-fg); }
.qq-pill-brass { background: var(--qq-brass-tint); color: var(--qq-brass-deep); }

/* --- Cards & list rows -------------------------------------------------------- */
.qq-card {
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 20px;
}

.qq-card-pad {
    padding: 1.5rem;
}

.qq-card-elevated {
    box-shadow: 0 4px 20px rgba(23, 21, 18, 0.06);
}

.qq-card-header {
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--qq-border-soft);
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-weight: 700;
}

.qq-row {
    padding: 0.9rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    /* Wrap, so a row that runs out of width moves its trailing controls to a
       second line instead of crushing the column that carries the words. See
       the min-width note below — the two rules only work together. */
    flex-wrap: wrap;
}

.qq-row + .qq-row {
    border-top: 1px solid var(--qq-border-soft);
}

/* A flex item's default min-width:auto refuses to shrink below its content, so
   one long line in the flexible column (a reschedule proposal, a dispute trail)
   sets a floor that pushes the row's trailing controls past the card edge —
   the Cancel button ends up outside the border.
   
   min-width:0 fixed that by letting the column shrink — but it shrinks to
   NOTHING, and it is the only flexible item in the row, so it absorbs the whole
   shortfall of every chip, hint and button beside it. On an appointment row
   that measured 63px against 832: the service name, store and time wrapping one
   word per line, and a chat panel folded into a sliver.
   
   So: a floor it may not go below, and `flex-wrap` on the row above so the
   trailing controls give way instead. `min()` keeps it honest on a narrow
   phone, where 100% is the smaller of the two and the column simply takes its
   own line. */
.qq-row > .flex-grow-1 {
    min-width: min(100%, 18rem);
}

/* --- Micro label -------------------------------------------------------------- */
.qq-microlabel {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--qq-text-faint);
}

/* --- Forms --------------------------------------------------------------------- */
.qq-label {
    display: block;
    font-size: 0.85rem;
    color: var(--qq-text-muted);
    margin-bottom: 0.35rem;
}

.qq-input, .qq-select, textarea.qq-input {
    font-family: inherit;
    font-size: 0.92rem;
    width: 100%;
    box-sizing: border-box;
    padding: 0.65rem 0.85rem;
    border: 1px solid var(--qq-border);
    border-radius: 12px;
    background: var(--qq-paper);
    color: var(--qq-text);
}

.qq-input:focus, .qq-select:focus, .qq-btn:focus-visible, .qq-btn-gold:focus-visible,
.qq-btn-outline:focus-visible, .qq-btn-danger:focus-visible, .qq-toggle input:focus-visible + .qq-toggle-track, .qq-switch input:focus-visible + .qq-toggle-track {
    outline: 2px solid var(--qq-brass);
    outline-offset: 2px;
    box-shadow: none;
}

/* --- Date & time fields ----------------------------------------------------------------
   Native date/time inputs, dressed to match the rest of the kit. Deliberately
   still native: the browser's own picker is keyboard-accessible, localised, and
   on a phone it opens the OS wheel, none of which a hand-rolled calendar gets
   for free. :root already declares color-scheme per theme, so the popup itself
   comes up dark in dark mode — what was left was the field.

   An earlier pass drew a custom brass glyph as the field's background and hid
   Chrome's real indicator behind it at zero opacity. That is fragile — the
   invisible button has to line up with the painted icon or clicking the icon
   opens nothing — and it broke opening the picker. The indicator is now left
   alone and simply tinted, so the control keeps its native behaviour exactly.

   Type selectors here are (0,1,1), which loses to the .qq-input class rules the
   admin console layers on, so admin fields keep the admin palette and only pick
   up the chrome below. */
input[type="date"],
input[type="time"],
input[type="datetime-local"] {
    font-family: inherit;
    font-size: 0.92rem;
    box-sizing: border-box;
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--qq-border);
    border-radius: 12px;
    background-color: var(--qq-paper);
    color: var(--qq-text);
    min-height: 44px; /* thumb-sized, per the mobile audit */
    transition: border-color 120ms ease;
}

input[type="date"]:hover,
input[type="time"]:hover,
input[type="datetime-local"]:hover {
    border-color: color-mix(in srgb, var(--qq-brass) 45%, var(--qq-border));
}

/* Chrome ships a near-black glyph, which disappears on a dark field. Tinting
   rather than replacing keeps the button that opens the picker untouched. */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
    cursor: pointer;
    opacity: 0.65;
    transition: opacity 120ms ease;
}

input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="time"]::-webkit-calendar-picker-indicator:hover,
input[type="datetime-local"]::-webkit-calendar-picker-indicator:hover {
    opacity: 1;
}

html[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
html[data-theme="dark"] input[type="time"]::-webkit-calendar-picker-indicator,
html[data-theme="dark"] input[type="datetime-local"]::-webkit-calendar-picker-indicator {
    filter: invert(1);
}

/* The segment you're editing, in brass instead of the browser's default blue. */
input[type="date"]::-webkit-datetime-edit-year-field:focus,
input[type="date"]::-webkit-datetime-edit-month-field:focus,
input[type="date"]::-webkit-datetime-edit-day-field:focus,
input[type="datetime-local"]::-webkit-datetime-edit-year-field:focus,
input[type="datetime-local"]::-webkit-datetime-edit-month-field:focus,
input[type="datetime-local"]::-webkit-datetime-edit-day-field:focus,
input[type="datetime-local"]::-webkit-datetime-edit-hour-field:focus,
input[type="datetime-local"]::-webkit-datetime-edit-minute-field:focus,
input[type="time"]::-webkit-datetime-edit-hour-field:focus,
input[type="time"]::-webkit-datetime-edit-minute-field:focus,
input[type="time"]::-webkit-datetime-edit-ampm-field:focus {
    background: var(--qq-brass-tint);
    color: var(--qq-brass-deep);
    border-radius: 4px;
    outline: none;
}

.qq-hint {
    font-size: 0.8rem;
    color: var(--qq-text-faint);
    margin-top: 0.3rem;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--qq-ok-fg);
}

.invalid {
    outline: 1px solid var(--qq-bad-fg);
}

.validation-message {
    color: var(--qq-bad-fg);
    font-size: 0.85rem;
}

input[type="checkbox"] {
    accent-color: var(--qq-ink);
}

/* --- Segmented control ---------------------------------------------------------- */
.qq-seg {
    display: inline-flex;
    background: var(--qq-mute-bg);
    border-radius: 999px;
    padding: 4px;
    gap: 0;
}

.qq-seg > a, .qq-seg > button, .qq-seg > span {
    border: none;
    background: transparent;
    border-radius: 999px;
    padding: 0.5rem 1.35rem;
    font-family: inherit;
    font-size: 0.88rem;
    font-weight: 500;
    color: var(--qq-text-muted);
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
}

/* Radio-backed segment (static-SSR forms, where a button's @onclick is dead).
   The input is hidden but still focusable, so keyboard users land on it and the
   label carries a visible focus ring. */
.qq-seg-radio label {
    border: none;
    background: transparent;
    border-radius: 999px;
    padding: 0.5rem 1.35rem;
    font-size: 0.88rem;
    font-weight: 500;
    color: var(--qq-text-muted);
    cursor: pointer;
    white-space: nowrap;
}

.qq-seg-radio label.disabled {
    opacity: 0.5;
    cursor: default;
}

.qq-seg-radio input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.qq-seg-radio label:has(input:focus-visible) {
    outline: 2px solid var(--qq-brass);
    outline-offset: 2px;
}

/* Without :has there is no pill, and the input itself is invisible, so nothing
   on the control would show what is selected. Show the native radio instead. */
@supports not selector(:has(*)) {
    .qq-seg-radio input[type="radio"] {
        position: static;
        opacity: 1;
        width: auto;
        height: auto;
        margin-right: 0.4rem;
    }
}

/* A server-rendered `active` class is honest on an interactive page and a lie on
   a static-SSR one: clicking a radio there changes no C# and re-renders nothing,
   so the pill would sit on whatever was posted. :checked is the browser's own
   truth, needs no script, and keeps the control correct with JS off. */
.qq-seg > .active,
.qq-seg-radio label.active,
.qq-seg-radio label:has(input:checked) {
    background: var(--qq-card);
    box-shadow: 0 1px 4px rgba(23, 21, 18, 0.1);
    font-weight: 700;
    color: var(--qq-text);
}

.qq-seg > a:hover {
    color: var(--qq-text);
    text-decoration: none;
}

/* --- Filter chips ------------------------------------------------------------------ */
.qq-chip {
    display: inline-block;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    color: var(--qq-text-body);
    font-size: 0.85rem;
    font-weight: 500;
    padding: 0.45rem 1.1rem;
    border-radius: 999px;
    cursor: pointer;
    font-family: inherit;
}

.qq-chip.active {
    background: var(--qq-ink);
    border-color: var(--qq-ink);
    color: var(--qq-paper);
    font-weight: 600;
}

/* --- Toggle switch ------------------------------------------------------------------- */
/* .qq-toggle is the compact form: switch plus its own small-caps typography.
   .qq-switch is the same mechanism without the type treatment, for rows whose
   label is a heading plus a hint line and shouldn't be shrunk to 0.82rem. */
.qq-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--qq-text-muted);
}

.qq-switch {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    cursor: pointer;
}

/* The track is a fixed-height pill; on a multi-line row nudge it onto the
   first line rather than letting align-items stretch the row around it. */
.qq-switch > .qq-toggle-track {
    margin-top: 2px;
}

.qq-toggle input,
.qq-switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.qq-toggle-track {
    width: 34px;
    height: 20px;
    border-radius: 999px;
    background: var(--qq-track-off);
    position: relative;
    flex-shrink: 0;
    transition: background-color 140ms ease;
}

.qq-toggle-track::after {
    content: "";
    position: absolute;
    left: 2px;
    top: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    /* The knob has to contrast with a track that changes colour per state, so
       it switches too: ink while off (dark knob on the light track, light knob
       on the dark one), paper once checked (see the :checked rule below, where
       the track becomes ok-fg and inverts the other way). */
    background: var(--qq-ink);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--qq-paper) 30%, transparent);
    transition: transform 140ms ease;
}

.qq-toggle input:checked + .qq-toggle-track,
.qq-switch input:checked + .qq-toggle-track {
    background: var(--qq-ok-fg);
}

.qq-toggle input:checked + .qq-toggle-track::after,
.qq-switch input:checked + .qq-toggle-track::after {
    background: var(--qq-paper);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--qq-ink) 22%, transparent);
    transform: translateX(14px);
}

.qq-toggle input:checked ~ .qq-toggle-label {
    color: var(--qq-ok-fg);
}

/* Inside the console the off-state label follows the admin palette rather than
   the site's muted grey. Lower specificity than the :checked rule above, so a
   toggle that's on still reads green. */
.admin-shell .qq-toggle-label,
.admin-page-body .qq-toggle-label,
.admin-page-bar .qq-toggle-label {
    color: var(--qq-admin-ink);
}

/* Themed checkbox, for the few places a switch would be the wrong control: an
   explicit acknowledgement the reader must tick, where a switch reads like a
   preference that can be flipped back. */
.qq-check {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    cursor: pointer;
}

.qq-check input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.qq-check-box {
    width: 18px;
    height: 18px;
    margin-top: 1px;
    border-radius: 5px;
    flex-shrink: 0;
    position: relative;
    border: 2px solid var(--qq-track-off);
    background: var(--qq-card);
    transition: background-color 120ms ease, border-color 120ms ease;
}

.qq-check input:checked + .qq-check-box {
    background: var(--qq-ok-fg);
    border-color: var(--qq-ok-fg);
}

/* Paper again, so the tick stays visible on ok-fg in both themes. */
.qq-check input:checked + .qq-check-box::after {
    content: "";
    position: absolute;
    left: 4px;
    top: 1px;
    width: 5px;
    height: 9px;
    border: solid var(--qq-paper);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.qq-check input:focus-visible + .qq-check-box {
    outline: 2px solid var(--qq-brass);
    outline-offset: 2px;
}

/* --- Avatars ---------------------------------------------------------------------------- */
.qq-avatar {
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    font-size: 0.95rem;
    background: var(--qq-brass-soft);
    color: var(--qq-brass-deep);
    object-fit: cover;
}

.qq-avatar-sm { width: 30px; height: 30px; font-size: 0.8rem; }
.qq-avatar-lg { width: 48px; height: 48px; font-size: 1.25rem; }

/* --- Alert banners (tinted cards) ---------------------------------------------------------- */
.qq-banner {
    border-radius: 14px;
    padding: 0.9rem 1.15rem;
    font-size: 0.92rem;
    font-weight: 600;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
}

.qq-banner-ok   { background: var(--qq-ok-bg);   color: var(--qq-ok-fg);   border: 1px solid color-mix(in srgb, var(--qq-ok-fg) 25%, transparent); }
.qq-banner-warn { background: var(--qq-warn-bg); color: var(--qq-warn-fg); border: 1px solid color-mix(in srgb, var(--qq-warn-fg) 25%, transparent); }
.qq-banner-bad  { background: var(--qq-bad-bg);  color: var(--qq-bad-fg);  border: 1px solid color-mix(in srgb, var(--qq-bad-fg) 25%, transparent); }
.qq-banner-info { background: var(--qq-info-bg); color: var(--qq-info-fg); border: 1px solid color-mix(in srgb, var(--qq-info-fg) 25%, transparent); }

/* --- QuickQuick landing hero ------------------------------------------------ */
.qq-hero {
    display: grid;
    grid-template-columns: 7fr 5fr;
    gap: 3rem;
    align-items: center;
    padding: 4rem 0 3rem;
}

/* Phones: the hero stacks — a 7/5 split at 360px is unreadable. */
@media (max-width: 768px) {
    .qq-hero {
        grid-template-columns: 1fr;
        gap: 2rem;
        padding: 2.25rem 0 2rem;
    }

    .qq-hero-collage {
        grid-template-columns: 1fr 1fr;
        max-width: 26rem;
    }

    .qq-float-review {
        display: none;
    }
}

.qq-hero h1 {
    font-size: clamp(2.4rem, 4.8vw, 4.375rem);
    line-height: 1.0;
    letter-spacing: -0.045em;
    margin-bottom: 1.25rem;
}

.qq-hero .qq-gold-text {
    color: var(--qq-brass);
}

.qq-hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    border: 1px solid var(--qq-border);
    background: var(--qq-card);
    border-radius: 999px;
    padding: 0.35rem 0.9rem;
    font-size: 0.82rem;
    color: var(--qq-text-muted);
    margin-bottom: 1.5rem;
}

.qq-hero-eyebrow::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--qq-brass);
}

.qq-hero p {
    font-size: 1.1rem;
    line-height: 1.55;
    color: var(--qq-text-body);
    max-width: 30rem;
    margin-bottom: 2rem;
}

.qq-hero-search {
    display: flex;
    align-items: center;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 14px;
    padding: 6px 6px 6px 16px;
    max-width: 30rem;
    box-shadow: 0 2px 10px rgba(23, 21, 18, 0.05);
}

.qq-hero-search input {
    font-family: inherit;
    flex: 1;
    border: none;
    outline: none;
    font-size: 0.97rem;
    background: transparent;
    color: var(--qq-text);
    min-width: 0;
}

.qq-hero-media {
    /* Token stripes: the muted caption sits directly on this band, and the
       hardcoded light hatch left it light-on-light in dark mode. */
    background: repeating-linear-gradient(45deg, var(--qq-border-soft, #efe9dd) 0 14px, var(--qq-shell, #f6f2e9) 14px 28px);
    border: 1px solid var(--qq-border);
    border-radius: 20px;
    min-height: 340px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: ui-monospace, monospace;
    font-size: 0.82rem;
    color: var(--qq-text-muted);
}

.qq-hero-search-icon {
    color: var(--qq-text-faint);
    flex-shrink: 0;
    margin-right: 0.35rem;
}

.qq-hero-search .qq-hero-search-btn {
    border-radius: 12px;
}

.qq-hero-popular {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 1.1rem;
    font-size: 0.8rem;
    color: var(--qq-text-faint);
}

/* White pill chip used for popular searches, categories, etc. */
.qq-chip-link {
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 999px;
    padding: 0.4rem 1rem;
    font-size: 0.84rem;
    font-weight: 500;
    color: var(--qq-text-body);
    text-decoration: none;
    white-space: nowrap;
}

.qq-chip-link:hover {
    border-color: var(--qq-brass);
    color: var(--qq-text);
}

.qq-chip-link.active {
    background: var(--qq-ink);
    border-color: var(--qq-ink);
    color: var(--qq-paper);
    font-weight: 600;
}

/* Hero collage: one tall + two stacked live store tiles. */
.qq-hero-collage {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 170px 170px;
    gap: 1rem;
}

.qq-hero-tile {
    border-radius: 20px;
    overflow: hidden;
    border: 1px solid var(--qq-border);
    background: var(--qq-card);
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: var(--qq-text);
    transition: box-shadow 140ms ease;
}

.qq-hero-tile:hover {
    box-shadow: 0 6px 18px rgba(23, 21, 18, 0.12);
    color: var(--qq-text);
}

.qq-hero-tile.tall {
    grid-row: span 2;
}

.qq-hero-tile-band {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 0;
}

.qq-hero-tile-band span,
.qq-hero-tile-band img {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: #fff;
    font-weight: 700;
    font-size: 1.1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    object-fit: cover;
}

.qq-hero-tile.tall .qq-hero-tile-band span,
.qq-hero-tile.tall .qq-hero-tile-band img {
    width: 64px;
    height: 64px;
    font-size: 1.55rem;
}

.qq-hero-tile-body {
    padding: 0.7rem 0.9rem;
}

.qq-hero-tile-body .name {
    font-weight: 700;
    font-size: 0.86rem;
}

.qq-hero-tile.tall .qq-hero-tile-body .name {
    font-size: 0.95rem;
}

.qq-hero-tile-body .meta {
    font-size: 0.74rem;
    color: var(--qq-text-muted);
    margin-top: 1px;
}

.qq-hero-tile-body .star {
    color: var(--qq-brass);
    font-weight: 600;
}

/* Category chips band under the hero: one horizontally scrollable row with a
   slim always-visible scrollbar as the affordance; storefront.js additionally
   maps the mouse wheel to horizontal scrolling.
   NOTE: setting the standard `scrollbar-width` makes Chromium IGNORE the
   ::-webkit-scrollbar styling and fall back to overlay bars that hide at
   rest — so the standard properties are scoped to Firefox only. */
.qq-browse-chips {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    overflow-x: auto;
    padding-bottom: 0.5rem;
}

@supports (-moz-appearance: none) {
    .qq-browse-chips {
        scrollbar-width: thin;
        scrollbar-color: var(--qq-border) transparent;
    }
}

.qq-browse-chips::-webkit-scrollbar {
    height: 6px;
}

.qq-browse-chips::-webkit-scrollbar-track {
    background: transparent;
}

.qq-browse-chips::-webkit-scrollbar-thumb {
    background: var(--qq-border);
    border-radius: 99px;
}

.qq-browse-chips::-webkit-scrollbar-thumb:hover {
    background: var(--qq-text-faint);
}

.qq-browse-chips > * {
    flex-shrink: 0;
}

.qq-browse-chips .qq-microlabel {
    margin-right: 0.25rem;
    flex-shrink: 0;
}

.qq-count-hint {
    font-size: 0.82rem;
    color: var(--qq-text-faint);
}

.qq-see-all {
    font-weight: 600;
    font-size: 0.88rem;
    color: var(--qq-brass);
    text-decoration: none;
}

.qq-see-all:hover {
    color: var(--qq-brass-deep);
}

.qq-gold-dot {
    color: var(--qq-gold-bright);
}

/* Buyer account dropdown in the public nav. Bootstrap's dropdown paints from
   its own variables (white panel, near-black links) — feed them our tokens so
   the menu follows dark mode. */
.qq-account-menu {
    border: 1px solid var(--qq-border);
    border-radius: 14px;
    box-shadow: 0 10px 30px rgba(23, 21, 18, 0.14);
    padding: 0.4rem;
    min-width: 12rem;
    --bs-dropdown-bg: var(--qq-card);
    --bs-dropdown-color: var(--qq-text);
    --bs-dropdown-link-color: var(--qq-text);
    --bs-dropdown-link-hover-color: var(--qq-text);
    --bs-dropdown-link-hover-bg: var(--qq-paper);
    --bs-dropdown-divider-bg: var(--qq-border);
}

.qq-account-menu .dropdown-item {
    border-radius: 9px;
    padding: 0.5rem 0.8rem;
    font-size: 0.9rem;
    font-weight: 500;
}

/* Notification bell panel — same token feed as the account menu. The utility
   classes inside (border-bottom, text-muted) paint from Bootstrap variables,
   so those are fed too. */
.qq-notif-menu {
    border: 1px solid var(--qq-border);
    border-radius: 14px;
    box-shadow: 0 10px 30px rgba(23, 21, 18, 0.14);
    --bs-dropdown-bg: var(--qq-card);
    --bs-dropdown-color: var(--qq-text);
    --bs-dropdown-link-color: var(--qq-text);
    --bs-border-color: var(--qq-border);
    --bs-secondary-color: var(--qq-text-muted);
}

/* Phones: popper pins the panel to the bell and shoves it off the left edge.
   Pin it under the navbar with even gutters instead. */
@media (max-width: 575.98px) {
    .qq-notif-menu.show {
        position: fixed !important;
        inset: 66px 0.75rem auto 0.75rem !important;
        transform: none !important;
        min-width: 0 !important;
        max-width: none !important;
        width: auto !important;
    }
}

.qq-account-menu .dropdown-item:hover {
    background: var(--qq-paper);
}

/* Active public-nav link gets the brass underline from the design. */
.qq-navbar .nav-link.active {
    color: var(--qq-text);
    font-weight: 600;
    box-shadow: inset 0 -2px 0 var(--qq-brass);
}

/* --- Home store directory -------------------------------------------------- */
.qq-store-card {
    border: 1px solid var(--qq-border);
    border-radius: 16px;
    overflow: hidden;
    background: var(--qq-card);
    color: var(--qq-text);
    display: block;
    text-decoration: none;
    transition: box-shadow 140ms ease;
}

.qq-store-card:hover {
    box-shadow: 0 4px 14px rgba(23, 21, 18, 0.1);
    color: var(--qq-text);
    text-decoration: none;
}

.qq-store-card-band {
    height: 110px;
    position: relative;
    background: repeating-linear-gradient(45deg, #efe9dd 0 12px, #f6f2e9 12px 24px);
}

.qq-store-card-band .qq-avatar {
    position: absolute;
    left: 16px;
    bottom: -22px;
    width: 44px;
    height: 44px;
    font-size: 1.15rem;
    /* Card, not #fff: the ring fakes a cut-out against the card body, which
       is dark in dark mode — a white ring read as a bright halo there. */
    border: 3px solid var(--qq-card, #fff);
}

.qq-store-card-band img.qq-avatar {
    background: #fff;
}

/* Rating + Featured pills live on the band itself. */
.qq-store-card-rating {
    position: absolute;
    top: 10px;
    right: 10px;
    /* Fixed glass pill over the store-coloured band (which doesn't flip with
       the theme) — the text must stay fixed dark too, or dark mode's light
       text token vanishes on the white glass. */
    background: rgba(255, 255, 255, 0.92);
    color: #23201a;
    font-size: 0.74rem;
    font-weight: 700;
    border-radius: 999px;
    padding: 0.22rem 0.7rem;
    white-space: nowrap;
}

.qq-store-card-rating span {
    color: #6f6757;
    font-weight: 500;
}

.qq-store-card-featured {
    position: absolute;
    top: 10px;
    left: 10px;
    background: var(--qq-brass-tint);
    color: var(--qq-brass-deep);
    font-size: 0.68rem;
    font-weight: 700;
    border-radius: 999px;
    padding: 0.18rem 0.65rem;
    white-space: nowrap;
}

.qq-store-card-body {
    padding: 1.9rem 1rem 1rem;
}

.qq-store-card-body .name {
    font-weight: 700;
    font-size: 1rem;
}

.qq-store-card-body .meta {
    font-size: 0.85rem;
    color: var(--qq-text-muted);
    margin-top: 2px;
}

/* --- Dark seller strip -------------------------------------------------------- */
.qq-seller-strip {
    background: var(--qq-ink);
    color: var(--qq-paper);
    border-radius: 22px;
    padding: 2.75rem 2.5rem;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 1.5rem;
    margin: 3rem 0;
}

.qq-seller-strip h2 {
    margin-bottom: 0.5rem;
}

.qq-seller-strip .gold {
    color: var(--qq-gold-bright);
}

.qq-seller-strip p {
    /* The ink-filled strip inverts to a light panel in dark mode; a fixed
       warm grey went light-on-light there. Mixing paper into ink tracks the
       inversion in both themes. */
    color: color-mix(in srgb, var(--qq-paper) 72%, var(--qq-ink));
    max-width: 35rem;
    margin: 0;
    line-height: 1.5;
    font-weight: 400;
}

/* --- Home v3: trust line, floating review, category tiles, spotlight, proof --- */

.qq-trust-line {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    flex-wrap: wrap;
    font-size: 0.83rem;
    color: var(--qq-text-muted);
}

.qq-trust-line strong {
    color: var(--qq-text);
}

.qq-trust-star {
    color: var(--qq-brass);
    font-weight: 700;
}

.qq-trust-avatars {
    display: inline-flex;
}

.qq-trust-avatar {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 2px solid var(--qq-paper);
    color: #fff;
    font-size: 0.66rem;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.qq-trust-avatar + .qq-trust-avatar {
    margin-left: -7px;
}

.qq-hero-visual {
    position: relative;
}

.qq-hero-visual .qq-hero-tile {
    box-shadow: 0 8px 24px rgba(23, 21, 18, 0.08);
}

.qq-hero-visual .qq-hero-tile.tall {
    box-shadow: 0 8px 24px rgba(23, 21, 18, 0.1);
    border-radius: 22px;
}

.qq-float-review {
    position: absolute;
    left: -28px;
    bottom: 60px;
    width: 250px;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 16px;
    padding: 0.85rem 1rem;
    box-shadow: 0 12px 30px rgba(23, 21, 18, 0.16);
}

.qq-float-review-stars {
    color: var(--qq-brass);
    font-size: 0.75rem;
    letter-spacing: 2px;
}

.qq-float-review-quote {
    font-size: 0.79rem;
    color: var(--qq-text-body);
    line-height: 1.5;
    margin-top: 0.3rem;
}

.qq-float-review-by {
    font-size: 0.72rem;
    color: var(--qq-text-faint);
    margin-top: 0.4rem;
}

/* Category icon tiles (the chips row grows up) */
.qq-cat-tile {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 14px;
    padding: 0.65rem 1.2rem;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--qq-text-body);
    text-decoration: none;
    white-space: nowrap;
    transition: box-shadow 140ms ease, border-color 140ms ease;
}

.qq-cat-tile:hover {
    border-color: var(--qq-text-faint);
    box-shadow: 0 2px 10px rgba(23, 21, 18, 0.06);
    color: var(--qq-text);
}

.qq-cat-tile.active {
    background: var(--qq-ink);
    border-color: var(--qq-ink);
    color: var(--qq-paper);
    font-weight: 600;
}

.qq-cat-see-all {
    margin-left: auto;
    white-space: nowrap;
}

/* Featured spotlight (first boosted store) */
.qq-spotlight {
    display: grid;
    grid-template-columns: 5fr 7fr;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 22px;
    overflow: hidden;
    box-shadow: 0 4px 18px rgba(23, 21, 18, 0.06);
    margin: 2rem 0 0.5rem;
}

.qq-spot-media {
    position: relative;
    min-height: 280px;
    display: block;
    background-size: cover;
    background-position: center;
}

.qq-spot-pill {
    position: absolute;
    top: 16px;
    left: 16px;
    background: var(--qq-brass-tint);
    color: var(--qq-brass-deep);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.3rem 0.85rem;
    border-radius: 999px;
}

.qq-spot-body {
    padding: 1.9rem 2.25rem;
    display: flex;
    flex-direction: column;
}

.qq-spot-head {
    display: flex;
    align-items: center;
    gap: 0.9rem;
}

.qq-spot-avatar {
    width: 54px;
    height: 54px;
    border-radius: 50%;
    color: #fff;
    font-weight: 700;
    font-size: 1.3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
}

.qq-spot-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.qq-spot-name-row {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    flex-wrap: wrap;
}

.qq-spot-name {
    font-weight: 700;
    font-size: 1.3rem;
    letter-spacing: -0.02em;
}

.qq-spot-verified {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    color: var(--qq-ok-fg);
    font-size: 0.75rem;
    font-weight: 600;
}

.qq-spot-verified .tick {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--qq-ok-bg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.62rem;
}

.qq-spot-meta {
    font-size: 0.82rem;
    color: var(--qq-text-muted);
    margin-top: 0.15rem;
}

.qq-spot-meta .star {
    color: var(--qq-brass);
    font-weight: 700;
}

.qq-spot-desc {
    font-size: 0.9rem;
    color: var(--qq-text-body);
    line-height: 1.6;
    max-width: 33rem;
    margin: 0.85rem 0 0;
}

.qq-spot-prods {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 1.1rem;
}

.qq-spot-prod {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: var(--qq-paper);
    border: 1px solid var(--qq-border-soft);
    border-radius: 14px;
    padding: 0.55rem 0.9rem 0.55rem 0.55rem;
}

.qq-spot-prod img,
.qq-spot-prod-swatch {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    object-fit: cover;
    display: block;
    flex-shrink: 0;
}

.qq-spot-prod-text {
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1.35;
}

.qq-spot-prod-text .price {
    color: var(--qq-brass-deep);
    font-weight: 700;
}

.qq-spot-cta-row {
    margin-top: auto;
    padding-top: 1.25rem;
}

/* Social proof band */
.qq-proof {
    display: grid;
    /* Stats, then however many quotes there actually are. This was
       "280px 1fr 1fr", which reserved a column for a second quote whether one
       existed or not — and the number of quotable reviews changes on its own as
       stores come and go, so the section rendered with a wide empty gap on the
       right the moment it dropped to one. auto-fit collapses the track that has
       nothing in it. */
    grid-template-columns: 280px repeat(auto-fit, minmax(18rem, 1fr));
    gap: 1.25rem;
    align-items: stretch;
    margin: 2.5rem 0;
}

.qq-proof-stats,
.qq-proof-quote {
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 18px;
    padding: 1.5rem;
}

.qq-proof-stats {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.9rem;
}

.qq-proof-stats .num {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.03em;
}

.qq-proof-stats .num.brass {
    color: var(--qq-brass);
}

.qq-proof-stats .label {
    font-size: 0.78rem;
    color: var(--qq-text-muted);
}

.qq-proof-quote .stars {
    color: var(--qq-brass);
    font-size: 0.8rem;
    letter-spacing: 2px;
}

.qq-proof-quote .quote {
    font-size: 0.9rem;
    color: var(--qq-text-body);
    line-height: 1.6;
    margin-top: 0.5rem;
}

.qq-proof-quote .by {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin-top: 0.9rem;
    font-size: 0.78rem;
    color: var(--qq-text-muted);
}

.qq-proof-quote .by strong {
    color: var(--qq-text);
}

.qq-proof-quote .avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    color: #fff;
    font-weight: 700;
    font-size: 0.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* Seller band v3: grid + decorative mini storefront */
.qq-seller-strip-v3 {
    display: grid;
    grid-template-columns: 7fr 5fr;
    gap: 3rem;
    align-items: center;
    padding: 3rem 3.25rem;
}

.qq-seller-microlabel {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--qq-gold-bright);
    margin-bottom: 0.6rem;
}

.qq-seller-cta-row {
    display: flex;
    align-items: center;
    gap: 1.1rem;
    flex-wrap: wrap;
    margin-top: 1.4rem;
}

.qq-seller-microcopy {
    font-size: 0.82rem;
    color: color-mix(in srgb, var(--qq-paper) 72%, var(--qq-ink));
}

.qq-mini-store {
    background: #fbf8f2;
    border-radius: 16px;
    overflow: hidden;
    color: #23201a;
    box-shadow: 0 20px 44px rgba(0, 0, 0, 0.4);
    transform: rotate(1.5deg);
    max-width: 21rem;
    justify-self: end;
}

.qq-mini-store-band {
    height: 56px;
    background: linear-gradient(160deg, #8e4d68, #6f3a51);
}

.qq-mini-store-body {
    padding: 0 1rem 0.9rem;
}

.qq-mini-store-id {
    display: flex;
    align-items: flex-end;
    gap: 0.6rem;
    margin-top: -18px;
}

.qq-mini-store-avatar {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: #8e4d68;
    color: #fff;
    font-weight: 700;
    font-size: 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 3px solid #fbf8f2;
    flex-shrink: 0;
}

.qq-mini-store-name {
    font-weight: 700;
    font-size: 0.9rem;
    padding-bottom: 0.25rem;
}

.qq-mini-store-chips {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.5rem;
}

.qq-mini-chip {
    background: #fff;
    border: 1px solid #e0d9ca;
    border-radius: 999px;
    padding: 0.25rem 0.65rem;
    font-size: 0.66rem;
}

.qq-mini-chip .star {
    color: var(--qq-brass);
    font-weight: 700;
}

.qq-mini-chip-cta {
    background: #8e4d68;
    border-color: #8e4d68;
    color: #fff;
    font-weight: 700;
}

.qq-mini-store-cards {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.6rem;
}

.qq-mini-card {
    flex: 1;
    background: #fff;
    border: 1px solid #efe9db;
    border-radius: 10px;
    padding: 0.5rem 0.6rem;
    font-size: 0.68rem;
    line-height: 1.4;
}

@media (max-width: 992px) {
    .qq-spotlight {
        grid-template-columns: 1fr;
    }

    .qq-spot-media {
        min-height: 96px;
    }

    .qq-proof {
        grid-template-columns: 1fr;
    }

    .qq-proof-quote:nth-of-type(3) {
        display: none;
    }

    .qq-seller-strip-v3 {
        grid-template-columns: 1fr;
        padding: 2.25rem 1.75rem;
    }
}

/* --- Seller storefront v3 (driven by per-store CSS variables) --------------
   The page reads like a floating card: identity card overlapping a taller
   cover, hairline stat row, segmented tabs, dark scroll mini-header. All
   colors resolve from the seller's theme vars (--sf-primary/--sf-accent/
   --sf-bg/--sf-text) plus the derived surface tones below — nothing about a
   specific store is hardcoded. */
/* The card's own clamp below is not enough on its own: MainLayout wraps every
   page in Bootstrap's .container, which caps the storefront at 1296 before the
   card's max-width is ever consulted. Widened only when the container is
   actually hosting a storefront, so Explore, Home and every other public page
   keep their column exactly as it is. */
article.content.container:has(.sf-page) {
    max-width: 1584px; /* --sf-col ceiling + the container's own 2x12px padding */
}

.sf-page {
    /* Derived surface tones (README "design tokens"): light values here,
       dark-tone overrides on .sf-dark. */
    --sf-card: #fff;
    --sf-border: #e2dccd;
    --sf-hair: #eee7da;
    --sf-soft: #f1ece1;
    --sf-muted: #6f685c;
    --sf-faint: #a39a88;
    --sf-body: #4f483d;
    --sf-seg: #eeeae2;
    --sf-glass: rgba(251, 248, 242, 0.92);
    background-color: var(--sf-bg);
    color: var(--sf-text);
    /* The card grows into wide screens instead of leaving dead gutters beside
       a folded tab bar (owner request 2026-08-24). 94vw keeps a visible margin
       so it still reads as a card; 1560 is the ceiling so lines of text and
       the product grid do not sprawl; below ~1255px this evaluates to the old
       1180 and nothing changes. --sf-col is shared with the scroll mini-header
       so the two widths cannot drift apart. */
    --sf-col: clamp(1180px, 94vw, 1560px);
    max-width: var(--sf-col);
    margin: 0 auto;
    border-radius: 26px;
    box-shadow: 0 26px 60px rgba(23, 21, 18, 0.10);
    /* NO overflow:hidden — the add-to-cart popover must escape the card. */
}

.sf-dark {
    --sf-card: #221e1a;
    --sf-border: #3a342c;
    --sf-hair: #332e27;
    --sf-soft: #2a251f;
    --sf-muted: #b4ab9c;
    --sf-faint: #857c6d;
    --sf-body: #ded6c8;
    --sf-seg: #2a251f;
    --sf-glass: rgba(24, 21, 18, 0.9);
}

@keyframes sfUp {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
}

@keyframes sfPanel {
    from { opacity: 0; transform: translateY(-6px) scale(0.99); }
    to { opacity: 1; transform: none; }
}

@keyframes sfPulse {
    0% { box-shadow: 0 0 0 0 rgba(31, 122, 77, 0.5); }
    70% { box-shadow: 0 0 0 7px rgba(31, 122, 77, 0); }
    100% { box-shadow: 0 0 0 0 rgba(31, 122, 77, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .sf-page * {
        animation: none !important;
        transition: none !important;
    }
}

/* Cover: taller band, two-ended scrim so the glass pills stay legible on
   bright photos. Clips its own top corners — the page wrapper must not. */
.sf-cover {
    height: 400px;
    position: relative;
    background: color-mix(in srgb, var(--sf-primary) 30%, #e9e0d0);
    border-radius: 26px 26px 0 0;
    overflow: hidden;
}

.sf-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.sf-cover::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(23,21,18,.28) 0%, rgba(23,21,18,0) 30%, rgba(23,21,18,.52) 100%);
    pointer-events: none;
}

.sf-cover-actions {
    position: absolute;
    top: 18px;
    right: 18px;
    display: flex;
    gap: 9px;
    z-index: 2;
}

.sf-cover-actions form {
    margin: 0;
}

.sf-cover-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: rgba(251, 248, 242, 0.92);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border: 1px solid rgba(23, 21, 18, 0.06);
    border-radius: 999px;
    padding: 10px 18px;
    font-weight: 600;
    font-size: 0.845rem;
    color: #23201a;
    cursor: pointer;
    text-decoration: none;
    line-height: 1;
}

.sf-cover-pill:hover {
    background: rgba(251, 248, 242, 1);
    color: #23201a;
}

.sf-cover-pill.on {
    color: #c04f43;
}

/* Identity card: floats over the cover, holds name/meta/description/actions,
   the hours disclosure, and the hairline stat row. */
.sf-identity {
    position: relative;
    z-index: 2;
    margin-top: -72px;
    background: var(--sf-card);
    border: 1px solid var(--sf-border);
    /* Identity sits a step softer than the cards (spec 039). */
    border-radius: calc(var(--sf-r-card, 18px) + 6px);
    box-shadow: 0 18px 44px rgba(23, 21, 18, 0.12);
    padding: 22px 26px 0;
}

.sf-identity-top {
    display: flex;
    align-items: flex-start;
    gap: 1.35rem;
    flex-wrap: wrap;
}

.sf-identity-main {
    flex: 1 1 20rem;
    min-width: 0;
}

.sf-logo {
    width: 92px;
    height: 92px;
    object-fit: cover;
    border-radius: 22px;
    background: var(--sf-primary);
    color: var(--sf-on-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 2.375rem;
    flex-shrink: 0;
    box-shadow: 0 8px 22px rgba(23, 21, 18, 0.16);
}

.sf-store-name {
    font-size: 2.375rem;
    font-weight: 700;
    letter-spacing: -0.04em;
    line-height: 1.05;
    margin: 0;
}

.sf-verified {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: #e5f2ea;
    color: #1f7a4d;
    font-size: 0.75rem;
    font-weight: 700;
    padding: 5px 11px;
    border-radius: 999px;
}

.sf-meta-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 0.55rem;
}

.sf-badge {
    display: inline-block;
    padding: 5px 12px;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    background: var(--sf-primary);
    color: var(--sf-on-primary);
}

.sf-open-status {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.845rem;
    font-weight: 600;
    color: var(--sf-muted);
}

.sf-open-status.open {
    color: #1f7a4d;
}

.sf-open-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

.sf-open-status.open .sf-open-dot {
    animation: sfPulse 2.4s ease-out infinite;
}

.sf-store-desc {
    font-size: 0.9375rem;
    line-height: 1.55;
    color: var(--sf-muted);
    margin: 0.7rem 0 0;
    max-width: 46rem;
    text-wrap: pretty;
}

.sf-header-actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 9px;
    margin-left: auto;
}

/* Hours disclosure: summary is the "See all hours" text button in the meta
   row; the open panel is an inset card. <details> keeps it working no-JS. */
.sf-hours {
    margin-top: 0.9rem;
}

.sf-hours-summary {
    cursor: pointer;
    display: inline-block;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--sf-muted);
    text-decoration: underline;
    text-underline-offset: 3px;
    list-style: none;
}

.sf-hours-summary::-webkit-details-marker {
    display: none;
}

.sf-hours .when-open { display: none; }
.sf-hours[open] .when-open { display: inline; }
.sf-hours[open] .when-closed { display: none; }

.sf-hours-panel {
    margin-top: 0.8rem;
    background: var(--sf-soft);
    border: 1px solid var(--sf-border);
    border-radius: 16px;
    padding: 14px 18px;
    animation: sfPanel 0.2s ease;
}

.sf-hours-label {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 0.656rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--sf-faint);
    margin-bottom: 0.4rem;
}

.sf-hours-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 0 1.6rem;
    font-size: 0.845rem;
}

.sf-hours-line {
    display: flex;
    justify-content: space-between;
    gap: 1.25rem;
    padding: 5px 0;
    border-bottom: 1px solid var(--sf-hair);
    color: var(--sf-body);
}

.sf-hours-line .closed {
    color: var(--sf-faint);
}

/* Stat row: hairline-separated facts replacing the chip soup. */
.sf-stats {
    display: flex;
    flex-wrap: wrap;
    border-top: 1px solid var(--sf-hair);
    margin-top: 1.1rem;
}

.sf-stat {
    flex: 1 1 190px;
    padding: 14px 20px 15px 0;
    min-width: 0;
}

.sf-stat-label {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 0.656rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--sf-faint);
    margin-bottom: 3px;
}

.sf-stat-value {
    font-size: 0.906rem;
    font-weight: 600;
    color: var(--sf-body);
}

a.sf-stat {
    text-decoration: none;
}

.sf-stat-rating .sf-stat-value {
    color: var(--sf-accent);
}

/* Legacy chip (kept: Branding preview + inline uses). */
.sf-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    background: var(--sf-soft);
    border: 1px solid var(--sf-border);
    border-radius: 999px;
    padding: 0.3rem 0.75rem;
    font-size: 0.8rem;
    color: var(--sf-body);
    white-space: nowrap;
}

@media (max-width: 640px) {
    .sf-chip {
        white-space: normal;
    }
}

/* Sticky tabbar: segmented control (left) + search/sort pills (right). */
/* Sticks just below the app's 58px sticky navbar; when the mini-header shows
   it covers that same strip, so one constant top works for both states. */
.sf-tabbar {
    position: sticky;
    top: 58px;
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 1rem;
    /* Wrap when the row runs out of room, rather than crushing the tabs.
       Everything here is nowrap, so before this the only give in the row was
       the tab pill's hidden horizontal scroll — in French, whose labels run
       long, "Cartes-cadeaux" clipped mid-word and Avis vanished entirely, with
       no scrollbar to say it was still there. Wrapped, the search and filters
       drop to a second line and every tab keeps its name. */
    flex-wrap: wrap;
    row-gap: 10px;
    padding: 12px 26px;
    margin-top: 1.25rem;
    background: var(--sf-glass);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--sf-border);
}

.sf-tabs {
    display: flex;
    gap: 4px;
    background: var(--sf-seg);
    border-radius: 999px;
    padding: 4px;
    /* Kept as the phone fallback: on a narrow screen the pill alone is wider
       than the line, shrinks to it, and scrolls. On desktop the wrap above
       means it never has to. */
    overflow-x: auto;
    scrollbar-width: none;
    flex: 0 1 auto;
    max-width: 100%;
}

.sf-tabs::-webkit-scrollbar {
    display: none;
}

.sf-tabs a {
    padding: 9px 18px;
    font-weight: 600;
    font-size: 0.845rem;
    white-space: nowrap;
    color: var(--sf-muted);
    text-decoration: none;
    border-radius: 999px;
    line-height: 1.2;
}

.sf-tabs a:hover {
    color: var(--sf-text);
    text-decoration: none;
}

.sf-tabs a.active {
    /* Subtle accent-usage keeps today's tone-matched ink; bold fills with
       the accent. Resolved per-theme in StorePage.ThemeStyle (spec 039). */
    background: var(--sf-tab-bg, #171512);
    color: var(--sf-tab-fg, #faf8f4);
    box-shadow: 0 2px 8px rgba(23, 21, 18, 0.18);
}

.sf-dark .sf-tabs a.active {
    background: #faf8f4;
    color: #171512;
}

.sf-tabs .count {
    font-size: 0.75rem;
    font-weight: 500;
    opacity: 0.55;
    margin-left: 2px;
}

.sf-tabbar .sf-search {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 1 auto;
    min-width: 0;
    margin-left: auto;
    position: relative;
    flex-wrap: nowrap;
}

.sf-tabbar .sf-search input {
    width: 265px;
    max-width: 100%;
    /* The input is the flexible one: it gives way so the selects never
       truncate their labels ("All categ..."). */
    flex: 0 1 265px;
    min-width: 110px;
    border: 1px solid var(--sf-border);
    background: var(--sf-card);
    color: var(--sf-text);
    border-radius: 13px;
    padding: 0.5rem 0.9rem 0.5rem 2.3rem;
    font: inherit;
    font-size: 0.875rem;
}

.sf-tabbar .sf-search input:focus {
    outline: 2px solid var(--sf-accent);
    outline-offset: 1px;
}

.sf-tabbar .sf-search-icon {
    position: absolute;
    left: 0.8rem;
    top: 50%;
    transform: translateY(-50%);
    color: #a39a88;
    opacity: 1;
    pointer-events: none;
    font-size: 1rem;
}

.sf-filter-select {
    border: 1px solid var(--sf-border);
    background-color: var(--sf-card);
    color: var(--sf-text);
    border-radius: 13px;
    padding: 0.5rem 2rem 0.5rem 0.9rem;
    font: inherit;
    /* Never squeezed into "All categ..." - the search input shrinks instead. */
    flex-shrink: 0;
    font-size: 0.875rem;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23a39a88' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 13px center;
}

.sf-anchor {
    scroll-margin-top: 120px;
}

/* Enter submits the search; the button stays for no-JS but is visually hidden. */
.sf-search-submit {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.sf-section-title {
    font-size: 1.4375rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    margin: 0 0 0.9rem;
}

.sf-section-count {
    font-family: "Space Mono", ui-monospace, monospace;
    font-weight: 400;
    font-size: 0.75rem;
    color: var(--sf-faint);
    margin-left: 0.45rem;
}

/* Product grid: CSS grid, not Bootstrap cols. */
.sf-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
    gap: var(--sf-gap, 20px);
    margin-bottom: 2.25rem;
}

.sf-grid-gallery {
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.sf-product-card {
    position: relative;
    border: 1px solid var(--sf-border);
    border-radius: var(--sf-r-card, 18px);
    background: var(--sf-card);
    height: 100%;
    display: flex;
    flex-direction: column;
    box-shadow: 0 2px 10px rgba(23, 21, 18, 0.04);
    transition: box-shadow 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
    /* No overflow:hidden — the options popover escapes the card. */
}

.sf-product-card:hover {
    box-shadow: 0 16px 34px rgba(23, 21, 18, 0.10);
    transform: translateY(-3px);
    border-color: #d9cfbc;
}

/* While a chooser is open the card must paint above its grid neighbours, and
   the hover transform would trap the popover in a stacking context. */
.sf-product-card:has(.sf-chooser[open]) {
    z-index: 50;
    transform: none;
}

.sf-product-media {
    position: relative;
    border-radius: 18px 18px 0 0;
    overflow: hidden;
}

.sf-product-img {
    width: 100%;
    height: 168px;
    object-fit: cover;
    background: color-mix(in srgb, var(--sf-text) 8%, var(--sf-bg));
    display: block;
}

.sf-grid-gallery .sf-product-img,
.sf-product-media-tall .sf-product-img {
    height: 210px;
}

.sf-price-tag {
    position: absolute;
    left: 11px;
    bottom: 11px;
    background: rgba(23, 21, 18, 0.84);
    color: #fff;
    font-weight: 700;
    font-size: 0.8125rem;
    padding: 6px 12px;
    border-radius: 999px;
    pointer-events: none;
}

.sf-price {
    font-weight: 700;
    color: var(--sf-accent);
}

.sf-no-photo {
    background: repeating-linear-gradient(45deg, #f4efe4, #f4efe4 12px, #efe9db 12px, #efe9db 24px);
    color: var(--sf-faint);
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 0.656rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.sf-dark .sf-no-photo {
    background: repeating-linear-gradient(45deg, #2b2620, #2b2620 12px, #332e27 12px, #332e27 24px);
}

.sf-photo-count {
    position: absolute;
    right: 10px;
    bottom: 10px;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: rgba(251, 248, 242, 0.92);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: #23201a;
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 0.6875rem;
    padding: 5px 10px;
    border-radius: 999px;
    text-decoration: none;
}

.sf-media-heart-form {
    position: absolute;
    top: 11px;
    right: 11px;
    margin: 0;
}

.sf-media-heart {
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(251, 248, 242, 0.92);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: color-mix(in srgb, var(--sf-text) 55%, transparent);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.sf-media-heart:hover,
.sf-media-heart.on {
    color: #c04f43;
}

.sf-product-desc {
    color: var(--sf-muted);
    font-size: 0.8125rem;
    line-height: 1.5;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: 0.15rem;
}

/* Card footer anchors the chooser popover. */
.sf-card-foot {
    position: relative;
    margin-top: auto;
}

.sf-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--sf-cta, var(--sf-primary));
    color: var(--sf-on-cta, var(--sf-on-primary));
    border: none;
    border-radius: var(--sf-r-btn, 999px);
    font-family: inherit;
    font-size: 0.845rem;
    font-weight: 700;
    padding: 0.55rem 1.4rem;
    cursor: pointer;
    text-decoration: none;
}

.sf-btn:hover {
    filter: brightness(0.92);
    color: var(--sf-on-primary);
    text-decoration: none;
}

.sf-btn-outline {
    background: transparent;
    color: var(--sf-primary);
    border: 1.5px solid var(--sf-border);
    font-weight: 600;
}

.sf-btn-outline:hover {
    background: color-mix(in srgb, var(--sf-primary) 10%, transparent);
    color: var(--sf-primary);
    filter: none;
}

.sf-btn-block {
    width: 100%;
}

.sf-cta {
    box-shadow: 0 8px 22px color-mix(in srgb, var(--sf-primary) 28%, transparent);
    font-size: 0.906rem;
    padding: 14px 26px;
}

/* Favourite hearts on service rows. */
.sf-fav-heart {
    background: none;
    border: none;
    padding: 0.1rem 0.3rem;
    font-size: 1.06rem;
    line-height: 1;
    cursor: pointer;
    color: color-mix(in srgb, var(--sf-text) 55%, transparent);
}

.sf-fav-heart:hover,
.sf-fav-heart.on {
    color: #c04f43;
}

/* Options chooser: summary is the Add pill; the panel hangs under the footer
   at the card's full width. */
.sf-chooser {
    position: static;
}

.sf-chooser > summary {
    list-style: none;
}

.sf-chooser > summary::-webkit-details-marker {
    display: none;
}

.sf-chooser[open] > summary.sf-btn {
    background: var(--sf-soft);
    color: var(--sf-text);
    filter: none;
}

.sf-chooser-scrim {
    display: none;
}

.sf-chooser[open] .sf-chooser-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 1;
    background: rgba(23, 21, 18, 0.14);
}

.sf-chooser-panel {
    position: absolute;
    left: -15px;
    right: -15px;
    top: calc(100% + 9px);
    z-index: 2;
    background: var(--sf-card);
    border: 1.5px solid var(--sf-primary);
    border-radius: 18px;
    box-shadow: 0 18px 40px rgba(23, 21, 18, 0.18);
    padding: 16px;
    max-height: min(58vh, 430px);
    overflow-y: auto;
    animation: sfPanel 0.18s ease;
}

.sf-chooser-group {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 0.656rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--sf-faint);
    margin: 0.7rem 0 0.3rem;
}

.sf-chooser-group:first-of-type {
    margin-top: 0;
}

.sf-choice {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.845rem;
    padding: 7px 0;
    cursor: pointer;
    color: var(--sf-body);
}

.sf-choice input[type="radio"],
.sf-choice input[type="checkbox"] {
    width: 17px;
    height: 17px;
    accent-color: var(--sf-primary);
    flex-shrink: 0;
}

.sf-choice-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere; /* long, unbroken option names wrap instead of overflowing */
}

.sf-choice input:checked ~ .sf-choice-name {
    font-weight: 600;
    color: var(--sf-text);
}

.sf-choice-price {
    font-size: 0.8125rem;
    color: var(--sf-muted);
    white-space: nowrap;
}

.sf-chooser-cancel {
    display: block;
    width: 100%;
    background: none;
    border: none;
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--sf-muted);
    padding: 0.55rem 0 0.1rem;
    cursor: pointer;
}

/* The add-to-cart button stays visible while long option lists scroll. */
.sf-chooser-panel .sf-btn-block {
    position: sticky;
    bottom: 0;
}

.sf-chooser-panel button[disabled] {
    opacity: 0.55;
    cursor: not-allowed;
}

.sf-owner-note {
    display: inline-block;
    font-size: 0.8rem;
    color: var(--sf-faint);
    padding: 0.55rem 0;
}

.sf-owner-panel-note {
    font-size: 0.78rem;
    color: var(--sf-faint);
    margin-top: 0.4rem;
    text-align: center;
}

/* Phones: the popover becomes a bottom sheet (same markup, swapped shell). */
@media (max-width: 767px) {
    .sf-chooser-panel {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        top: auto;
        z-index: 70;
        border-radius: 20px 20px 0 0;
        border: none;
        border-top: 1.5px solid var(--sf-primary);
        box-shadow: 0 -14px 34px rgba(23, 21, 18, 0.20);
        padding: 14px 16px 16px;
        max-height: 74vh;
        animation: sfUp 0.2s ease;
    }
}

/* Services: one hairline-divided card of rows with real photos. */
.sf-service-card {
    background: var(--sf-card);
    border: 1px solid var(--sf-border);
    border-radius: var(--sf-r-card, 20px);
    max-width: 900px;
    overflow: hidden;
    margin-bottom: 2.25rem;
}

.sf-service-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 20px;
    transition: background 0.15s ease;
}

.sf-service-row:hover {
    background: var(--sf-soft);
}

.sf-service-row + .sf-service-row {
    border-top: 1px solid var(--sf-hair);
}

.sf-service-photo {
    position: relative;
    width: 104px;
    height: 78px;
    border-radius: 14px;
    overflow: hidden;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.sf-service-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.sf-service-photo .sf-photo-count {
    right: 5px;
    bottom: 5px;
    font-size: 0.625rem;
    padding: 3px 7px;
}

/* Legacy icon tile (Branding preview fallback). */
.sf-service-icon {
    width: 46px;
    height: 46px;
    border-radius: 14px;
    background: color-mix(in srgb, var(--sf-primary) 12%, var(--sf-bg));
    color: var(--sf-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
    flex-shrink: 0;
}

.sf-duration {
    background: var(--sf-soft);
    color: var(--sf-body);
    font-size: 0.78rem;
    font-weight: 600;
    padding: 6px 12px;
    border-radius: 999px;
    white-space: nowrap;
}

/* Gift cards: ticket faces with a perforated edge. */
.sf-giftcards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 20px;
    max-width: 900px;
    margin-bottom: 2.25rem;
}

.sf-giftcard {
    display: flex;
    flex-direction: column;
    border-radius: 20px;
    border: 1px solid var(--sf-border);
    background: var(--sf-card);
    overflow: hidden;
}

.sf-giftcard-top {
    position: relative;
    background: linear-gradient(135deg, var(--sf-primary), color-mix(in srgb, var(--sf-primary) 55%, #171512));
    color: #fff;
    padding: 20px 22px 22px;
}

.sf-giftcard-top .qq-microlabel,
.sf-giftcard-kind {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 0.656rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    opacity: 0.7;
    color: inherit;
}

.sf-giftcard-face {
    font-size: 2.125rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1.1;
    margin-top: 0.35rem;
}

.sf-giftcard-name {
    font-weight: 600;
    font-size: 0.906rem;
    margin-top: 0.15rem;
}

/* Perforation: punched dots along the ticket's tear line. */
.sf-giftcard-top::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -7px;
    height: 14px;
    background-image: radial-gradient(circle at 7px 7px, var(--sf-card) 6px, transparent 6.5px);
    background-size: 18px 14px;
}

.sf-giftcard-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    padding: 16px 22px 18px;
}

.sf-giftcard-desc {
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--sf-muted);
    margin: 0 0 0.6rem;
}

.sf-giftcard-buy {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: auto;
}

.sf-giftcard-price {
    font-weight: 700;
    font-size: 0.906rem;
}

.sf-giftcard-buy form {
    margin: 0;
}

/* Reviews: sticky summary/composer column + hairline list. */
.sf-reviews {
    display: grid;
    grid-template-columns: 340px 1fr;
    gap: 28px;
    align-items: start;
}

.sf-reviews-side {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    position: sticky;
    top: 150px;
}

.sf-review-summary,
.sf-composer {
    border: 1px solid var(--sf-border);
    background: var(--sf-card);
    border-radius: 20px;
    padding: 22px;
}

.sf-review-avg {
    font-size: 2.875rem;
    font-weight: 700;
    letter-spacing: -0.04em;
    line-height: 1;
}

.sf-review-avg-stars {
    font-size: 0.9375rem;
    letter-spacing: 2px;
    margin: 0.25rem 0;
}

.sf-review-avg-count {
    font-size: 0.78rem;
    color: var(--sf-muted);
    margin-bottom: 0.9rem;
}

.sf-dist-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.35rem;
}

.sf-dist-star {
    width: 26px;
    font-size: 0.75rem;
    color: var(--sf-muted);
    white-space: nowrap;
}

.sf-dist-track {
    flex: 1;
    height: 7px;
    border-radius: 99px;
    background: var(--sf-soft);
    overflow: hidden;
}

.sf-dist-fill {
    display: block;
    height: 100%;
    background: var(--sf-accent);
    border-radius: 99px;
}

.sf-dist-n {
    width: 26px;
    text-align: right;
    font-size: 0.75rem;
    color: var(--sf-faint);
}

.sf-composer-hint {
    font-size: 0.78rem;
    color: var(--sf-muted);
    margin-bottom: 0.6rem;
}

.sf-composer-input {
    width: 100%;
    border: 1px solid var(--sf-border);
    background: var(--sf-soft);
    color: var(--sf-text);
    border-radius: 12px;
    padding: 11px 13px;
    font: inherit;
    resize: vertical;
}

.sf-reviews-list {
    display: flex;
    flex-direction: column;
}

.sf-review {
    display: flex;
    gap: 14px;
    padding: 18px 2px;
    border-bottom: 1px solid var(--sf-hair);
    animation: sfUp 0.22s ease;
}

.sf-review-avatar {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-weight: 700;
    font-size: 1rem;
}

.sf-review-date {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 0.72rem;
    color: var(--sf-faint);
}

.sf-review-comment {
    color: var(--sf-body);
    line-height: 1.6;
    font-size: 0.875rem;
    text-wrap: pretty;
}

.sf-show-all {
    align-self: flex-start;
    margin-top: 1rem;
    font-size: 0.845rem;
    padding: 11px 24px;
}

/* Footer strip. */
.sf-footer {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 18px 26px;
    border-top: 1px solid var(--sf-border);
    background: var(--sf-soft);
    border-radius: 0 0 26px 26px;
}

.sf-footer-url {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 0.78rem;
    color: var(--sf-muted);
}

.sf-footer-copy {
    background: var(--sf-card);
    border: 1px solid var(--sf-border);
    color: var(--sf-text);
    padding: 8px 16px;
    font-size: 0.78rem;
}

.sf-footer-powered {
    margin-left: auto;
    font-size: 0.78rem;
    color: var(--sf-faint);
}

.sf-footer-powered .gold {
    color: #d9a94e;
}

/* Scroll mini-header: dark takeover bar once the cover is out of view.
   Progressive enhancement — hidden until JS toggles .show. */
.sf-minihead {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    /* Above the app's sticky navbar (z 1020): the dark bar takes over the
       whole top strip, navbar included. */
    z-index: 1030;
    background: rgba(23, 21, 18, 0.93);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    padding: 11px 24px;
    opacity: 0;
    transform: translateY(-100%);
    transition: opacity 0.22s ease, transform 0.22s ease;
    pointer-events: none;
}

.sf-minihead.show {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.sf-minihead-in {
    /* Tracks the card's width — same token, so they cannot disagree. The
       fallback matters because the mini-header is fixed to the viewport and
       may sit outside .sf-page in the DOM. */
    max-width: var(--sf-col, clamp(1180px, 94vw, 1560px));
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 14px;
}

.sf-minihead-logo {
    width: 32px;
    height: 32px;
    border-radius: 9px;
    object-fit: cover;
    background: var(--sf-primary, #2f5d50);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.9rem;
    flex-shrink: 0;
}

.sf-minihead-name {
    font-size: 0.9375rem;
    font-weight: 700;
    color: #faf8f4;
    white-space: nowrap;
}

.sf-minihead-tabs {
    display: flex;
    gap: 18px;
    overflow-x: auto;
    scrollbar-width: none;
}

.sf-minihead-tabs::-webkit-scrollbar {
    display: none;
}

.sf-minihead-tabs a {
    font-size: 0.845rem;
    font-weight: 600;
    color: rgba(250, 248, 244, 0.6);
    text-decoration: none;
    white-space: nowrap;
}

.sf-minihead-tabs a.active,
.sf-minihead-tabs a:hover {
    color: #faf8f4;
    text-decoration: none;
}

.sf-minihead-status {
    margin-left: auto;
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 0.72rem;
    color: rgba(250, 248, 244, 0.55);
    white-space: nowrap;
}

.sf-minihead-cta {
    font-size: 0.8125rem;
    padding: 9px 18px;
    flex-shrink: 0;
}

/* Dark tone: glass pills flip to a dark, light-bordered treatment. */
.sf-dark .sf-cover-pill,
.sf-dark .sf-photo-count,
.sf-dark .sf-media-heart {
    background: rgba(24, 21, 18, 0.7);
    border: 1px solid rgba(242, 237, 228, 0.2);
    color: #f2ede4;
}

.sf-dark .sf-verified {
    background: rgba(31, 122, 77, 0.22);
    color: #7fc9a2;
}

.sf-dark .sf-open-status.open {
    color: #7fc9a2;
}

@media (max-width: 768px) {
    .sf-cover {
        height: 190px;
    }

    .sf-cover-actions {
        top: 12px;
        right: 12px;
    }

    .sf-cover-pill {
        padding: 8px 13px;
    }

    .sf-cover-pill .label {
        display: none;
    }

    .sf-store-name {
        font-size: 1.3125rem;
    }

    .sf-tabbar {
        padding: 10px 16px;
    }

    .sf-tabbar .sf-search {
        display: none;
    }

    .sf-tabs a {
        font-size: 0.78rem;
        padding: 8px 15px;
    }

    .sf-reviews {
        grid-template-columns: 1fr;
    }

    .sf-reviews-side {
        position: static;
    }

    .sf-minihead-tabs,
    .sf-minihead-status {
        display: none;
    }
}

@media (max-width: 640px) {
    .sf-identity {
        margin-top: -46px;
        border-radius: 20px;
        padding: 16px 16px 0;
    }

    .sf-identity-top {
        gap: 0.8rem;
    }

    .sf-logo {
        width: 58px;
        height: 58px;
        font-size: 1.4rem;
        border-radius: 16px;
    }

    .sf-store-desc {
        font-size: 0.875rem;
        margin-top: 0.5rem;
    }

    .sf-header-actions {
        flex-direction: row;
        width: 100%;
        margin-left: 0;
        margin-top: 0.6rem;
        gap: 0.5rem;
    }

    .sf-header-actions .sf-btn {
        flex: 1 1 0;
        justify-content: center;
        padding: 0.6rem 0.75rem;
        font-size: 0.8125rem;
    }

    .sf-stat {
        flex: 1 1 45%;
        padding: 10px 12px 11px 0;
    }

    .sf-grid,
    .sf-grid-gallery {
        grid-template-columns: repeat(2, 1fr);
        gap: 12px;
    }

    .sf-product-img,
    .sf-grid-gallery .sf-product-img {
        height: 96px;
    }

    .sf-product-card .fw-bold {
        font-size: 0.8125rem;
    }

    .sf-card-foot .sf-btn {
        font-size: 0.75rem;
        padding: 0.5rem 0.6rem;
    }

    .sf-service-row {
        flex-wrap: wrap;
        gap: 0.6rem 1rem;
        padding: 0.95rem 1rem;
    }

    .sf-service-photo {
        width: 72px;
        height: 56px;
        border-radius: 12px;
    }

    .sf-service-photo .sf-photo-count {
        display: none;
    }
}

/* --- Booking ------------------------------------------------------------------ */
.qq-daypick {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: 2rem;
}

.qq-day {
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 14px;
    padding: 0.7rem 0;
    width: 76px;
    text-align: center;
    cursor: pointer;
    font-family: inherit;
    color: var(--qq-text);
}

.qq-day .dow { font-size: 0.75rem; color: var(--qq-text-faint); }
.qq-day .num { font-size: 1.2rem; font-weight: 700; line-height: 1.2; }
.qq-day .mon { font-size: 0.72rem; color: var(--qq-text-faint); }

.qq-day.active {
    background: var(--qq-ink);
    border-color: var(--qq-ink);
    color: var(--qq-paper);
}

.qq-day.active .dow, .qq-day.active .num, .qq-day.active .mon {
    color: var(--qq-paper);
}

.qq-day.active .dow, .qq-day.active .mon { opacity: 0.7; }

.qq-slots {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
    gap: 0.6rem;
    max-width: 36rem;
}

.qq-slot {
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 12px;
    padding: 0.7rem 0;
    text-align: center;
    font-weight: 600;
    font-size: 0.9rem;
    cursor: pointer;
    font-family: inherit;
    color: var(--qq-text);
}

.qq-slot.active {
    background: var(--qq-ink);
    border-color: var(--qq-ink);
    color: var(--qq-paper);
    font-weight: 700;
}

/* --- Buyer stepper ---------------------------------------------------------------- */
.qq-stepper {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--qq-border);
    border-radius: 999px;
}

.qq-stepper button {
    background: none;
    border: none;
    padding: 0.4rem 0.85rem;
    color: var(--qq-text-muted);
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    font-size: 0.95rem;
}

.qq-stepper button:disabled {
    color: var(--qq-text-faint, #d3cbbc);
}

.qq-stepper .qty {
    padding: 0.4rem 0.35rem;
    font-weight: 700;
    min-width: 1.1rem;
    text-align: center;
}

/* --- Payment method cards ------------------------------------------------------------ */
.qq-paycard {
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 16px;
    padding: 1.1rem 1.25rem;
    display: flex;
    gap: 0.9rem;
    align-items: flex-start;
    position: relative;
    cursor: pointer;
    margin-bottom: 0.75rem;
}

/* .active is server-rendered and correct on the interactive checkout; the guest
   page is static SSR, where it freezes on whatever was posted. Its cards are
   labels wrapping a radio, so :checked follows the click with no script. */
.qq-paycard.active,
.qq-paycard:has(input:checked) {
    border: 2px solid var(--qq-ink);
    padding: calc(1.1rem - 1px) calc(1.25rem - 1px);
}

.qq-paycard .form-check-input {
    margin-top: 0.2rem;
}

.qq-paycard .tag {
    position: absolute;
    right: 1.25rem;
    top: 1.1rem;
}

/* --- Progress track (order detail) ---------------------------------------------------- */
.qq-progress {
    display: flex;
    align-items: center;
    margin-bottom: 0.4rem;
}

.qq-progress .dot {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--qq-mute-bg);
    color: var(--qq-text-faint);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.72rem;
    font-weight: 700;
    flex-shrink: 0;
}

.qq-progress .dot.done {
    background: var(--qq-brass);
    /* Brass flips to light gold in dark mode — the label must flip dark. */
    color: var(--qq-paper, #fff);
}

.qq-progress .bar {
    flex: 1;
    height: 2px;
    background: #e0d8c8;
}

.qq-progress-labels {
    display: flex;
    justify-content: space-between;
    font-size: 0.7rem;
    color: var(--qq-text-faint);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 1.5rem;
}

.qq-progress-labels .done {
    color: var(--qq-brass);
}

/* --- Date block (appointments) --------------------------------------------------------- */
.qq-dateblock {
    width: 64px;
    text-align: center;
    border-radius: 14px;
    padding: 0.6rem 0;
    flex-shrink: 0;
    background: var(--qq-mute-bg);
    color: var(--qq-text-muted);
}

.qq-dateblock.upcoming {
    background: var(--qq-ink);
    color: var(--qq-paper);
}

.qq-dateblock .m { font-size: 0.7rem; font-weight: 700; opacity: 0.75; }
.qq-dateblock .d { font-size: 1.45rem; font-weight: 700; line-height: 1.1; }
.qq-dateblock .w { font-size: 0.7rem; opacity: 0.75; }

/* --- Seller gallery editor (kept, restyled) ----------------------------------------- */
.qq-gallery-tile {
    position: relative;
    width: 96px;
    height: 96px;
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid var(--qq-border);
}

.qq-gallery-tile img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.qq-gallery-cover {
    position: absolute;
    top: 6px;
    left: 6px;
    background: var(--qq-ink);
    color: var(--qq-paper);
    font-size: 0.62rem;
    font-weight: 700;
    padding: 0.12rem 0.5rem;
    border-radius: 999px;
}

.qq-gallery-actions {
    position: absolute;
    bottom: 4px;
    right: 4px;
    display: flex;
    gap: 0.2rem;
}

.qq-gallery-actions .qq-btn-outline {
    padding: 0 0.45rem;
    line-height: 1.5;
    border-radius: 8px;
    font-size: 0.85rem;
}

/* --- Dropzone --------------------------------------------------------------------------- */
.qq-dropzone {
    border: 2px dashed var(--qq-track-off);
    border-radius: 14px;
    padding: 1.2rem;
    text-align: center;
    color: var(--qq-text-faint);
    font-size: 0.86rem;
}

.qq-dropzone input[type=file] {
    width: 100%;
    font-family: inherit;
    font-size: 0.85rem;
    color: var(--qq-text-muted);
}

/* Upload feedback: spinner + per-file progress bar under the dropzone. */
.qq-spinner {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    flex: none;
    border: 2px solid var(--qq-border);
    border-top-color: var(--qq-brass);
    border-radius: 50%;
    animation: qq-spin 0.7s linear infinite;
}

@keyframes qq-spin {
    to { transform: rotate(360deg); }
}

.qq-upload-track {
    height: 5px;
    margin-top: 0.4rem;
    border-radius: 99px;
    background: var(--qq-border-soft);
    overflow: hidden;
}

.qq-upload-fill {
    height: 100%;
    border-radius: 99px;
    background: var(--qq-brass);
    transition: width 200ms ease;
}

/* --- Theme toggle (dark/light) ----------------------------------------------- */
.qq-theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: 1px solid var(--qq-border);
    border-radius: 50%;
    background: var(--qq-card);
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}

.qq-theme-toggle:hover {
    border-color: var(--qq-brass);
}

/* --- Field help tips --------------------------------------------------------- */
/* Info bubble beside a label (HelpTip.razor). CSS-only reveal: hover on
   desktop, focus on keyboard/touch. Ink-on-paper inverts with the theme, so
   the popup is the "opposite" panel in both light and dark. */
.qq-help {
    position: relative;
    display: inline-flex;
    align-items: center;
    margin-left: 0.3rem;
    color: var(--qq-text-faint);
    cursor: help;
    vertical-align: middle;
    outline: none;
}

.qq-help svg {
    width: 14px;
    height: 14px;
}

.qq-help:hover,
.qq-help:focus {
    color: var(--qq-brass);
}

.qq-help-pop {
    position: absolute;
    bottom: calc(100% + 8px);
    /* anchored to the icon's left so it grows rightward — labels usually sit
       near the left edge, where a centered popup would clip offscreen */
    left: -8px;
    display: none;
    width: max-content;
    max-width: min(280px, 78vw);
    padding: 0.55rem 0.75rem;
    border-radius: 10px;
    background: var(--qq-ink);
    color: var(--qq-paper);
    font-size: 0.8rem;
    font-weight: 400;
    line-height: 1.45;
    white-space: normal;
    text-transform: none;
    letter-spacing: normal;
    box-shadow: 0 10px 28px rgba(23, 21, 18, 0.28);
    z-index: 1090;
}

.qq-help-pop-title {
    display: block;
    font-weight: 700;
    margin-bottom: 0.2rem;
}

.qq-help:hover .qq-help-pop,
.qq-help:focus .qq-help-pop,
.qq-help:focus-within .qq-help-pop {
    display: block;
}

/* Flipped variant (set by nav-drawer.js when the popup would clip on the
   right): anchor to the icon's right and grow leftward. */
.qq-help-pop.qq-help-pop-flip {
    left: auto;
    right: -8px;
}

/* --- Language toggle --------------------------------------------------------- */
.qq-lang-toggle {
    font-size: 0.78rem;
    white-space: nowrap;
    color: var(--qq-text-muted);
}

.qq-lang-toggle a {
    text-decoration: none;
    color: var(--qq-text-muted);
    padding: 0 0.15rem;
}

.qq-lang-toggle a.active {
    color: var(--qq-text);
    font-weight: 700;
}

.qq-lang-toggle .sep {
    color: var(--qq-text-faint);
    padding: 0 0.1rem;
}

/* dark chrome variants */
.qq-on-dark .qq-lang-toggle a { color: #9aa4ae; }
.qq-on-dark .qq-lang-toggle a.active { color: #fff; }
.qq-on-dark .qq-lang-toggle .sep { color: #9aa4ae; }

/* --- Image lightbox (unchanged behavior, warmer chrome) ----------------------- */
.qq-lightbox {
    border: none;
    border-radius: 16px;
    padding: 0;
    background: #171512;
    max-width: min(92vw, 1000px);
    overflow: hidden;
}

.qq-lightbox::backdrop {
    background: rgba(15, 13, 10, 0.8);
}

.qq-lightbox img {
    display: block;
    max-width: min(92vw, 1000px);
    max-height: 82vh;
    object-fit: contain;
    margin: 0 auto;
}

/* Mouse users can swipe the gallery too (lightbox.js); the open hand says so.
   Touch devices never see this cursor. */
@media (pointer: fine) {
    .qq-lightbox img {
        cursor: grab;
    }
}

.qq-lightbox-close {
    position: absolute;
    top: 0.35rem;
    right: 0.55rem;
    background: rgba(0, 0, 0, 0.45);
    border: none;
    color: #fff;
    font-size: 1.4rem;
    line-height: 1;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    cursor: pointer;
    z-index: 1;
}

.qq-lightbox-close:hover {
    background: var(--qq-brass);
}

.qq-lightbox-footer {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 0.75rem;
    color: #d8d2c5;
    padding: 0.45rem 0.8rem;
    font-size: 0.85rem;
}

.qq-lightbox-footer:not(:has(span:not(:empty))) {
    display: none;
}

.qq-lightbox-counter {
    color: #9a917f;
    font-variant-numeric: tabular-nums;
}

.qq-lightbox-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0, 0, 0, 0.45);
    border: none;
    color: #fff;
    font-size: 1.3rem;
    line-height: 1;
    padding: 0.55rem 0.65rem;
    border-radius: 999px;
    cursor: pointer;
    z-index: 1;
}

.qq-lightbox-prev { left: 0.5rem; }
.qq-lightbox-next { right: 0.5rem; }

.qq-lightbox-nav:hover {
    background: var(--qq-brass);
}

/* --- Blazor plumbing (unchanged) ---------------------------------------------- */
.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

/* --- Explore (marketplace search) ----------------------------------------------------------- */
.qq-explore-head {
    margin-bottom: 1.1rem;
}

.qq-ex-microlabel {
    font-family: 'Space Mono', ui-monospace, monospace;
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--qq-text-faint);
}

.qq-ex-title {
    font-size: clamp(1.875rem, 4.5vw, 2.75rem);
    font-weight: 700;
    letter-spacing: -0.04em;
    margin: 0.3rem 0 0.25rem;
}

.qq-ex-title .gold {
    color: var(--qq-gold-bright);
}

.qq-ex-subtitle {
    font-size: 0.94rem;
    color: var(--qq-text-muted);
    margin: 0;
}

/* Sticky frosted toolbar: search + filters + sort, segments beneath */
.qq-ex-toolbar {
    position: sticky;
    top: 0;
    z-index: 40;
    /* Frosted glass from the paper token, not a fixed light rgba — the
       toolbar's light text was unreadable on the light glass in dark mode. */
    background: color-mix(in srgb, var(--qq-paper, #faf8f4) 90%, transparent);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    padding: 1rem 0 0.85rem;
    margin-bottom: 0.25rem;
    border-bottom: 1px solid transparent;
    transition: border-color 0.25s ease;
}

.qq-ex-toolbar.scrolled {
    border-bottom-color: var(--qq-border);
}

.qq-ex-toolbar-row {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    flex-wrap: wrap;
}

.qq-ex-toolbar-row + .qq-ex-toolbar-row {
    margin-top: 0.75rem;
}

.qq-ex-seg {
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
}

.qq-ex-seg::-webkit-scrollbar {
    display: none;
}

.qq-ex-key-hint {
    position: absolute;
    right: 0.9rem;
    top: 50%;
    transform: translateY(-50%);
    font-family: 'Space Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    color: var(--qq-text-faint);
    border: 1px solid var(--qq-border);
    border-radius: 6px;
    padding: 0.12rem 0.5rem;
    pointer-events: none;
}

.qq-explore-search:has(.qq-explore-search-clear) .qq-ex-key-hint {
    display: none;
}

/* Sort as a self-labelled select with a custom chevron */
.qq-ex-sort {
    appearance: none;
    -webkit-appearance: none;
    background-color: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 14px;
    padding: 0.65rem 2.3rem 0.65rem 1.1rem;
    font-family: inherit;
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--qq-text);
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%237a7264' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
}

.qq-ex-sort:hover {
    border-color: #c9bfa9;
}

/* the chevron's stroke is baked into the data-URI, so dark mode swaps the
   image rather than a color token */
html[data-theme="dark"] .qq-ex-sort {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23a89f8d' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

.qq-explore-search {
    position: relative;
    flex: 1 1 280px;
    max-width: 44rem;
}

.qq-explore-search .qq-input {
    width: 100%;
    padding: 0.8rem 3rem 0.8rem 2.9rem;
    font-size: 0.96rem;
    border-radius: 14px;
    box-shadow: 0 2px 10px rgba(23, 21, 18, 0.04);
}

.qq-explore-search-icon {
    position: absolute;
    left: 1rem;
    top: 50%;
    transform: translateY(-50%);
    opacity: 0.55;
    pointer-events: none;
}

.qq-explore-search-clear {
    position: absolute;
    right: 0.9rem;
    top: 50%;
    transform: translateY(-50%);
    border: none;
    background: none;
    color: var(--qq-text-faint);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.1rem 0.3rem;
}

.qq-explore-search-clear:hover {
    color: var(--qq-text);
}

/* "Filters" pill with the active-count badge. */
.qq-filter-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 999px;
    padding: 0.65rem 1.35rem;
    font-family: inherit;
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--qq-text);
    cursor: pointer;
    white-space: nowrap;
}

.qq-filter-pill:hover {
    border-color: var(--qq-brass);
}

.qq-filter-pill-count {
    background: var(--qq-brass-tint);
    color: var(--qq-brass-deep);
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 0.05rem 0.5rem;
}

.qq-seg-count {
    color: var(--qq-text-faint);
    font-weight: 500;
}

.qq-sort-label {
    font-size: 0.85rem;
    color: var(--qq-text-muted);
    margin: 0;
}

.qq-sort-select {
    border-radius: 999px;
    padding: 0.5rem 1.1rem;
    font-weight: 600;
    width: auto;
}

/* One ink pill per active filter, each with its own ×. */
.qq-filter-chips {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 0.9rem;
}

.qq-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    background: var(--qq-ink);
    color: var(--qq-paper);
    border-radius: 999px;
    padding: 0.4rem 0.9rem;
    font-size: 0.78rem;
    font-weight: 600;
}

.qq-filter-chip {
    animation: qqFadeUp 0.2s ease;
}

.qq-filter-chip button {
    border: none;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.16);
    color: var(--qq-paper);
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.qq-filter-chip button:hover {
    background: rgba(255, 255, 255, 0.32);
}

.qq-clear-all {
    border: none;
    background: none;
    font-family: inherit;
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--qq-brass);
    cursor: pointer;
}

.qq-explore-filters {
    border-radius: 20px;
    padding: 1.5rem;
    margin-top: 0.9rem;
    box-shadow: 0 12px 34px rgba(23, 21, 18, 0.07);
    animation: qqSlideDown 0.22s ease;
}

.qq-explore-filters .qq-label {
    margin-bottom: 0.25rem;
}

.qq-ex-filter-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 1.25rem 1.4rem;
}

/* Grid items default to min-width:auto, which lets wide controls (date/time
   inputs, the rating pill) blow out of their 215px column. Let everything
   shrink instead. */
.qq-ex-filter-grid > div {
    min-width: 0;
}

.qq-ex-filter-grid .d-flex > .qq-input {
    flex: 1 1 0;
    min-width: 0;
}

/* Date/time inputs carry big intrinsic widths; tighter padding helps them
   fit side by side in one column. */
.qq-ex-filter-grid input[type="date"],
.qq-ex-filter-grid input[type="time"] {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
}

/* The 4-option rating pill can't always fit ("Toutes les notes" in French):
   compact buttons, and scroll inside its own pill as the last resort. */
.qq-ex-filter-grid .qq-seg-sm {
    display: flex;
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
}

.qq-ex-filter-grid .qq-seg-sm::-webkit-scrollbar {
    display: none;
}

.qq-ex-filter-grid .qq-seg-sm button {
    padding: 0.5rem 0.55rem;
    font-size: 0.76rem;
}

.qq-ex-flabel {
    display: block;
    font-family: 'Space Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--qq-text-muted);
    margin-bottom: 0.35rem;
}

.qq-explore-filters .qq-input,
.qq-explore-filters .qq-select {
    background: var(--qq-paper);
}

.qq-explore-filters .qq-input:focus,
.qq-explore-filters .qq-select:focus {
    border-color: var(--qq-brass);
    box-shadow: 0 0 0 3px rgba(154, 107, 30, 0.12);
    outline: none;
}

.qq-ex-filter-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    border-top: 1px solid var(--qq-border-soft);
    margin-top: 1.25rem;
    padding-top: 1rem;
}

/* Loading skeletons with shimmer */
.qq-ex-skeletons {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
    gap: 1rem;
    margin-top: 1rem;
}

.qq-ex-skel {
    background: var(--qq-card);
    border: 1px solid var(--qq-border-soft);
    border-radius: 16px;
    overflow: hidden;
    padding-bottom: 1rem;
}

.qq-ex-skel-band,
.qq-ex-skel-bar {
    background: linear-gradient(90deg, #efeadf 25%, #f7f3ea 50%, #efeadf 75%);
    background-size: 200% 100%;
    animation: qqShimmer 1.2s linear infinite;
}

.qq-ex-skel-band {
    height: 110px;
}

.qq-ex-skel-bar {
    height: 12px;
    border-radius: 6px;
    margin: 0.85rem 1rem 0;
}

/* Stores grid/list toggle + list view */
.qq-ex-viewtoggle {
    display: inline-flex;
    background: var(--qq-brass-soft, #eeeae2);
    border-radius: 10px;
    padding: 3px;
    gap: 2px;
}

.qq-ex-viewtoggle button {
    border: none;
    background: transparent;
    color: var(--qq-text-body);
    border-radius: 8px;
    padding: 0.35rem 0.6rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
}

.qq-ex-viewtoggle button.active {
    background: var(--qq-ink);
    color: var(--qq-paper);
}

.qq-ex-storelist {
    border-radius: 20px;
    overflow: hidden;
}

.qq-ex-storerow {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.85rem 1.25rem;
    text-decoration: none;
    color: inherit;
}

.qq-ex-storerow:hover {
    background: var(--qq-paper, #fbf9f4);
    color: inherit;
}

.qq-ex-storerow + .qq-ex-storerow {
    border-top: 1px solid var(--qq-border-soft);
}

.qq-ex-row-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    font-weight: 700;
    font-size: 0.95rem;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
}

.qq-ex-row-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.qq-ex-row-main {
    flex: 1;
    min-width: 0;
}

.qq-ex-row-name {
    display: block;
    font-weight: 700;
    font-size: 0.9rem;
}

.qq-ex-row-meta {
    display: block;
    font-size: 0.78rem;
    color: var(--qq-text-muted);
}

.qq-ex-row-rating {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--qq-brass);
    white-space: nowrap;
}

.qq-ex-row-rating span {
    color: var(--qq-text-faint);
    font-weight: 500;
}

/* Product meta: store-color dot + name */
.qq-ex-prod-meta {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.2rem;
    min-width: 0;
}

.qq-ex-prod-meta .dot {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    font-size: 0.6rem;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.qq-ex-prod-meta .txt {
    font-size: 0.78rem;
    color: var(--qq-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Empty state */
.qq-ex-empty {
    text-align: center;
    padding: 3.5rem 1rem;
}

.qq-ex-empty-icon {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--qq-brass-tint);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1rem;
}

.qq-ex-empty-title {
    font-size: 1.05rem;
    font-weight: 700;
    margin-bottom: 0.25rem;
}

.qq-ex-empty-hint {
    color: var(--qq-text-muted);
    margin-bottom: 1.25rem;
}

.qq-ex-fadeup {
    animation: qqFadeUp 0.3s ease;
}

@keyframes qqFadeUp {
    from { opacity: 0; transform: translateY(7px); }
    to { opacity: 1; transform: none; }
}

@keyframes qqSlideDown {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: none; }
}

@keyframes qqShimmer {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
}

/* Compact segmented control (the min-rating picker). */
.qq-seg-sm button {
    padding: 0.5rem 0.75rem;
    font-size: 0.8rem;
    flex: 1;
}

.qq-view-link {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--qq-brass);
}

.qq-explore-service-card {
    border-radius: 20px;
    overflow: hidden;
}

.qq-explore-service-avatar {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    font-weight: 700;
    font-size: 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.qq-explore-product {
    display: block;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.qq-explore-product {
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

.qq-explore-product:hover {
    transform: translateY(-3px);
    box-shadow: 0 16px 34px rgba(23, 21, 18, 0.1);
    border-color: #d9cfbc;
    color: inherit;
}

.qq-explore-product img {
    width: 100%;
    height: 150px;
    object-fit: cover;
    display: block;
}

/* --- Service providers (spec 014) --------------------------------------- */
/* The people who perform services. One tile per person carries everything
   about them — face, name, whether they do this service, their photo upload —
   because splitting "tick a box here, pick a name in that dropdown to attach a
   photo" across two controls is what made the first version unusable. */

.qq-team {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
    gap: 0.75rem;
}

.qq-team-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 0.9rem 0.6rem 0.75rem;
    border: 1.5px solid var(--qq-border);
    border-radius: 18px;
    background: var(--qq-card);
    cursor: pointer;
    text-align: center;
    transition: border-color .15s ease, background-color .15s ease, transform .15s ease;
}

.qq-team-tile:hover {
    border-color: var(--qq-border-soft, var(--qq-brass));
    transform: translateY(-1px);
}

.qq-team-tile.on {
    border-color: var(--qq-brass);
    background: color-mix(in srgb, var(--qq-brass) 10%, var(--qq-card));
}

/* The tick is the answer to "does this person do this service?" — the whole
   tile toggles it, so the badge is state, not a second button. */
.qq-team-check {
    position: absolute;
    top: 0.45rem;
    left: 0.5rem;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: .7rem;
    font-weight: 700;
    color: var(--qq-paper);
    background: var(--qq-brass);
}

.qq-team-remove {
    position: absolute;
    top: 0.3rem;
    right: 0.35rem;
    width: 22px;
    height: 22px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--qq-text-faint);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transition: opacity .15s ease, color .15s ease, background-color .15s ease;
}

.qq-team-tile:hover .qq-team-remove,
.qq-team-remove:focus-visible {
    opacity: 1;
}

.qq-team-remove:hover {
    color: var(--qq-bad-fg);
    background: var(--qq-bad-bg);
}

/* Touch has no hover, so the control can't hide behind one. */
@media (hover: none) {
    .qq-team-remove { opacity: 1; }
}

/* The avatar IS the upload control: click the face to change the face. */
.qq-team-photo {
    position: relative;
    display: block;
    cursor: pointer;
}

.qq-team-photo .qq-provider-avatar {
    width: 62px;
    height: 62px;
}

.qq-team-tile.on .qq-provider-avatar {
    box-shadow: 0 0 0 2px var(--qq-card), 0 0 0 4px var(--qq-brass);
}

.qq-team-cam {
    position: absolute;
    right: -2px;
    bottom: -2px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--qq-brass);
    color: var(--qq-paper);
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--qq-card);
}

.qq-team-cam svg { width: 11px; height: 11px; }

.qq-team-name {
    font-size: .85rem;
    font-weight: 600;
    color: var(--qq-text);
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Add tile: a dashed slot that becomes a name field in place. */
.qq-team-add {
    border-style: dashed;
    background: transparent;
    justify-content: center;
    min-height: 8.5rem;
    color: var(--qq-text-muted);
}

.qq-team-add-plus {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--qq-brass) 14%, transparent);
    color: var(--qq-brass-deep);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    line-height: 1;
}

.qq-provider-avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
    flex: none;
    background: var(--qq-track-off);
}

.qq-provider-avatar-initial {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: .78rem;
    font-weight: 700;
    color: var(--qq-brass-deep);
    background: color-mix(in srgb, var(--qq-brass) 22%, var(--qq-card));
}

.qq-team-photo .qq-provider-avatar-initial { font-size: 1.4rem; }

/* --- The team page ------------------------------------------------------ */
/* A roster list with one person open beside it, rather than a card per person
   carrying its own full checkbox list. The old grid grew sideways and buried
   the only two facts that decide whether bookings work: a person on zero
   services can't be booked at all, and a service nobody performs falls back to
   the shop's single shared calendar. The first is stated on the row, the second
   is what the coverage card exists to show. */

.qq-team-page {
    max-width: 68rem;
}

.qq-team-head {
    display: flex;
    align-items: flex-start;
    gap: 1.25rem;
    margin-bottom: 1.15rem;
}

.qq-team-head-text {
    flex: 1;
    min-width: 0;
}

.qq-team-intro {
    margin: 0;
    font-size: .845rem;
    color: var(--qq-text-muted);
    max-width: 38rem;
    line-height: 1.55;
}

/* Counters. Numbers are mono so the eye can compare them down the strip, and
   the block is a live region: ticking one pill can be what closes the last gap. */
.qq-team-stats {
    display: flex;
    align-items: center;
    gap: 1.6rem;
    flex-wrap: wrap;
    padding: 0.875rem 1.25rem;
    border-radius: 14px;
}

.qq-team-stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.qq-team-stat-label {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: .6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .14em;
    color: var(--qq-text-faint);
}

.qq-team-stat-value {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: 1.19rem;
    font-weight: 700;
}

.qq-team-stat-value.warn { color: var(--qq-warn-fg); }

.qq-team-stat-div {
    width: 1px;
    align-self: stretch;
    background: var(--qq-border-soft);
}

.qq-team-stat-note {
    margin: 0 0 0 auto;
    font-size: .78rem;
    color: var(--qq-text-muted);
    max-width: 20rem;
    line-height: 1.45;
}

.qq-team-grid {
    display: grid;
    grid-template-columns: 7fr 5fr;
    gap: 1.375rem;
    align-items: start;
    margin-top: 1.125rem;
}

/* A grid item's default min-width:auto refuses to shrink below its content, so
   one long service name in a pill would widen its whole column and push the
   page sideways. Let the columns shrink and the content wrap instead. */
.qq-team-grid > * {
    min-width: 0;
}

.qq-team-side {
    display: flex;
    flex-direction: column;
    gap: 1.125rem;
}

/* --- Roster list --- */
.qq-roster {
    overflow: hidden;
}

.qq-roster-top {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.94rem 1.25rem;
    border-bottom: 1px solid var(--qq-border-soft);
}

.qq-roster-title {
    font-weight: 700;
    font-size: .97rem;
}

.qq-roster-hint {
    margin-left: auto;
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: .69rem;
    color: var(--qq-text-faint);
}

.qq-roster-adding {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.875rem 1.25rem;
    border-bottom: 1px solid var(--qq-border-soft);
    background: color-mix(in srgb, var(--qq-brass) 5%, var(--qq-card));
}

.qq-roster-adding .qq-input {
    flex: 1;
    min-width: 0;
}

.qq-roster-add-plus {
    width: 38px;
    height: 38px;
    flex-shrink: 0;
    border-radius: 50%;
    border: 1px dashed var(--qq-gold-bright);
    color: var(--qq-brass);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    line-height: 1;
}

.qq-roster-add-cancel {
    font-size: .82rem;
    color: var(--qq-text-muted);
}

/* The selected edge is a border that is always there, only transparent when
   the person is closed — a border that appears would shift the whole row. */
.qq-roster-item {
    border-bottom: 1px solid var(--qq-border-soft);
    border-left: 3px solid transparent;
}

.qq-roster-item:last-child { border-bottom: 0; }

.qq-roster-item.on {
    border-left-color: var(--qq-gold-bright);
    background: color-mix(in srgb, var(--qq-brass) 4%, var(--qq-card));
}

.qq-roster-row {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.8rem 1.25rem;
    cursor: pointer;
}

.qq-roster-row:focus-visible {
    outline: 2px solid var(--qq-brass);
    outline-offset: -2px;
}

.qq-roster-row .qq-team-photo .qq-provider-avatar { width: 38px; height: 38px; }
.qq-roster-row .qq-team-photo .qq-provider-avatar-initial { font-size: .95rem; }
.qq-roster-row .qq-team-cam { width: 17px; height: 17px; }
.qq-roster-row .qq-team-cam svg { width: 8px; height: 8px; }

/* The badge is brass, so the default spinner (border + brass) would vanish
   into it. */
.qq-team-cam .qq-spinner {
    width: 9px;
    height: 9px;
    border-width: 2px;
    border-color: color-mix(in srgb, var(--qq-paper) 40%, transparent);
    border-top-color: var(--qq-paper);
}

.qq-roster-main {
    flex: 1;
    min-width: 0;
}

.qq-roster-name {
    font-weight: 700;
    font-size: .9rem;
    color: var(--qq-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qq-roster-count {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: .69rem;
    color: var(--qq-text-faint);
    margin-top: 2px;
}

.qq-roster-count.warn { color: var(--qq-warn-fg); }

.qq-roster-chips {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}

.qq-roster-chip {
    font-size: .69rem;
    color: var(--qq-text-muted);
    background: var(--qq-shell);
    border: 1px solid var(--qq-border-soft);
    padding: 3px 8px;
    border-radius: 99px;
    white-space: nowrap;
    max-width: 8rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

.qq-roster-more {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: .69rem;
    color: var(--qq-text-faint);
}

.qq-roster-x {
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 99px;
    background: transparent;
    color: var(--qq-text-faint);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
}

.qq-roster-x:hover {
    color: var(--qq-bad-fg);
    background: var(--qq-bad-bg);
}

/* Phone-only: the row carries its own pills, because there is no second
   column to open a person into. */
.qq-roster-inline { display: none; }

.qq-roster-acts {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.625rem;
    font-size: .8rem;
    color: var(--qq-text-muted);
}

.qq-roster-acts .qq-input { flex: 1 1 8rem; min-width: 0; }

/* --- The open person --- */
.qq-person {
    padding: 1.25rem;
}

.qq-person-head {
    display: flex;
    align-items: center;
    gap: 0.8rem;
}

.qq-person .qq-team-photo .qq-provider-avatar { width: 58px; height: 58px; }
.qq-person .qq-team-photo .qq-provider-avatar-initial { font-size: 1.35rem; }
.qq-person .qq-team-cam { width: 22px; height: 22px; }
.qq-person .qq-team-cam svg { width: 11px; height: 11px; }

.qq-person-ident {
    flex: 1;
    min-width: 0;
}

.qq-person-name {
    font-size: 1.19rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qq-person-actions {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    flex-wrap: wrap;
    margin-top: 0.2rem;
    font-size: .78rem;
    color: var(--qq-text-faint);
}

.qq-person-rename {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.qq-person-rule {
    height: 1px;
    background: var(--qq-border-soft);
    margin: 1.06rem 0 0.94rem;
}

.qq-person-label { margin-bottom: 0.625rem; }

/* A quiet inset surface: "add a service first", the calendar row. */
.qq-team-inset {
    font-size: .78rem;
    color: var(--qq-text-muted);
    background: var(--qq-paper);
    border: 1px solid var(--qq-border-soft);
    border-radius: 12px;
    padding: 0.75rem 0.875rem;
    line-height: 1.5;
}

/* Nobody can book this person: amber and in words, not a grey footnote. */
.qq-team-warn {
    margin-top: 0.75rem;
    font-size: .78rem;
    color: var(--qq-warn-fg);
    background: var(--qq-warn-bg);
    border: 1px solid color-mix(in srgb, var(--qq-warn-fg) 25%, var(--qq-warn-bg));
    border-radius: 12px;
    padding: 0.7rem 0.8rem;
    line-height: 1.5;
}

.qq-hours-row {
    margin-top: 0.875rem;
    background: var(--qq-paper);
    border: 1px solid var(--qq-border-soft);
    border-radius: 12px;
    padding: 0.75rem 0.875rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.qq-hours-text {
    flex: 1;
    min-width: 0;
}

.qq-hours-title {
    font-size: .78rem;
    font-weight: 600;
}

.qq-hours-sub {
    font-size: .72rem;
    color: var(--qq-text-muted);
    margin-top: 3px;
    line-height: 1.45;
}

/* --- Who covers what --- */
/* The same join as the pills, read from the service's side: the only place a
   service with nobody on it becomes visible before a buyer finds it. */
.qq-cover {
    overflow: hidden;
}

.qq-cover-top {
    padding: 0.875rem 1.125rem;
    border-bottom: 1px solid var(--qq-border-soft);
}

.qq-cover-title {
    font-weight: 700;
    font-size: .94rem;
}

.qq-cover-sub {
    font-size: .75rem;
    color: var(--qq-text-muted);
    margin-top: 3px;
    line-height: 1.45;
}

.qq-cover-row {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.69rem 1.125rem;
    border-bottom: 1px solid var(--qq-border-soft);
}

.qq-cover-row:last-child { border-bottom: 0; }

.qq-cover-row.gap {
    background: color-mix(in srgb, var(--qq-warn-bg) 45%, var(--qq-card));
}

/* A hidden service with nobody on it is not a live problem. */
.qq-cover-row.off { opacity: .68; }

.qq-cover-main {
    flex: 1;
    min-width: 0;
}

.qq-cover-name {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: .81rem;
    font-weight: 600;
}

.qq-cover-off,
.qq-svc-pill-off {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: .6rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--qq-text-faint);
    border: 1px solid var(--qq-border);
    border-radius: 99px;
    padding: 1px 6px;
    white-space: nowrap;
}

.qq-cover-note {
    font-size: .72rem;
    color: var(--qq-text-muted);
    margin-top: 2px;
}

.qq-cover-note.warn { color: var(--qq-warn-fg); }

.qq-cover-faces {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

.qq-cover-faces .qq-provider-avatar {
    width: 25px;
    height: 25px;
    border: 2px solid var(--qq-card);
    margin-left: -6px;
}

.qq-cover-faces .qq-provider-avatar-initial { font-size: .63rem; }

.qq-cover-more {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: .66rem;
    color: var(--qq-text-faint);
    margin-left: 4px;
}

/* --- Nobody added yet --- */
.qq-team-empty {
    max-width: 42.5rem;
    padding: 2.125rem;
}

.qq-team-ghosts {
    display: flex;
    margin-bottom: 1.125rem;
}

.qq-team-ghost {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--qq-shell);
    border: 1px dashed var(--qq-border);
    margin-left: -10px;
}

.qq-team-ghost-lead {
    margin-left: 0;
    background: var(--qq-brass-tint);
    color: var(--qq-brass);
    border: 2px solid var(--qq-card);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    line-height: 1;
}

.qq-team-empty-title {
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.qq-team-empty-body {
    font-size: .845rem;
    color: var(--qq-text-muted);
    margin: 0.5rem 0 0;
    max-width: 29rem;
    line-height: 1.55;
}

.qq-team-empty-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
}

.qq-team-empty-also {
    font-size: .78rem;
    color: var(--qq-text-faint);
}

/* The pinned add bar only exists on phones. */
.qq-team-bar { display: none; }

@media (max-width: 767.98px) {
    .qq-team-page { padding-bottom: 5.5rem; }

    .qq-team-head-add { display: none; }

    .qq-team-stats { gap: 1.1rem; }

    .qq-team-stat-note {
        margin-left: 0;
        max-width: none;
        flex-basis: 100%;
        font-size: .72rem;
    }

    .qq-team-grid {
        grid-template-columns: 1fr;
        gap: 0.875rem;
    }

    /* The list becomes free-standing cards: a person and their pills are one
       object on a phone. */
    .qq-roster {
        background: transparent;
        border: 0;
        border-radius: 0;
        overflow: visible;
    }

    .qq-roster-top { display: none; }

    .qq-roster-adding {
        flex-wrap: wrap;
        border: 1px solid var(--qq-border);
        border-radius: 16px;
        margin-bottom: 0.75rem;
        padding: 0.875rem;
    }

    .qq-roster-item {
        background: var(--qq-card);
        border: 1px solid var(--qq-border);
        border-left-width: 3px;
        border-radius: 16px;
        margin-bottom: 0.75rem;
    }

    .qq-roster-item:last-child { border-bottom: 1px solid var(--qq-border); }

    .qq-roster-row {
        padding: 0.875rem;
        cursor: default;
    }

    .qq-roster-row .qq-team-photo .qq-provider-avatar { width: 42px; height: 42px; }
    .qq-roster-row .qq-team-photo .qq-provider-avatar-initial { font-size: 1.05rem; }
    .qq-roster-row .qq-team-cam { width: 20px; height: 20px; }
    .qq-roster-row .qq-team-cam svg { width: 10px; height: 10px; }

    .qq-roster-chips { display: none; }

    .qq-roster-x {
        width: 44px;
        height: 44px;
    }

    .qq-roster-inline {
        display: block;
        padding: 0 0.875rem 0.875rem;
    }

    /* No room for a second column, so nothing is "open" here. */
    .qq-person { display: none; }

    .qq-svc-pill {
        min-height: 44px;
        font-size: .8rem;
    }

    .qq-team-bar {
        display: block;
        position: fixed;
        inset: auto 0 0;
        z-index: 45;
        padding: 0.75rem 1.125rem calc(0.75rem + env(safe-area-inset-bottom));
        background: var(--qq-card);
        border-top: 1px solid var(--qq-border);
        box-shadow: 0 -6px 18px rgba(23, 21, 18, 0.05);
    }
}

.qq-linkish {
    border: 0;
    background: none;
    padding: 0;
    font: inherit;
    color: var(--qq-brass-deep);
    cursor: pointer;
    text-decoration: none;
}

.qq-linkish:hover { text-decoration: underline; }
.qq-linkish-bad { color: var(--qq-bad-fg); }

/* Which services a person performs. A real checkbox, visually hidden inside
   its own label, so Tab and Space still work and the state is announced. The
   leading glyph carries the state as well as the colour does — ✓ on, + off —
   because a border tint alone is not a state anyone can read. */
.qq-svc-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
}

.qq-svc-pill {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.4rem 0.75rem;
    border: 1px solid var(--qq-border);
    border-radius: 99px;
    background: var(--qq-card);
    font-size: .78rem;
    color: var(--qq-text-body);
    cursor: pointer;
}

.qq-svc-pill input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
    pointer-events: none;
}

.qq-svc-pill:focus-within {
    outline: 2px solid var(--qq-brass);
    outline-offset: 2px;
}

.qq-svc-pill.on {
    border-color: var(--qq-gold-bright);
    background: color-mix(in srgb, var(--qq-brass) 10%, var(--qq-card));
    color: var(--qq-brass-deep);
}

/* Hidden services still take assignments — someone has to be able to perform
   one before it can be switched back on — but they are drawn as the aside
   they are, so a gap on one doesn't read as a live problem. */
.qq-svc-pill.off {
    border-style: dashed;
    opacity: .75;
}

.qq-svc-pill-mark {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: .69rem;
    font-weight: 700;
}

.qq-svc-pill-dur {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: .66rem;
    color: var(--qq-text-faint);
}

/* --- Buyer's provider chooser ------------------------------------------- */
/* Bigger than the seller's roster: this is a choice about a person, so the
   face leads. The magnifier is a separate small target for a proper look at
   the photo — the card itself always selects, never navigates. */

.qq-pick-team {
    display: flex;
    gap: 0.6rem;
    overflow-x: auto;
    padding-bottom: 0.25rem;
    scrollbar-width: none;
}

.qq-pick-team::-webkit-scrollbar { display: none; }

.qq-pick {
    position: relative;
    flex: 0 0 auto;
    width: 6.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.45rem;
    padding: 0.85rem 0.5rem 0.7rem;
    border: 1.5px solid var(--qq-border);
    border-radius: 18px;
    background: var(--qq-card);
    cursor: pointer;
    text-align: center;
    transition: border-color .15s ease, background-color .15s ease;
}

.qq-pick.on {
    border-color: var(--qq-brass);
    background: color-mix(in srgb, var(--qq-brass) 10%, var(--qq-card));
}

.qq-pick .qq-provider-avatar {
    width: 60px;
    height: 60px;
}

.qq-pick.on .qq-provider-avatar {
    box-shadow: 0 0 0 2px var(--qq-card), 0 0 0 4px var(--qq-brass);
}

.qq-pick-name {
    font-size: .82rem;
    font-weight: 600;
    color: var(--qq-text);
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qq-pick-zoom {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: rgba(23, 21, 18, 0.55);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
}

.qq-pick-zoom:hover { background: rgba(23, 21, 18, 0.75); color: #fff; }
.qq-pick-zoom svg { width: 12px; height: 12px; }

/* "Anyone available" has no face — a neutral glyph tile instead. */
.qq-pick-any-glyph {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--qq-brass) 16%, var(--qq-card));
    color: var(--qq-brass-deep);
    display: flex;
    align-items: center;
    justify-content: center;
}

.qq-pick-any-glyph svg { width: 24px; height: 24px; }

/* The card carries two links (photo → gallery, body → store), so the colour
   and underline resets that used to sit on the card itself move onto them.
   The photo anchor is also the positioning context for its count badge. */
.qq-ex-prod-photo {
    display: block;
    position: relative;
}

.qq-ex-prod-body,
.qq-ex-prod-body:hover {
    display: block;
    text-decoration: none;
    color: inherit;
}

.qq-explore-noimg {
    height: 150px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: repeating-linear-gradient(45deg, #efe9dd 0 12px, #f6f2e9 12px 24px);
}

.qq-explore-noimg span {
    font-family: ui-monospace, monospace;
    font-size: 0.7rem;
    color: var(--qq-text-faint);
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 999px;
    padding: 0.25rem 0.8rem;
}

.qq-explore-service {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.9rem 1.15rem;
    flex-wrap: wrap;
}

.qq-explore-service + .qq-explore-service {
    border-top: 1px solid var(--qq-border-soft);
}

/* --- Seller getting-started checklist ---------------------------------------- */
.qq-checklist {
    overflow: hidden;
}

.qq-checklist-head {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    padding: 1rem 1.25rem 0.6rem;
}

.qq-checklist-bar {
    height: 6px;
    background: var(--qq-border-soft);
    border-radius: 99px;
    margin: 0 1.25rem 0.6rem;
    overflow: hidden;
}

.qq-checklist-bar div {
    height: 100%;
    background: var(--qq-gold-bright);
    border-radius: 99px;
    transition: width 0.3s ease;
}

.qq-checklist-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 1.25rem;
    border-top: 1px solid var(--qq-border-soft);
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--qq-text);
    text-decoration: none;
}

.qq-checklist-item:hover {
    background: var(--qq-paper);
    color: var(--qq-text);
}

.qq-checklist-mark {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 1.5px solid var(--qq-border);
    background: var(--qq-card);
    /* Paper, not #fff: the done state paints brass behind this, which flips
       light in dark mode. */
    color: var(--qq-paper, #fff);
    font-size: 0.72rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.qq-checklist-item.done .qq-checklist-mark {
    background: var(--qq-brass);
    border-color: var(--qq-brass);
}

.qq-checklist-item.done span:not(.qq-checklist-mark) {
    color: var(--qq-text-faint);
    text-decoration: line-through;
}

.qq-checklist-go {
    margin-left: auto;
    color: var(--qq-brass);
    font-weight: 700;
}

/* --- Spotlight tour ------------------------------------------------------------ */
.qq-tour-overlay {
    position: fixed;
    inset: 0;
    z-index: 1100;
}

.qq-tour-spot {
    position: fixed;
    border-radius: 14px;
    box-shadow: 0 0 0 9999px rgba(23, 21, 18, 0.55), 0 0 0 3px var(--qq-gold-bright);
    transition: all 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
    pointer-events: none;
}

.qq-tour-tip {
    position: fixed;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 16px;
    padding: 1.1rem 1.25rem;
    box-shadow: 0 14px 40px rgba(23, 21, 18, 0.25);
    transition: top 0.28s ease, left 0.28s ease;
}

.qq-tour-tip-head {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.qq-tour-tip-title {
    font-weight: 700;
    font-size: 1rem;
}

.qq-tour-skip {
    margin-left: auto;
    border: none;
    background: none;
    color: var(--qq-text-faint);
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.15rem;
}

.qq-tour-skip:hover {
    color: var(--qq-text);
}

.qq-tour-tip p {
    font-size: 0.88rem;
    color: var(--qq-text-body);
    line-height: 1.55;
    margin: 0.4rem 0 0.9rem;
}

.qq-tour-tip-foot {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.qq-tour-count {
    font-size: 0.76rem;
    color: var(--qq-text-faint);
    margin-right: auto;
}

/* --- How it works (/how-it-works) -------------------------------------------- */
.qq-hiw-head {
    padding: 2.5rem 0 2.75rem;
    max-width: 52rem;
}

.qq-hiw-head h1 {
    font-size: clamp(2rem, 4.5vw, 3.25rem);
    line-height: 1.05;
    letter-spacing: -0.04em;
    margin: 1.25rem 0 0;
}

.qq-hiw-head p {
    font-size: 1.05rem;
    color: var(--qq-text-body);
    line-height: 1.6;
    max-width: 35rem;
    margin-top: 1.1rem;
}

.qq-hiw-step {
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 20px;
    padding: 1.75rem;
    height: 100%;
}

.qq-hiw-step-head {
    display: flex;
    align-items: center;
    gap: 0.9rem;
}

.qq-hiw-num {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--qq-brass-tint);
    color: var(--qq-brass-deep);
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.qq-hiw-step-title {
    font-weight: 700;
    font-size: 1.1rem;
    margin-top: 1.1rem;
}

.qq-hiw-step p {
    font-size: 0.9rem;
    color: var(--qq-text-body);
    line-height: 1.6;
    margin: 0.5rem 0 0;
}

.qq-hiw-journey {
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 20px;
    margin-top: 1.1rem;
    padding: 1.35rem 1.75rem;
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.qq-hiw-journey-track {
    flex: 1;
    min-width: 16rem;
    display: flex;
    align-items: center;
}

.qq-hiw-journey-track .qq-pill {
    white-space: nowrap;
}

.qq-hiw-journey-line {
    flex: 1;
    height: 1.5px;
    background: var(--qq-border);
    min-width: 0.5rem;
}

.qq-hiw-sell {
    background: var(--qq-ink);
    color: var(--qq-paper);
    border-radius: 22px;
    padding: 2.75rem 2.5rem;
    margin: 3rem 0;
}

.qq-hiw-sell .gold {
    color: var(--qq-gold-bright);
}

.qq-hiw-sell-hint {
    font-size: 0.82rem;
    /* Ink panel inverts to light in dark mode — see .qq-seller-strip p. */
    color: color-mix(in srgb, var(--qq-paper) 72%, var(--qq-ink));
}

.qq-hiw-sell-step {
    border: 1px solid color-mix(in srgb, var(--qq-paper) 14%, var(--qq-ink));
    border-radius: 18px;
    padding: 1.5rem;
    height: 100%;
}

.qq-hiw-sell-step .step {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--qq-gold-bright);
    letter-spacing: 0.04em;
}

.qq-hiw-sell-step .title {
    font-weight: 700;
    font-size: 1.05rem;
    margin-top: 0.6rem;
}

.qq-hiw-sell-step p {
    font-size: 0.88rem;
    color: color-mix(in srgb, var(--qq-paper) 72%, var(--qq-ink));
    line-height: 1.6;
    margin: 0.45rem 0 0;
}

.qq-hiw-faq {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 3rem;
    align-items: start;
    margin: 0 0 3.5rem;
}

.qq-hiw-faq-card {
    border-radius: 20px;
    overflow: hidden;
}

.qq-hiw-faq-card details + details {
    border-top: 1px solid var(--qq-border-soft);
}

.qq-hiw-faq-card summary {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.25rem 1.6rem;
    font-weight: 600;
    font-size: 0.97rem;
    cursor: pointer;
    list-style: none;
}

.qq-hiw-faq-card summary::-webkit-details-marker {
    display: none;
}

.qq-hiw-faq-mark {
    margin-left: auto;
    color: var(--qq-text-faint);
    font-size: 1.15rem;
}

.qq-hiw-faq-mark::before {
    content: "+";
}

.qq-hiw-faq-card details[open] .qq-hiw-faq-mark::before {
    content: "−";
}

.qq-hiw-faq-card details > p {
    padding: 0 1.6rem 1.25rem;
    font-size: 0.9rem;
    color: var(--qq-text-body);
    line-height: 1.6;
    max-width: 40rem;
    margin: 0;
}

@media (max-width: 768px) {
    .qq-hiw-faq {
        grid-template-columns: 1fr;
        gap: 1.25rem;
    }

    .qq-hiw-journey-track {
        overflow-x: auto;
        scrollbar-width: none;
    }

    .qq-hiw-journey-track::-webkit-scrollbar {
        display: none;
    }
}

/* --- Storefront toolbar (in-store search + actions) ----------------------------------------- */
.sf-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    padding: 0.9rem 1.5rem;
    border-top: 1px solid color-mix(in srgb, var(--sf-text) 12%, transparent);
    border-bottom: 1px solid color-mix(in srgb, var(--sf-text) 12%, transparent);
    margin-top: 1rem;
}

.sf-search {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    flex: 1 1 auto;
    min-width: 16rem;
}

.sf-search input {
    flex: 1 1 12rem;
    min-width: 10rem;
    border: 1px solid color-mix(in srgb, var(--sf-text) 22%, transparent);
    background: color-mix(in srgb, var(--sf-bg) 88%, var(--sf-text) 4%);
    color: var(--sf-text);
    border-radius: 999px;
    padding: 0.55rem 1rem 0.55rem 2.5rem;
    font: inherit;
}

.sf-search input:focus {
    outline: 2px solid var(--sf-accent);
    outline-offset: 1px;
}

.sf-search-icon {
    position: absolute;
    left: 0.9rem;
    top: 50%;
    transform: translateY(-50%);
    opacity: 0.55;
    pointer-events: none;
}

/* --- Private messaging ----------------------------------------------------------------------- */
.qq-msg-row {
    text-decoration: none;
    color: inherit;
}

/* An inbox row is a <button> now that opening a thread happens in place rather
   than by navigating. A button is not a link: it shrink-wraps its content,
   centres its text and paints its own background and border, which turned the
   rows into narrow grey boxes floating in a full-width card. This puts it back
   to what the anchor gave for free — everything else about .qq-row already
   works, since it was always display:flex. */
button.qq-row {
    width: 100%;
    background: none;
    border: 0;
    border-radius: 0;
    text-align: left;
    font: inherit;
    color: inherit;
    -webkit-appearance: none;
    appearance: none;
}

/* The border between rows comes from .qq-row + .qq-row, and a button resetting
   its own border above would otherwise drop it. */
button.qq-row + button.qq-row,
button.qq-row + a.qq-row,
a.qq-row + button.qq-row {
    border-top: 1px solid var(--qq-border-soft);
}

.qq-msg-row:hover {
    background: var(--qq-border-soft);
    color: inherit;
}

.qq-msg-preview {
    color: var(--qq-text-muted);
    font-size: 0.85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.qq-msg-thread {
    display: flex;
    flex-direction: column;
    max-width: 46rem;
}

.qq-msg-head {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.9rem 1.15rem;
    border-bottom: 1px solid var(--qq-border-soft);
}

.qq-msg-back {
    font-size: 1.3rem;
    text-decoration: none;
    color: var(--qq-text-muted);
    line-height: 1;
}

.qq-msg-scroll {
    display: flex;
    flex-direction: column-reverse;
    gap: 0.35rem;
    padding: 1rem 1.15rem;
    height: 24rem;
    overflow-y: auto;
    background: var(--qq-shell);
}

.qq-msg {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    max-width: 78%;
}

.qq-msg-mine {
    align-self: flex-end;
    align-items: flex-end;
}

.qq-msg-bubble {
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 14px 14px 14px 4px;
    padding: 0.5rem 0.85rem;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.qq-msg-mine .qq-msg-bubble {
    background: var(--qq-brass-tint);
    border-color: var(--qq-brass-soft);
    border-radius: 14px 14px 4px 14px;
}

.qq-msg-time {
    font-size: 0.7rem;
    color: var(--qq-text-faint);
    margin: 0.15rem 0.25rem 0.35rem;
}

.qq-msg-compose {
    display: flex;
    gap: 0.6rem;
    align-items: flex-end;
    padding: 0.9rem 1.15rem;
    border-top: 1px solid var(--qq-border-soft);
}

.qq-msg-compose textarea {
    flex: 1;
    resize: none;
}

/* --- Select2 theme overrides (city pickers) -------------------------------------------------- */
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    border: 1px solid var(--qq-border);
    border-radius: 12px;
    min-height: 44px;
    background: var(--qq-card);
}

.select2-container--default .select2-selection--single {
    height: 44px;
}

.select2-container--default .select2-selection--single .select2-selection__rendered {
    line-height: 42px;
    padding-left: 0.9rem;
    color: var(--qq-text);
}

.select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 42px;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
    background: var(--qq-brass-tint);
    color: var(--qq-brass-deep);
    border: none;
    border-radius: 999px;
    padding: 0.2rem 0.6rem;
    font-size: 0.85rem;
    font-weight: 600;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
    color: var(--qq-brass-deep);
    border: none;
    background: transparent;
    margin-right: 0.15rem;
}

.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--qq-brass);
    box-shadow: 0 0 0 3px var(--qq-brass-tint);
}

/* Select2 appends the dropdown to <body>, outside the field's own card, and
   ships `background: white` of its own — without this it stayed white while
   the inherited text went light, i.e. invisible in dark mode. */
.select2-dropdown {
    border: 1px solid var(--qq-border);
    border-radius: 12px;
    overflow: hidden;
    background: var(--qq-card);
    color: var(--qq-text);
    /* In dark mode card and page sit 1.12:1 apart, so the 1px border alone
       doesn't read as a raised layer — the shadow does the separating. */
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
}

.select2-container--default .select2-results__option {
    color: var(--qq-text);
}

.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
    /* brass-deep, not brass: plain brass measured 4.40:1 against the paper
       label in light mode, just under AA. And paper rather than #fff, because
       brass brightens in dark mode where white would drop to ~1.9:1 — paper
       inverts with the theme, so the label reads in both. */
    background: var(--qq-brass-deep);
    color: var(--qq-paper);
}

.select2-container--default .select2-results__option--selected {
    background: var(--qq-brass-tint);
    color: var(--qq-brass-deep);
    font-weight: 600;
}

.select2-container--default .select2-search--dropdown .select2-search__field,
.select2-container--default .select2-search--inline .select2-search__field {
    border: 1px solid var(--qq-border);
    border-radius: 8px;
    font: inherit;
    background: var(--qq-paper);
    color: var(--qq-text);
}

.select2-container--default .select2-search--dropdown .select2-search__field:focus {
    outline: none;
    border-color: var(--qq-brass);
}

.select2-container--default .select2-selection__placeholder {
    color: var(--qq-text-muted);
}

.select2-container--default .select2-selection--single .select2-selection__arrow b {
    border-color: var(--qq-text-muted) transparent transparent transparent;
}

.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
    border-color: transparent transparent var(--qq-text-muted) transparent;
}

/* Disabled selects: Select2's default grey ignores the theme. */
.select2-container--default .select2-selection--single.select2-selection--disabled,
.select2-container--default.select2-container--disabled .select2-selection--single {
    background: var(--qq-mute-bg);
    color: var(--qq-text-muted);
}

.select2-container--default .select2-search--inline .select2-search__field {
    border: none;
}

/* Admin (v3) Select2 skin: warm editorial kit. Scoped by the selection/dropdown
   css classes that js/admin-select.js passes to select2, so the storefront
   city pickers above keep their own look. */
.select2-container--default .select2-selection--single.qq-admin-s2 {
    background: var(--qq-admin-input);
    border: 1px solid var(--qq-admin-border);
    border-radius: 10px;
    height: auto;
    padding: 8px 10px;
}

.select2-container--default .select2-selection--single.qq-admin-s2 .select2-selection__rendered {
    color: var(--qq-admin-ink);
    font-size: 13px;
    line-height: 1.3;
    padding: 0 18px 0 2px;
}

.select2-container--default .select2-selection--single.qq-admin-s2 .select2-selection__arrow {
    top: 50%;
    transform: translateY(-50%);
    right: 8px;
}

.select2-container--default .select2-selection--single.qq-admin-s2 .select2-selection__arrow b {
    border-color: var(--qq-admin-faint) transparent transparent transparent;
}

.select2-container--default.select2-container--open .select2-selection--single.qq-admin-s2 {
    border-color: var(--qq-admin-accent);
    /* Was #f6e5df — a light peach halo that stayed light on the dark shell. */
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--qq-admin-accent) 26%, transparent);
}

.select2-container--default.select2-container--open .select2-selection--single.qq-admin-s2 .select2-selection__arrow b {
    border-color: transparent transparent var(--qq-admin-faint) transparent;
}

.select2-dropdown.qq-admin-s2-drop {
    background: var(--qq-admin-card);
    border: 1px solid var(--qq-admin-border);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 10px 30px rgba(40, 32, 20, 0.16);
}

.qq-admin-s2-drop .select2-results__option {
    font-size: 13px;
    color: var(--qq-admin-ink);
    padding: 8px 12px;
}

.qq-admin-s2-drop .select2-results__option--highlighted.select2-results__option--selectable {
    background: var(--qq-admin-shell);
    color: var(--qq-admin-ink);
}

.qq-admin-s2-drop .select2-results__option--selected {
    background: var(--qq-admin-flag);
    color: var(--qq-admin-accent);
    font-weight: 600;
}

.qq-admin-s2-drop .select2-search--dropdown {
    padding: 8px;
}

.qq-admin-s2-drop .select2-search--dropdown .select2-search__field {
    border: 1px solid var(--qq-admin-border);
    border-radius: 8px;
    background: var(--qq-admin-input);
    padding: 7px 10px;
    font-size: 13px;
    outline: none;
}

.qq-admin-s2-drop .select2-search--dropdown .select2-search__field:focus {
    border-color: var(--qq-admin-accent);
}

/* Storefront Select2 skin: the filter pills are part of a per-store branded
   surface, so they follow --sf-* rather than the site palette. js/qq-select.js
   anchors the dropdown inside .sf-page — appended to <body> it would resolve
   none of these tokens. */
.select2-container--default .select2-selection--single.qq-sf-s2 {
    background: color-mix(in srgb, var(--sf-bg) 88%, var(--sf-text) 4%);
    border: 1px solid color-mix(in srgb, var(--sf-text) 22%, transparent);
    border-radius: 999px;
    height: auto;
    padding: 0.5rem 0.9rem;
}

.select2-container--default .select2-selection--single.qq-sf-s2 .select2-selection__rendered {
    color: var(--sf-text);
    font-size: 0.9rem;
    line-height: 1.3;
    padding: 0 18px 0 0;
}

.select2-container--default .select2-selection--single.qq-sf-s2 .select2-selection__arrow {
    top: 50%;
    transform: translateY(-50%);
    right: 10px;
}

.select2-container--default .select2-selection--single.qq-sf-s2 .select2-selection__arrow b {
    border-color: var(--sf-muted) transparent transparent transparent;
}

.select2-container--default.select2-container--open .select2-selection--single.qq-sf-s2 {
    border-color: var(--sf-primary);
}

.select2-dropdown.qq-sf-s2-drop {
    background: var(--sf-card);
    border: 1px solid var(--sf-border);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
}

.qq-sf-s2-drop .select2-results__option {
    font-size: 0.875rem;
    color: var(--sf-text);
    padding: 8px 12px;
}

.qq-sf-s2-drop .select2-results__option--highlighted.select2-results__option--selectable {
    background: var(--sf-primary);
    /* The store picks --sf-primary, so the label can't be a fixed colour —
       ThemeColors.ReadableTextOn drives this same choice server-side. */
    color: var(--sf-on-primary, #fff);
}

.qq-sf-s2-drop .select2-results__option--selected {
    background: color-mix(in srgb, var(--sf-primary) 14%, transparent);
    color: var(--sf-text);
    font-weight: 600;
}

.qq-sf-s2-drop .select2-search--dropdown {
    padding: 8px;
}

.qq-sf-s2-drop .select2-search--dropdown .select2-search__field {
    border: 1px solid var(--sf-border);
    border-radius: 9px;
    background: var(--sf-bg);
    color: var(--sf-text);
    padding: 7px 10px;
    font-size: 0.875rem;
    outline: none;
}

.qq-sf-s2-drop .select2-search--dropdown .select2-search__field:focus {
    border-color: var(--sf-primary);
}

/* --- Date picker (qq-dt) ---------------------------------------------------------------
   Design handoff "Modern - Date Time Controls", control 1. The handoff's
   --qq-primary maps to --qq-brass: this app has one accent, and a second would
   put two different "selected" colours in the same form.

   Text on a brass fill is --qq-paper, not #fff — brass brightens to #d9a94e in
   dark mode, where white drops to ~1.9:1. Paper inverts with the theme, so the
   label reads in both (the same trick the toggle knob and Select2 rows use). */
.qq-dt {
    position: relative;
}

.qq-dt-set {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.qq-dt-field {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    min-height: 44px;
    box-sizing: border-box;
    padding: 0.7rem 0.85rem;
    border: 1.5px solid var(--qq-border);
    border-radius: 14px;
    background: var(--qq-card);
    color: var(--qq-text);
    font: inherit;
    font-size: 0.875rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

.qq-dt-field .qq-dt-icon {
    flex-shrink: 0;
    color: var(--qq-text-faint);
    transition: color 120ms ease;
}

.qq-dt-value {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Unset optional date: dashed and quiet, so "no end date" reads as a choice
   rather than a field someone forgot to fill. */
.qq-dt-field.is-empty {
    border-style: dashed;
    border-color: color-mix(in srgb, var(--qq-border) 80%, var(--qq-text-faint));
    background: transparent;
    /* muted, not faint: faint measured 3.63:1 in dark and this text states the
       field's value ("No end date"), so it isn't decorative. The dashed border
       and normal weight keep it quiet without dropping under AA. */
    color: var(--qq-text-muted);
    font-weight: 500;
}

.qq-dt-field:hover {
    border-color: color-mix(in srgb, var(--qq-brass) 45%, var(--qq-border));
}

.qq-dt-field:focus-visible,
.qq-dt.is-open .qq-dt-field {
    outline: none;
    border-color: var(--qq-brass);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--qq-brass) 18%, transparent);
}

.qq-dt.is-open .qq-dt-field .qq-dt-icon {
    color: var(--qq-brass);
}

.qq-dt-clear {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    border: none;
    border-radius: 999px;
    background: var(--qq-mute-bg);
    color: var(--qq-text-muted);
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
}

.qq-dt-clear:hover {
    background: color-mix(in srgb, var(--qq-bad-fg) 16%, var(--qq-mute-bg));
    color: var(--qq-bad-fg);
}

/* Desktop: an invisible catcher so clicking away closes without a document
   listener. Mobile turns it into the sheet's scrim. */
.qq-dt-backdrop {
    position: fixed;
    inset: 0;
    z-index: 40;
    background: transparent;
    border: none;
}

/* The popover is absolutely positioned, so any ancestor that clips will cut it
   off — the seller Availability card is .qq-card.overflow-hidden and sliced the
   calendar in half. Rather than un-clipping those cards permanently (the
   rounding relies on it) or patching each host as it appears, drop the clip
   only while a picker inside is actually open. Bootstrap's utility is
   !important, so this has to be too. */
.qq-card:has(.qq-dt.is-open),
.overflow-hidden:has(.qq-dt.is-open) {
    overflow: visible !important;
}

.qq-dt-pop {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    z-index: 41;
    width: 318px;
    max-width: calc(100vw - 2rem);
    box-sizing: border-box;
    padding: 1rem;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 20px;
    box-shadow: 0 22px 50px rgba(0, 0, 0, 0.22);
    animation: qqDtPop 160ms ease;
}

/* The grab handle belongs to the mobile sheet only. */
.qq-dt-grab {
    display: none;
}

@keyframes qqDtPop {
    from { opacity: 0; transform: translateY(-6px) scale(0.98); }
    to { opacity: 1; transform: none; }
}

.qq-dt-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.6rem;
}

.qq-dt-nav {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border: 1px solid var(--qq-border);
    border-radius: 10px;
    background: var(--qq-card);
    color: var(--qq-text);
    cursor: pointer;
    line-height: 1;
}

.qq-dt-nav:hover,
.qq-dt-title:hover {
    background: var(--qq-mute-bg);
}

.qq-dt-title {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    padding: 0.35rem 0.5rem;
    border: none;
    border-radius: 10px;
    background: transparent;
    color: var(--qq-text);
    font: inherit;
    font-size: 0.905rem;
    font-weight: 700;
    cursor: pointer;
}

.qq-dt-caret {
    font-size: 0.7rem;
    color: var(--qq-text-muted);
}

.qq-dt-dow {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
    margin-bottom: 0.25rem;
}

.qq-dt-dow span {
    text-align: center;
    font-family: 'Space Mono', ui-monospace, monospace;
    font-size: 0.5625rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--qq-text-muted);
}

.qq-dt-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
}

.qq-dt-blank {
    height: 38px;
}

.qq-dt-day {
    height: 38px;
    border: none;
    border-radius: 11px;
    background: transparent;
    color: var(--qq-text);
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}

.qq-dt-day:hover:not(:disabled):not(.on) {
    background: var(--qq-mute-bg);
}

.qq-dt-day:disabled {
    color: var(--qq-text-faint);
    cursor: default;
}

.qq-dt-day.today {
    font-weight: 700;
    box-shadow: inset 0 0 0 1.5px var(--qq-brass);
}

.qq-dt-day.on {
    /* brass-deep, not brass: plain brass measured 4.40:1 against the paper
       label in light mode. Matches the Select2 highlighted row. */
    background: var(--qq-brass-deep);
    color: var(--qq-paper);
    font-weight: 700;
}

.qq-dt-foot {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.7rem;
    padding-top: 0.7rem;
    border-top: 1px solid var(--qq-border);
}

.qq-dt-chip {
    flex: 1 1 auto;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--qq-border);
    border-radius: 999px;
    background: var(--qq-card);
    color: var(--qq-text-body);
    font: inherit;
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.qq-dt-chip:hover:not(:disabled) {
    border-color: var(--qq-brass);
    color: var(--qq-brass-deep);
}

.qq-dt-chip:disabled {
    color: var(--qq-text-faint);
    cursor: default;
}

/* Month/year zoom view */
.qq-dt-years {
    display: flex;
    gap: 0.35rem;
    overflow-x: auto;
    padding-bottom: 0.5rem;
    margin-bottom: 0.5rem;
    scrollbar-width: none;
}

.qq-dt-years::-webkit-scrollbar {
    display: none;
}

.qq-dt-year {
    flex: 0 0 auto;
    padding: 0.3rem 0.7rem;
    border: none;
    border-radius: 999px;
    background: var(--qq-mute-bg);
    color: var(--qq-text-body);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}

.qq-dt-year.on {
    background: var(--qq-ink);
    color: var(--qq-paper);
    font-weight: 700;
}

.qq-dt-months {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.35rem;
}

.qq-dt-month {
    padding: 0.8rem 0;
    border: none;
    border-radius: 11px;
    background: var(--qq-mute-bg);
    color: var(--qq-text-body);
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
}

.qq-dt-month.on {
    background: var(--qq-brass-deep);
    color: var(--qq-paper);
    font-weight: 700;
}

/* Mobile: the popover becomes a bottom sheet. Same markup, and cells grow to
   the 44px hit-target floor the mobile audit set. */
@media (max-width: 767.98px) {
    .qq-dt-backdrop {
        background: rgba(0, 0, 0, 0.32);
    }

    .qq-dt-pop {
        position: fixed;
        top: auto;
        bottom: 0;
        left: 0;
        right: 0;
        width: auto;
        max-width: none;
        border-radius: 22px 22px 0 0;
        border-bottom: none;
        padding: 0.625rem 1.125rem 1.125rem;
        box-shadow: 0 -16px 40px rgba(0, 0, 0, 0.24);
        animation: qqDtSheet 200ms ease;
    }

    .qq-dt-grab {
        display: block;
        width: 38px;
        height: 4px;
        margin: 0 auto 0.75rem;
        border-radius: 999px;
        background: var(--qq-border);
    }

    .qq-dt-day,
    .qq-dt-blank {
        height: 44px;
    }
}

/* Deliberately a short rise rather than a full translateY(100%) slide: the
   resting position must not depend on the animation completing. If frames are
   ever suspended the sheet sits 14px low and stays usable, instead of parked
   entirely off-screen. */
@keyframes qqDtSheet {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .qq-dt-pop {
        animation: none;
    }
}

/* --- Time picker (qq-tp) ---------------------------------------------------------------
   Control 3 of the date/time handoff. Reuses the date picker's field, backdrop
   and popover (.qq-dt-*) so the two controls are the same object with different
   contents; only what's inside the popover is new. Selected fills use
   --qq-brass-deep for the same reason the calendar does: plain brass is 4.40:1
   against a --qq-paper label in light mode. */
.qq-tp-pop {
    width: 252px;
    border-radius: 18px;
    padding: 0.875rem;
}

.qq-tp-top {
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.qq-tp-preview {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem 0.75rem;
    border-radius: 12px;
    background: var(--qq-mute-bg);
    color: var(--qq-text);
    font-size: 1.3125rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Stacked AM/PM, hidden entirely on a 24-hour culture. */
.qq-tp-ampm {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 3px;
    border-radius: 12px;
    background: var(--qq-mute-bg);
}

.qq-tp-ampm button {
    flex: 1 1 auto;
    min-width: 2.5rem;
    border: none;
    border-radius: 9px;
    background: transparent;
    color: var(--qq-text-muted);
    font: inherit;
    font-size: 0.72rem;
    font-weight: 700;
    cursor: pointer;
}

.qq-tp-ampm button.on {
    background: var(--qq-ink);
    color: var(--qq-paper);
}

.qq-tp-label {
    font-family: 'Space Mono', ui-monospace, monospace;
    font-size: 0.5625rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--qq-text-muted);
    margin-bottom: 0.35rem;
}

.qq-tp-hours {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 0.25rem;
    margin-bottom: 0.75rem;
}

.qq-tp-hour {
    padding: 0.5rem 0;
    border: none;
    border-radius: 9px;
    background: var(--qq-mute-bg);
    color: var(--qq-text);
    font: inherit;
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}

.qq-tp-hour:hover:not(.on) {
    background: color-mix(in srgb, var(--qq-brass) 18%, var(--qq-mute-bg));
}

.qq-tp-hour.on {
    background: var(--qq-brass-deep);
    color: var(--qq-paper);
    font-weight: 700;
}

.qq-tp-mins {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.25rem;
    margin-bottom: 0.75rem;
}

.qq-tp-min {
    padding: 0.5rem 0;
    border: none;
    border-radius: 9px;
    background: var(--qq-mute-bg);
    color: var(--qq-text);
    font: inherit;
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}

.qq-tp-min:hover:not(.on) {
    background: color-mix(in srgb, var(--qq-brass) 18%, var(--qq-mute-bg));
}

.qq-tp-min.on {
    background: var(--qq-brass-deep);
    color: var(--qq-paper);
    font-weight: 700;
}

.qq-tp-done {
    width: 100%;
    padding: 0.6rem 0;
    border: none;
    border-radius: 999px;
    background: var(--qq-ink);
    color: var(--qq-paper);
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 700;
    cursor: pointer;
}

/* More minute chips than fit in four columns wrap to a comfortable grid. */
.qq-tp-mins:has(> :nth-child(5)) {
    grid-template-columns: repeat(6, 1fr);
}

@media (max-width: 767.98px) {
    .qq-tp-pop {
        width: auto;
    }

    .qq-tp-hour,
    .qq-tp-min {
        padding: 0.6875rem 0;
    }
}

/* --- Date range (qq-rp) ----------------------------------------------------------------
   Control 2 of the date/time handoff: segmented presets fused with the range
   calendar. Reuses the date picker's field, backdrop, popover and day grid
   (.qq-dt-*); only the segmented control, the day-count badge, the phase row,
   the range fill and the Apply pill are new. */
.qq-rp {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    /* As a flex item this defaults to min-width:auto, i.e. "never shrink below
       my content" — and the content is a preset track wider than a phone. That
       floor propagated outwards and made the whole control, trigger field
       included, hang off the right edge. Letting it shrink is what gives the
       track's own max-width/overflow a real bound to scroll within. */
    min-width: 0;
}

.qq-rp-anchor {
    position: relative;
}

.qq-rp-seg {
    display: inline-flex;
    gap: 2px;
    padding: 4px;
    border-radius: 999px;
    background: var(--qq-mute-bg);
}

.qq-rp-seg button {
    border: none;
    border-radius: 999px;
    background: transparent;
    color: var(--qq-text-body);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 0.4rem 0.8rem;
    white-space: nowrap;
    cursor: pointer;
}

.qq-rp-seg button:hover:not(.on) {
    color: var(--qq-text);
}

.qq-rp-seg button.on {
    background: var(--qq-ink);
    color: var(--qq-paper);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}

/* Space Mono day count on the trigger, e.g. 30D. */
.qq-rp-count {
    flex-shrink: 0;
    font-family: 'Space Mono', ui-monospace, monospace;
    font-size: 0.625rem;
    letter-spacing: 0.04em;
    color: var(--qq-text-muted);
    font-variant-numeric: tabular-nums;
}

/* Which end the next tap sets. */
.qq-rp-phase {
    display: flex;
    gap: 0.35rem;
    margin-bottom: 0.6rem;
}

.qq-rp-phase span {
    flex: 1 1 0;
    text-align: center;
    padding: 0.3rem 0.5rem;
    border-radius: 999px;
    background: var(--qq-mute-bg);
    color: var(--qq-text-muted);
    font-size: 0.75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.qq-rp-phase span.on {
    background: var(--qq-brass-deep);
    color: var(--qq-paper);
}

/* Range fill: the ends keep the pill, the days between square off so the run
   reads as one band. .on already supplies the brass-deep fill. */
.qq-dt-day.in-range {
    background: color-mix(in srgb, var(--qq-brass) 16%, var(--qq-card));
    border-radius: 0;
}

.qq-dt-day.range-start {
    border-radius: 11px 0 0 11px;
}

.qq-dt-day.range-end {
    border-radius: 0 11px 11px 0;
}

.qq-dt-day.range-start.range-end {
    border-radius: 11px;
}

.qq-rp-apply {
    width: 100%;
    margin-top: 0.7rem;
    padding: 0.6rem 0;
    border: none;
    border-radius: 999px;
    background: var(--qq-ink);
    color: var(--qq-paper);
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 700;
    cursor: pointer;
}

@media (max-width: 767.98px) {
    .qq-rp {
        width: 100%;
    }

    .qq-rp-seg {
        width: 100%;
        justify-content: space-between;
    }

    .qq-rp-anchor {
        flex: 1 1 100%;
    }
}

/* --- Booking day + slot strip (handoff control 4) ---------------------------------------
   Availability dots on the day cards, slots grouped by period, and a summary of
   what's chosen. Extends the existing .qq-day / .qq-slot rules above. */
.qq-day {
    position: relative;
}

/* 5px dot: green when the day has openings, muted when it's full. Colour isn't
   the only signal — a full card also dims and its aria-label says so. */
.qq-day .dot {
    display: block;
    width: 5px;
    height: 5px;
    margin: 0.35rem auto 0;
    border-radius: 50%;
    background: var(--qq-ok-fg);
}

.qq-day .dot.none {
    background: var(--qq-text-faint);
}

.qq-day.full {
    opacity: 0.55;
}

.qq-day.active .dot {
    background: var(--qq-paper);
}

.qq-daypick-legend {
    display: flex;
    gap: 1rem;
    margin: -1.5rem 0 1.75rem;
    font-size: 0.72rem;
    color: var(--qq-text-muted);
}

.qq-daypick-legend span {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.qq-daypick-legend .dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--qq-ok-fg);
    flex-shrink: 0;
}

.qq-daypick-legend .dot.none {
    background: var(--qq-text-faint);
}

.qq-slot-group {
    margin-bottom: 1rem;
}

.qq-slot-grouphead {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.45rem;
    font-family: 'Space Mono', ui-monospace, monospace;
    font-size: 0.5625rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--qq-text-muted);
}

.qq-slot-grouphead .n {
    font-variant-numeric: tabular-nums;
    color: var(--qq-text-faint);
}

/* What's chosen, restated once so the buyer doesn't have to re-read the chips. */
.qq-slot-summary {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
    padding: 0.7rem 0.9rem;
    background: var(--qq-card);
    border: 1.5px solid var(--qq-brass);
    border-radius: 14px;
}

.qq-slot-summary .when {
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--qq-text);
    font-variant-numeric: tabular-nums;
}

.qq-slot-summary .yours {
    font-size: 0.8rem;
    color: var(--qq-brass-deep);
    font-variant-numeric: tabular-nums;
}

/* In-page section anchors: keep headings clear of the sticky navbar when scrolled to. */
#menu,
#services {
    scroll-margin-top: 90px;
}

/* --- Toasts (action feedback) ----------------------------------------------------------------- */
/* Cart basket icon + item-count badge in the nav. */
.qq-cart-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.4rem 0.55rem;
}

.qq-cart-badge {
    position: absolute;
    top: 0.05rem;
    right: 0.05rem;
    min-width: 1.05rem;
    height: 1.05rem;
    padding: 0 0.28rem;
    border-radius: 999px;
    background: var(--qq-gold-bright);
    color: #23201a;
    font-size: 0.66rem;
    font-weight: 700;
    line-height: 1.05rem;
    text-align: center;
    /* --qq-surface is never defined; the #fff fallback left a white halo
       around the badge on the dark navbar. Paper matches the bar behind. */
    box-shadow: 0 0 0 2px var(--qq-paper, #fff);
}

/* --- Mini-cart drawer: slide-out panel opened from the basket icon ---------- */
.qq-mc {
    position: fixed;
    inset: 0;
    z-index: 1090;
    pointer-events: none;
    /* The closed drawer sits translated off-screen; without clipping it still
       counts toward scrollable overflow and gives phones a sideways wobble. */
    overflow: hidden;
}

.qq-mc.open {
    pointer-events: auto;
}

.qq-mc-lock {
    overflow: hidden;
}

.qq-mc-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(23, 21, 18, 0.45);
    opacity: 0;
    transition: opacity 0.25s ease;
}

.qq-mc.open .qq-mc-backdrop {
    opacity: 1;
}

.qq-mc-drawer {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: min(26rem, 100vw);
    display: flex;
    flex-direction: column;
    background: var(--qq-card);
    border-radius: 18px 0 0 18px;
    box-shadow: -18px 0 48px rgba(23, 21, 18, 0.25);
    transform: translateX(105%);
    transition: transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.qq-mc.open .qq-mc-drawer {
    transform: none;
}

.qq-mc-head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--qq-border-soft, #ece5d6);
}

.qq-mc-title {
    font-weight: 700;
    font-size: 1.05rem;
}

.qq-mc-x {
    margin-left: auto;
    border: none;
    background: none;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    color: var(--qq-text-muted, #6f6757);
    padding: 0.15rem 0.4rem;
    border-radius: 8px;
}

.qq-mc-x:hover {
    background: var(--qq-border-soft, #ece5d6);
}

.qq-mc-body {
    flex: 1;
    overflow-y: auto;
    padding: 1rem 1.25rem 1.5rem;
}

.qq-mc-body.qq-mc-loading {
    opacity: 0.55;
}

.qq-mc-empty {
    text-align: center;
    padding: 3.5rem 1rem;
    color: var(--qq-text-muted, #6f6757);
}

.qq-mc-empty svg {
    opacity: 0.4;
    margin-bottom: 0.75rem;
}

.qq-mc-empty p {
    margin-bottom: 1.25rem;
}

.qq-mc-group {
    margin-bottom: 1.5rem;
}

.qq-mc-store {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--qq-border-soft, #ece5d6);
    margin-bottom: 0.35rem;
}

.qq-mc-store a {
    font-weight: 700;
    color: var(--qq-text, #171512);
    text-decoration: none;
}

.qq-mc-subtotal {
    margin-left: auto;
    font-weight: 700;
    font-size: 0.9rem;
}

.qq-mc-line {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--qq-border-soft, #ece5d6);
}

.qq-mc-line img,
.qq-mc-noimg {
    width: 52px;
    height: 52px;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
    background: var(--qq-border-soft, #ece5d6);
}

.qq-mc-off img {
    opacity: 0.5;
}

.qq-mc-off .qq-mc-name {
    text-decoration: line-through;
    color: var(--qq-text-faint, #a89f8d);
}

.qq-mc-info {
    flex: 1;
    min-width: 0;
}

.qq-mc-name {
    font-weight: 600;
    font-size: 0.9rem;
}

.qq-mc-sel {
    font-size: 0.78rem;
    color: var(--qq-text-muted, #6f6757);
}

.qq-mc-controls {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.4rem;
}

.qq-mc-stepper {
    gap: 0.15rem;
}

.qq-mc-stepper button {
    width: 1.6rem;
    height: 1.6rem;
    font-size: 0.85rem;
}

.qq-mc-stepper .qty {
    min-width: 1.4rem;
    text-align: center;
    font-size: 0.88rem;
}

.qq-mc-price {
    font-weight: 700;
    font-size: 0.88rem;
    margin-left: auto;
}

.qq-mc-remove button {
    border: none;
    background: none;
    color: var(--qq-text-faint, #a89f8d);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.1rem 0.3rem;
    border-radius: 6px;
}

.qq-mc-remove button:hover {
    color: var(--qq-bad-fg, #9a3b26);
    background: var(--qq-border-soft, #ece5d6);
}

.qq-mc-checkout {
    margin-top: 0.85rem;
}

.qq-mc-viewfull {
    display: block;
    text-align: center;
    font-size: 0.88rem;
    font-weight: 600;
    padding: 0.4rem 0 0.2rem;
}

/* Toasts: a prominent top-right stack, newest on top, auto-dismiss with a
   timer bar. High z-index so they sit above modals and drawers. */
.qq-toast-host {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 1200;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    width: min(23rem, calc(100vw - 2rem));
    pointer-events: none;
}

.qq-toast {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 0.85rem 2.2rem 0.85rem 0.9rem;
    border-radius: 14px;
    /* --qq-card, not the never-defined --qq-surface: the #fff fallback left
       dark mode with light text on a white toast. */
    background: var(--qq-card, #fff);
    border: 1px solid var(--qq-border, #e7e1d8);
    box-shadow: 0 14px 40px rgba(23, 21, 18, 0.22), 0 2px 6px rgba(23, 21, 18, 0.08);
    overflow: hidden;
    pointer-events: auto;
    animation: qq-toast-in 0.32s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Coloured left accent rail keyed to the outcome. */
.qq-toast::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: var(--qq-accent, #1f7a4d);
}

.qq-toast-icon {
    flex: 0 0 auto;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: 0.85rem;
    font-weight: 800;
    color: #fff;
    background: var(--qq-accent, #1f7a4d);
    margin-top: 1px;
}

.qq-toast-text {
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--qq-text, #211d18);
    word-break: break-word;
}

.qq-toast-close {
    position: absolute;
    top: 0.4rem;
    right: 0.5rem;
    border: 0;
    background: transparent;
    color: var(--qq-text-muted, #7a736a);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.25rem;
    border-radius: 6px;
}
.qq-toast-close:hover { background: color-mix(in srgb, var(--qq-text, #211d18) 8%, transparent); }

/* Auto-dismiss timer bar. */
.qq-toast-bar {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 3px;
    width: 100%;
    background: var(--qq-accent, #1f7a4d);
    transform-origin: left;
    animation: qq-toast-timer 4.5s linear forwards;
}

.qq-toast-ok { --qq-accent: #1f7a4d; }
.qq-toast-bad { --qq-accent: #c0392b; }

@keyframes qq-toast-in {
    from { opacity: 0; transform: translateX(28px) scale(0.98); }
    to { opacity: 1; transform: translateX(0) scale(1); }
}

@keyframes qq-toast-timer {
    from { transform: scaleX(1); }
    to { transform: scaleX(0); }
}

@media (prefers-reduced-motion: reduce) {
    .qq-toast { animation: none; }
    .qq-toast-bar { animation: none; }
}

/* --- Review star input (row-reversed radios so hover/checked colors leading stars) ----------- */
.sf-stars {
    display: inline-flex;
    flex-direction: row-reverse;
    gap: 0.15rem;
    margin-bottom: 0.5rem;
}

.sf-stars input {
    position: absolute;
    opacity: 0;
    width: 0;
}

.sf-stars label {
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    color: color-mix(in srgb, var(--sf-text, var(--qq-text)) 25%, transparent);
    transition: color 0.1s ease;
}

.sf-stars label:hover,
.sf-stars label:hover ~ label,
.sf-stars input:checked ~ label {
    color: var(--sf-accent, var(--qq-brass));
}

/* Storefront toolbar filter selects, themed like the search input. */
.sf-filter-select {
    border: 1px solid color-mix(in srgb, var(--sf-text) 22%, transparent);
    background: color-mix(in srgb, var(--sf-bg) 88%, var(--sf-text) 4%);
    color: var(--sf-text);
    border-radius: 999px;
    padding: 0.5rem 0.9rem;
    font: inherit;
    font-size: 0.9rem;
    max-width: 11rem;
}

/* select2 clones the native select's resolved width, but its own chrome
   (padding + arrow) is wider than a native select's - the copied width
   showed "All categ...". Auto beats the inline width it sets, so the
   enhanced control sizes to its label instead. */
.sf-tabbar .sf-search .select2-container {
    width: auto !important;
    min-width: 8.5rem;
    flex-shrink: 0;
}

/* Clickable dashboard summary tiles: whole card is a quick action. */
.qq-tile-link {
    display: block;
    color: inherit;
    text-decoration: none;
    height: 100%;
}

.qq-tile-link:hover {
    color: inherit;
    text-decoration: none;
}

.qq-tile-link > .qq-card {
    height: 100%;
    transition: border-color 0.12s ease, transform 0.12s ease, box-shadow 0.12s ease;
}

.qq-tile-link:hover > .qq-card {
    border-color: var(--qq-brass);
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.07);
}

.admin-shell .qq-tile-link:hover > .qq-card {
    border-color: var(--qq-admin-muted);
}

/* QuickGrid tables in kit style (search/sort/paginate detail pages). */
.qq-grid table {
    width: 100%;
    border-collapse: collapse;
}

.qq-grid th {
    text-align: left;
    padding: 0.6rem 1.25rem;
    font-size: 0.69rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--qq-text-faint);
    border-bottom: 1px solid var(--qq-border-soft);
}

.qq-grid th button.column-title {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.qq-grid td {
    padding: 0.8rem 1.25rem;
    border-top: 1px solid var(--qq-border-soft);
    font-size: 0.88rem;
    vertical-align: middle;
}

.qq-grid tbody tr:hover td {
    background: color-mix(in srgb, var(--qq-shell) 55%, transparent);
}

.admin-shell .qq-grid th {
    color: var(--qq-admin-faint);
    border-color: #eceef0;
}

.admin-shell .qq-grid td {
    border-color: var(--qq-admin-divider);
}

.admin-shell .qq-grid tbody tr:hover td {
    background: var(--qq-admin-input);
}

.qq-grid-pager {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.9rem;
    padding: 0.65rem 1.25rem;
    border-top: 1px solid var(--qq-border-soft);
    font-size: 0.82rem;
    color: var(--qq-text-muted);
}

.admin-shell .qq-grid-pager {
    border-color: var(--qq-admin-divider);
    color: var(--qq-admin-muted);
}

/* Admin sign-in / 2FA / security-setup cards (shared by the admin-login layout pages). */
.admin-login-card {
    background: #fff;
    border-radius: 12px;
    padding: 2rem 2rem 1.5rem;
    box-shadow: 0 4px 32px rgba(0,0,0,.25);
}

.admin-login-card-head { margin-bottom: 1.5rem; }

.admin-login-title {
    font-size: 1.2rem;
    font-weight: 700;
    color: #171512;
    margin: 0 0 .25rem;
}

.admin-login-subtitle {
    font-size: .83rem;
    color: #6b6b6b;
    margin: 0;
}

.admin-login-label {
    display: block;
    font-size: .83rem;
    font-weight: 600;
    color: #374151;
    margin-bottom: .3rem;
}

.admin-login-input {
    display: block;
    width: 100%;
    padding: .55rem .75rem;
    font-size: .95rem;
    border: 1px solid #d1d5db;
    border-radius: 6px;
    background: #f9fafb;
    color: #111827;
    outline: none;
    transition: border-color .15s;
}

.admin-login-input:focus {
    border-color: var(--qq-admin-bar);
    background: #fff;
    box-shadow: 0 0 0 3px rgba(32,38,45,.12);
}

.admin-login-forgot {
    font-size: .78rem;
    font-weight: 600;
    color: #6b7280;
    text-decoration: none;
}

.admin-login-forgot:hover {
    color: #374151;
    text-decoration: underline;
}

.admin-login-btn {
    display: block;
    width: 100%;
    padding: .65rem 1rem;
    background: var(--qq-admin-bar);
    color: #fff;
    font-size: .95rem;
    font-weight: 600;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    transition: background .15s;
}

.admin-login-btn:hover { background: #2c333b; }

.admin-login-back {
    text-align: center;
    margin: 1.25rem 0 0;
    font-size: .8rem;
}

.admin-login-back a {
    color: #9aa4ae;
    text-decoration: none;
}

.admin-login-back a:hover {
    color: #c9d1d9;
    text-decoration: underline;
}

/* 2FA setup: the authenticator secret key, easy to copy into an app. */
.admin-login-qr {
    display: flex;
    justify-content: center;
    margin: .35rem 0 .5rem;
}

.admin-login-qr img {
    width: 200px;
    height: 200px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 8px;
    background: #fff;
}

.admin-login-key {
    display: block;
    font-family: var(--qq-admin-mono, ui-monospace, monospace);
    font-size: 1rem;
    letter-spacing: .12em;
    background: #f3f4f6;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    padding: .6rem .75rem;
    margin: .35rem 0 .75rem;
    word-break: break-all;
    color: #111827;
}

.admin-login-codes {
    list-style: none;
    padding: .75rem 1rem;
    margin: .5rem 0 1rem;
    background: #f9fafb;
    border: 1px dashed #d1d5db;
    border-radius: 8px;
    columns: 2;
    font-family: var(--qq-admin-mono, ui-monospace, monospace);
    font-size: .9rem;
    color: #111827;
}

/* Honeypot wrapper for the auth forms: parked off-screen rather than
   display:none (which naive bots detect) and removed from the tab order. */
.qq-hp {
    position: absolute;
    left: -9999px;
    top: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Phones/tablets: data tables are wider than the screen, so the card scrolls
   horizontally instead of clipping columns (the markup's .overflow-hidden
   utility would otherwise cut them off unreachably). A min-width keeps the
   columns readable while the user swipes. */
@media (max-width: 900px) {
    .qq-grid,
    .qq-grid.overflow-hidden {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    .qq-grid table {
        min-width: 640px;
    }

    .qq-grid-pager {
        padding: 0.65rem 0.9rem;
    }

    /* Tighter admin chrome on small screens; the search box goes full width
       so it's a comfortable touch target. */
    .admin-shell .admin-content .admin-page-bar {
        padding: 0.85rem 1rem;
        gap: 0.5rem 0.9rem;
    }

    .admin-shell .admin-content .admin-page-body {
        padding: 1rem 0.9rem 2.25rem;
    }

    .admin-shell .admin-content .admin-page-hint {
        display: none;
    }

    .admin-shell .admin-content .admin-search {
        flex: 1 1 100%;
    }

    .admin-shell .admin-content .admin-search input {
        width: 100%;
    }
}

/* Flag in the locale switch. */
.qq-flag {
    width: 20px;
    height: 10px;
    border-radius: 2px;
    vertical-align: -1px;
    margin-right: 0.25rem;
}

/* ---------------------------------------------------------------------------
   Admin mini sidebar. js/admin-sidebar.js toggles `qq-admin-mini` on <html>
   (persisted in localStorage); these rules live here because scoped CSS
   cannot match an ancestor of the layout component. Desktop only — under
   900px the sidebar already collapses to a top block.
--------------------------------------------------------------------------- */
@media (min-width: 901px) {
    html.qq-admin-mini .admin-sidebar {
        width: 76px;
    }

    html.qq-admin-mini .admin-sidebar-head {
        flex-direction: column;
        gap: 0.7rem;
        padding: 1.1rem 0.6rem 0.9rem;
    }

    html.qq-admin-mini .admin-nav-toggle {
        margin-left: 0;
    }

    html.qq-admin-mini .admin-nav-toggle svg {
        transform: rotate(180deg);
    }

    html.qq-admin-mini .admin-brand-text,
    html.qq-admin-mini .admin-nav-text,
    html.qq-admin-mini .admin-sidebar-meta,
    html.qq-admin-mini .admin-user-name,
    html.qq-admin-mini .admin-logout {
        display: none;
    }

    /* group headings become thin dividers so the grouping stays visible */
    html.qq-admin-mini .admin-nav-group {
        height: 1px;
        padding: 0;
        margin: 0.55rem 0.6rem;
        background: #332e24;
        overflow: hidden;
        font-size: 0;
    }

    html.qq-admin-mini .admin-nav a {
        justify-content: center;
        padding: 0.62rem 0;
    }

    /* the v3 active bar/marker need the full-width rail; icon-only mode keeps
       just the active background + icon tint */
    html.qq-admin-mini .admin-nav a.active::before,
    html.qq-admin-mini .admin-nav a.active::after {
        display: none;
    }

    html.qq-admin-mini .admin-user-card {
        justify-content: center;
        padding: 0.45rem;
    }
}

/* ---------------------------------------------------------------------------
   Floating help launcher (bottom-right on public, buyer, and seller pages).
   Static markup toggled by js/help-launcher.js — no circuit involved.
--------------------------------------------------------------------------- */
.qq-help-launcher {
    position: fixed;
    right: max(1.25rem, env(safe-area-inset-right));
    bottom: max(1.25rem, env(safe-area-inset-bottom));
    z-index: 1040; /* under toasts (1080), above page content */
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.75rem;
}

.qq-help-fab {
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 50%;
    border: none;
    background: var(--qq-ink);
    color: var(--qq-gold-bright);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 6px 18px rgba(23, 21, 18, 0.28);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.qq-help-fab:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 24px rgba(23, 21, 18, 0.32);
}

/* Dark mode: the ink fab inverts to an ivory disc, where gold-bright is
   illegible — use the light theme's deep brass for the glyph instead. */
html[data-theme="dark"] .qq-help-fab {
    color: #9a6b1e;
}

.qq-help-fab svg { width: 1.5rem; height: 1.5rem; }
.qq-help-fab .qq-help-fab-close { display: none; }
.qq-help-fab.open .qq-help-fab-open { display: none; }
.qq-help-fab.open .qq-help-fab-close { display: block; }

.qq-help-panel {
    width: min(21rem, calc(100vw - 2rem));
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 0.9rem;
    box-shadow: 0 14px 40px rgba(23, 21, 18, 0.22);
    overflow: hidden;
}

.qq-help-panel-head {
    padding: 0.9rem 1.1rem 0.65rem;
    background: var(--qq-brass-tint);
    border-bottom: 1px solid var(--qq-border-soft);
}

.qq-help-panel-hint {
    font-size: 0.82rem;
    color: var(--qq-text-muted);
}

.qq-help-panel-search {
    display: flex;
    gap: 0.5rem;
    padding: 0.75rem 1.1rem;
}

.qq-help-panel-search .qq-input { flex: 1; min-width: 0; }

.qq-help-panel-links {
    display: flex;
    flex-direction: column;
    padding: 0 1.1rem 0.6rem;
}

.qq-help-panel-links a {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.4rem 0;
    color: var(--qq-text-body);
    text-decoration: none;
    font-size: 0.9rem;
    border-bottom: 1px solid var(--qq-border-soft);
}

.qq-help-panel-links a:hover { color: var(--qq-brass-deep); }

.qq-help-panel-links a.qq-help-panel-all {
    border-bottom: none;
    color: var(--qq-brass);
    font-weight: 600;
}

.qq-help-panel-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.7rem 1.1rem;
    border-top: 1px solid var(--qq-border-soft);
    background: var(--qq-shell);
}

@media (max-width: 575px) {
    .qq-help-fab { width: 2.9rem; height: 2.9rem; }
    .qq-help-fab svg { width: 1.3rem; height: 1.3rem; }
}

/* ---------------------------------------------------------------------------
   Account settings (Account/Manage) — qq-mng design per handoff.
   Border-defined white cards on paper; ink pills; brass accents.
--------------------------------------------------------------------------- */
.qq-mng-page { max-width: 1100px; margin: 0 auto; padding: 0.5rem 0 3rem; }

/* Phones: give the manage cards breathing room at the screen edges. */
@media (max-width: 640px) {
    .qq-mng-page { padding: 0.5rem 0.75rem 3rem; }
}

.qq-mng-eyebrow {
    font-family: 'Space Mono', Consolas, monospace;
    font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--qq-text-faint); margin-bottom: 4px;
}

.qq-mng-title { font-size: 30px; font-weight: 700; letter-spacing: -0.035em; margin: 0 0 26px; }
.qq-mng-dot { color: var(--qq-gold-bright); }

.qq-mng-grid { display: grid; grid-template-columns: 280px 1fr; gap: 36px; align-items: start; }
.qq-mng-content { max-width: 720px; display: flex; flex-direction: column; gap: 20px; }

@media (max-width: 900px) {
    .qq-mng-grid { grid-template-columns: 1fr; }
}

/* Rail */
.qq-mng-rail { background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 18px; padding: 12px; }
.qq-mng-user { display: flex; gap: 10px; align-items: center; padding: 8px 10px 14px; border-bottom: 1px solid var(--qq-border-soft); margin-bottom: 8px; }
.qq-mng-avatar {
    width: 40px; height: 40px; border-radius: 50%; background: #41597a; color: #fff;
    display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 16px; flex: none;
}
.qq-mng-user-meta { min-width: 0; display: flex; flex-direction: column; }
.qq-mng-user-name { font-size: 14px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qq-mng-user-email { font-size: 12px; color: var(--qq-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.qq-mng-nav { display: flex; flex-direction: column; gap: 2px; }
.qq-mng-nav-group {
    font-family: 'Space Mono', Consolas, monospace;
    font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--qq-text-faint); padding: 12px 12px 6px;
}
.qq-mng-nav a {
    display: flex; align-items: center; gap: 8px;
    font-size: 13.5px; font-weight: 500; color: var(--qq-text-body); text-decoration: none;
    padding: 9px 12px; border-radius: 10px;
}
.qq-mng-nav a:hover { background: var(--qq-paper); }
.qq-mng-nav a.active { background: var(--qq-ink); color: var(--qq-paper); font-weight: 600; }
.qq-mng-chip {
    margin-left: auto; background: var(--qq-brass-tint); color: var(--qq-brass);
    font-size: 10.5px; font-weight: 700; padding: 2px 8px; border-radius: 999px;
}
.qq-mng-nav a.active .qq-mng-chip { background: #3a352c; color: #d9a94e; }

/* Status banners */
.qq-mng-status {
    display: flex; align-items: center; gap: 10px;
    border-radius: 14px; padding: 12px 16px; font-size: 13.5px; font-weight: 600;
}
.qq-mng-status svg { width: 18px; height: 18px; flex: none; }
.qq-mng-status-success { background: var(--qq-ok-bg); border: 1px solid color-mix(in srgb, var(--qq-ok-fg) 25%, transparent); color: var(--qq-ok-fg); }
.qq-mng-status-danger  { background: var(--qq-bad-bg); border: 1px solid color-mix(in srgb, var(--qq-bad-fg) 25%, transparent); color: var(--qq-bad-fg); }
.qq-mng-status-warn    { background: var(--qq-warn-bg); border: 1px solid color-mix(in srgb, var(--qq-warn-fg) 25%, transparent); color: var(--qq-brass-deep); }

/* Cards */
.qq-mng-card { background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 18px; padding: 26px 28px; }
.qq-mng-card-title { font-size: 17px; font-weight: 700; letter-spacing: -0.02em; margin: 0 0 4px; }
.qq-mng-help { font-size: 13px; color: var(--qq-text-muted); margin: 0 0 18px; }
.qq-mng-card-danger { border-color: color-mix(in srgb, var(--qq-bad-fg) 25%, transparent); }
.qq-mng-card-danger .qq-mng-card-title { color: var(--qq-bad-fg); }
.qq-mng-divider { border: none; border-top: 1px solid var(--qq-border-soft); margin: 20px 0; }

/* Fields */
.qq-mng-field { margin-bottom: 16px; }
.qq-mng-label { display: block; font-size: 12.5px; font-weight: 600; color: var(--qq-text-body); margin-bottom: 6px; }
.qq-mng-input {
    width: 100%; border: 1px solid var(--qq-border); border-radius: 12px;
    padding: 12px 14px; font-size: 14px; background: var(--qq-card); color: var(--qq-text);
}
.qq-mng-input:focus { outline: none; border-color: #c9bfa9; }
.qq-mng-hint { font-size: 12px; color: var(--qq-text-faint); margin-top: 6px; }
.qq-mng-readonly { position: relative; }
.qq-mng-readonly .qq-mng-input { background: var(--qq-paper); border-color: var(--qq-border-soft); color: var(--qq-text-muted); padding-right: 40px; }
.qq-mng-readonly svg {
    position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
    width: 15px; height: 15px; color: var(--qq-text-faint);
}
.qq-mng-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.qq-mng-row-address { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 16px; }
@media (max-width: 640px) { .qq-mng-row-2, .qq-mng-row-address { grid-template-columns: 1fr; } }
.qq-mng-content .validation-message, .qq-mng-content .text-danger { font-size: 12.5px; color: var(--qq-bad-fg); }

/* Buttons */
.qq-mng-btn {
    display: inline-flex; align-items: center; gap: 8px;
    background: var(--qq-ink); color: var(--qq-paper); border: 1px solid var(--qq-ink);
    font-size: 14px; font-weight: 600; padding: 12px 26px; border-radius: 999px; cursor: pointer;
    text-decoration: none;
}
.qq-mng-btn:hover { background: color-mix(in srgb, var(--qq-ink) 85%, var(--qq-paper)); border-color: color-mix(in srgb, var(--qq-ink) 85%, var(--qq-paper)); color: var(--qq-paper); }
.qq-mng-btn-ghost { background: var(--qq-card); color: var(--qq-text); border-color: var(--qq-border); }
.qq-mng-btn-ghost:hover { background: var(--qq-card); color: var(--qq-text); border-color: #c9bfa9; }
.qq-mng-btn-danger { background: #c0392b; border-color: #c0392b; color: #fff; }
.qq-mng-btn-danger:hover { background: #a53125; border-color: #a53125; color: #fff; }
.qq-mng-btn-danger-outline { background: var(--qq-card); border-color: color-mix(in srgb, var(--qq-bad-fg) 25%, transparent); color: var(--qq-bad-fg); }
.qq-mng-btn-danger-outline:hover { background: var(--qq-bad-bg); border-color: color-mix(in srgb, var(--qq-bad-fg) 30%, transparent); color: var(--qq-bad-fg); }
.qq-mng-actions { display: flex; justify-content: flex-end; align-items: center; gap: 12px; margin-top: 8px; }
.qq-mng-link { font-size: 12.5px; font-weight: 600; color: var(--qq-brass); text-decoration: none; }
.qq-mng-link:hover { color: var(--qq-brass-deep); }
.qq-mng-link-danger { color: var(--qq-bad-fg); }
.qq-mng-link-danger:hover { color: color-mix(in srgb, var(--qq-bad-fg) 85%, var(--qq-text)); }

/* Pills / chips */
.qq-mng-pill {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 11.5px; font-weight: 700; padding: 4px 10px; border-radius: 999px;
}
.qq-mng-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.qq-mng-pill-ok { background: var(--qq-ok-bg); color: var(--qq-ok-fg); }
.qq-mng-pill-warn { background: var(--qq-warn-bg); color: var(--qq-brass); }
.qq-mng-pill-warn .dot { background: color-mix(in srgb, var(--qq-brass) 50%, var(--qq-gold-bright)); }

/* Icon tiles + list rows */
.qq-mng-tile {
    width: 42px; height: 42px; border-radius: 12px; background: var(--qq-mute-bg);
    display: flex; align-items: center; justify-content: center; flex: none; color: var(--qq-text);
}
.qq-mng-tile svg { width: 20px; height: 20px; }
.qq-mng-item { display: flex; align-items: center; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--qq-border-soft); }
.qq-mng-item:last-child { border-bottom: none; }
.qq-mng-item:hover { background: var(--qq-paper); }
.qq-mng-item-name { font-size: 14.5px; font-weight: 700; }
.qq-mng-item-meta { font-size: 12.5px; color: var(--qq-text-muted); }
.qq-mng-locked-strip {
    display: flex; align-items: center; gap: 10px;
    background: var(--qq-paper); border-radius: 12px; padding: 12px 14px;
    font-size: 12.5px; color: var(--qq-text-muted); margin-top: 14px;
}
.qq-mng-locked-strip svg { width: 15px; height: 15px; flex: none; }

/* Verified-buyer hero + checklist + OTP */
.qq-mng-hero {
    background: #171512; color: #faf8f4; border-radius: 18px; padding: 26px 28px;
    display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
}
.qq-mng-hero-shield {
    width: 54px; height: 54px; border-radius: 50%; background: #d9a94e; color: #171512;
    display: flex; align-items: center; justify-content: center; flex: none;
}
.qq-mng-hero-shield svg { width: 26px; height: 26px; }
.qq-mng-hero-title { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; margin: 0; }
.qq-mng-hero-title .qq-mng-dot { color: #d9a94e; }
.qq-mng-hero-sub { font-size: 13px; color: #a39a88; margin: 4px 0 0; max-width: 30rem; }
.qq-mng-hero-progress { margin-left: auto; text-align: right; }
.qq-mng-hero-progress-label {
    font-family: 'Space Mono', Consolas, monospace;
    font-size: 10.5px; letter-spacing: 0.1em; color: #a39a88; margin-bottom: 6px;
}
.qq-mng-hero-count { font-size: 18px; font-weight: 700; color: #d9a94e; }
.qq-mng-hero-bar { width: 120px; height: 6px; border-radius: 999px; background: #3a352c; overflow: hidden; margin-top: 6px; }
.qq-mng-hero-bar span { display: block; height: 100%; background: #d9a94e; border-radius: 999px; }

.qq-mng-check { display: flex; align-items: center; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--qq-border-soft); }
.qq-mng-check:last-child { border-bottom: none; }
.qq-mng-check-dot {
    width: 26px; height: 26px; border-radius: 50%; flex: none;
    display: flex; align-items: center; justify-content: center;
    border: 1.5px solid #d3cbb9; color: transparent;
}
.qq-mng-check-dot.done { background: #d9a94e; border-color: #d9a94e; color: #171512; }
.qq-mng-check-dot svg { width: 14px; height: 14px; }
.qq-mng-check-label { font-size: 14px; font-weight: 600; }
.qq-mng-check-sub { font-size: 12.5px; color: var(--qq-text-muted); }
.qq-mng-check .qq-mng-link { margin-left: auto; }

.qq-mng-otp { display: flex; gap: 8px; }
.qq-mng-otp input {
    width: 46px; height: 54px; border: 1px solid var(--qq-border); border-radius: 12px;
    text-align: center; font-family: 'Space Mono', Consolas, monospace; font-size: 20px; font-weight: 700;
}
.qq-mng-otp input:focus { outline: none; border-color: #c9bfa9; }

/* Password strength meter */
.qq-mng-strength { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.qq-mng-strength span { flex: 1; height: 5px; border-radius: 999px; background: var(--qq-mute-bg); }
.qq-mng-strength span.on-1 { background: var(--qq-brass); }
.qq-mng-strength span.on-2 { background: #b0801f; }
.qq-mng-strength span.on-3 { background: #c69537; }
.qq-mng-strength span.on-4 { background: var(--qq-gold-bright); }
.qq-mng-strength-label { font-size: 12px; font-weight: 700; color: var(--qq-brass); flex: none; }

/* Authenticator setup steps + manual key + recovery codes */
.qq-mng-step { display: flex; gap: 16px; padding: 20px 0; border-bottom: 1px solid var(--qq-border-soft); }
.qq-mng-step:last-child { border-bottom: none; }
.qq-mng-step-n {
    width: 28px; height: 28px; border-radius: 50%; background: var(--qq-ink); color: var(--qq-paper);
    display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; flex: none;
}
.qq-mng-qr { width: 168px; height: 168px; border: 1px solid var(--qq-border); border-radius: 12px; padding: 8px; background: #fff; }
.qq-mng-qr img { width: 100%; height: 100%; }
.qq-mng-key {
    display: inline-block; font-family: 'Space Mono', Consolas, monospace; font-size: 14px;
    background: var(--qq-mute-bg); border-radius: 10px; padding: 8px 12px; word-break: break-all;
}
.qq-mng-code-input { font-family: 'Space Mono', Consolas, monospace; max-width: 180px; }

.qq-mng-ink-card { background: #171512; color: #faf8f4; border-radius: 18px; padding: 26px 28px; }
.qq-mng-ink-card .qq-mng-card-title { color: #faf8f4; }
.qq-mng-once {
    font-family: 'Space Mono', Consolas, monospace; font-size: 10.5px; letter-spacing: 0.1em;
    color: #d9a94e; border: 1px solid #3a352c; border-radius: 999px; padding: 3px 10px;
}
.qq-mng-codes { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin: 18px 0; }
@media (max-width: 640px) { .qq-mng-codes { grid-template-columns: repeat(2, 1fr); } }
.qq-mng-codes code {
    font-family: 'Space Mono', Consolas, monospace; font-size: 12.5px; color: #faf8f4;
    background: #26221c; border: 1px solid #3a352c; border-radius: 8px; padding: 7px 8px; text-align: center;
}

/* ============================================================ */
/* Admin v3: Features matrix (/admin/features)                  */
/* ============================================================ */
.qq-feat-status {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--qq-admin-mono, 'Space Mono', monospace);
    font-size: 11px;
    white-space: nowrap;
}

.qq-feat-status.unsaved { color: var(--qq-admin-accent); }
.qq-feat-status.saved { color: var(--qq-admin-muted); }

.qq-feat-status-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
}

.qq-feat-matrix {
    background: var(--qq-admin-card);
    border: 1px solid var(--qq-admin-border);
    border-radius: 14px;
    overflow: hidden;
}

.qq-feat-band {
    display: grid;
    background: var(--qq-admin-input);
    border-bottom: 1px solid var(--qq-admin-border);
}

.qq-feat-band-lead {
    padding: 15px 22px;
    display: flex;
    align-items: center;
}

.qq-feat-eyebrow {
    font-family: var(--qq-admin-mono, 'Space Mono', monospace);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--qq-admin-muted);
}

.qq-feat-plan {
    padding: 13px 18px;
    border-left: 1px solid #e9e2d3;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    text-align: center;
}

.qq-feat-plan-name {
    font-weight: 700;
    font-size: 14px;
    letter-spacing: -0.01em;
    color: var(--qq-admin-ink);
}

.qq-feat-plan-price {
    font-family: var(--qq-admin-mono, 'Space Mono', monospace);
    font-size: 11px;
    color: var(--qq-admin-faint);
    margin-top: 2px;
}

.qq-feat-plan-meta {
    display: flex;
    align-items: center;
    gap: 8px;
}

.qq-feat-count {
    font-family: var(--qq-admin-mono, 'Space Mono', monospace);
    font-size: 10px;
    color: var(--qq-admin-faint);
}

.qq-feat-bulk {
    font-family: var(--qq-admin-mono, 'Space Mono', monospace);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--qq-admin-accent);
    background: var(--qq-admin-flag);
    border: none;
    padding: 4px 9px;
    border-radius: 5px;
    cursor: pointer;
    text-transform: uppercase;
}

.qq-feat-bulk:hover { background: color-mix(in srgb, var(--qq-admin-accent) 12%, var(--qq-admin-flag)); }

.qq-feat-group {
    background: var(--qq-admin-input);
    border-bottom: 1px solid #e9e2d3;
    padding: 9px 22px;
}

.qq-feat-group span {
    font-family: var(--qq-admin-mono, 'Space Mono', monospace);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--qq-admin-muted, #9a917f);
}

.qq-feat-row {
    display: grid;
    border-bottom: 1px solid #f0eadc;
}

.qq-feat-row.soon { background: var(--qq-admin-input); }

.qq-feat-info { padding: 16px 22px; }
.qq-feat-info.dim { opacity: 0.62; }

.qq-feat-name-row {
    display: flex;
    align-items: center;
    gap: 9px;
}

.qq-feat-name {
    font-weight: 600;
    font-size: 14px;
    color: var(--qq-admin-ink);
}

.qq-feat-soon-pill {
    font-family: var(--qq-admin-mono, 'Space Mono', monospace);
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.1em;
    background: var(--qq-admin-flag);
    color: var(--qq-admin-accent);
    padding: 3px 8px;
    border-radius: 5px;
}

.qq-feat-desc {
    font-size: 12.5px;
    color: var(--qq-admin-muted);
    margin-top: 3px;
    line-height: 1.45;
    max-width: 340px;
}

.qq-feat-reach {
    font-family: var(--qq-admin-mono, 'Space Mono', monospace);
    font-size: 10px;
    letter-spacing: 0.04em;
    color: #b3aa97;
    margin-top: 7px;
}

.qq-feat-cell {
    padding: 16px 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-left: 1px solid #f2ece0;
    transition: background 0.12s;
}

.qq-feat-cell.changed { background: var(--qq-admin-flag); }

/* Toggle: a visually-hidden real checkbox behind a styled box, so it's
   natively keyboard-operable (Tab + Space) and screen-reader friendly. */
.qq-feat-toggle {
    position: relative;
    width: 24px;
    height: 24px;
    border-radius: 7px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--qq-admin-card);
    border: 1.5px solid #d5cdba;
    cursor: pointer;
    transition: all 0.12s;
    /* btn-fg, not #fbf8f1: the .on state fills with admin-ink, which inverts
       to ivory in dark mode — a hardcoded ivory check disappeared on it. */
    color: var(--qq-admin-btn-fg, #fbf8f1);
}

.qq-feat-toggle input {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

.qq-feat-toggle svg {
    width: 15px;
    height: 15px;
    pointer-events: none;
}

.qq-feat-toggle.on {
    background: var(--qq-admin-ink);
    border-color: var(--qq-admin-ink);
}

.qq-feat-toggle.changed { box-shadow: 0 0 0 3px #f6e5df; }

.qq-feat-toggle:has(input:focus-visible) {
    outline: 2px solid var(--qq-admin-accent);
    outline-offset: 2px;
}

.qq-feat-toggle.soon {
    background: var(--qq-admin-input);
    border: 1.5px dashed var(--qq-admin-border);
    cursor: not-allowed;
}

.qq-feat-toggle.soon input { cursor: not-allowed; }

/* Spec 036 part two: manage the document types on the same grid. */
.qq-feat-actions { display: inline-flex; gap: 6px; margin-left: 10px; }
.qq-feat-addrow {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    padding: 12px;
    background: none;
    border: 0;
    border-top: 1px dashed var(--qq-admin-border);
    color: var(--qq-admin-accent);
    font-family: var(--qq-admin-mono, 'Space Mono', monospace);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
}

.qq-feat-addrow:hover { background: var(--qq-admin-flag); }

.qq-feat-legend {
    display: flex;
    align-items: center;
    gap: 20px;
    margin-top: 16px;
    flex-wrap: wrap;
}

.qq-feat-leg {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: var(--qq-admin-muted);
}

.qq-feat-sw {
    width: 20px;
    height: 20px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.qq-feat-sw.on {
    background: var(--qq-admin-ink);
    color: var(--qq-admin-btn-fg, #fbf8f1);
}

.qq-feat-sw.on svg { width: 12px; height: 12px; }

.qq-feat-sw.off {
    background: var(--qq-admin-card);
    border: 1.5px solid #d5cdba;
}

.qq-feat-sw.soon {
    background: var(--qq-admin-input);
    border: 1.5px dashed var(--qq-admin-border);
}

.qq-feat-sw.changed {
    background: var(--qq-admin-ink);
    box-shadow: 0 0 0 3px #f6e5df;
}

.qq-feat-hint {
    margin-left: auto;
    font-size: 12px;
    color: var(--qq-admin-faint);
    max-width: 420px;
    text-align: right;
}

@media (max-width: 820px) {
    .qq-feat-matrix { overflow-x: auto; }
    .qq-feat-band, .qq-feat-row { min-width: 640px; }
    .qq-feat-hint { margin-left: 0; text-align: left; }
}

/* ---- Vouchers: buyer wallet cards ---------------------------------------- */
.qq-giftcard {
    border-radius: 14px;
    padding: 1.1rem 1.2rem;
    color: #fff;
    background: linear-gradient(135deg, #905e26, #c9a24b);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.14);
    min-height: 150px;
    display: flex;
    flex-direction: column;
}
.qq-giftcard.spent {
    filter: grayscale(0.7);
    opacity: 0.72;
}
.qq-giftcard-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: 0.08em;
    font-size: 1.05rem;
    font-weight: 700;
}
.qq-giftcard-value {
    font-size: 1.7rem;
    font-weight: 800;
    margin-top: auto;
}
.qq-giftcard-foot {
    font-size: 0.78rem;
    opacity: 0.9;
    margin-top: 0.35rem;
}
.qq-empty {
    text-align: center;
    padding: 2.5rem 1rem;
    color: var(--qq-text-muted);
}
.qq-empty p {
    margin-bottom: 1rem;
}

/* ---- Deals discovery strip (M3) ----------------------------------------- */
.qq-deals-strip {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 0.85rem;
}
.qq-deal-card {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    border-radius: 14px;
    padding: 0.95rem 1rem;
    text-decoration: none;
    color: var(--qq-text);
    border: 1px solid var(--qq-border);
    background: var(--qq-card);
    transition: transform 0.12s ease, box-shadow 0.12s ease;
    min-height: 128px;
}
.qq-deal-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
}
.qq-deal-card.gift {
    background: linear-gradient(135deg, rgba(144, 94, 38, 0.08), rgba(201, 162, 75, 0.14));
    border-color: rgba(201, 162, 75, 0.4);
}
.qq-deal-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}
.qq-deal-kind {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--qq-brass-deep, #8a5a1e);
}
.qq-deal-title {
    font-weight: 700;
    line-height: 1.2;
}
.qq-deal-sub {
    font-size: 0.85rem;
    color: var(--qq-text-muted);
}
.qq-deal-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: auto;
    padding-top: 0.4rem;
}
.qq-deal-store {
    font-size: 0.78rem;
    color: var(--qq-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.qq-deal-urgency {
    flex: none;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: var(--qq-bad-bg, rgba(200, 50, 40, 0.12));
    color: var(--qq-bad-fg, #b3271b);
    white-space: nowrap;
}

/* ---- Seller in-person redemption (M4) ----------------------------------- */
.qq-redeem-card {
    border: 1px solid var(--qq-border);
    border-radius: 12px;
    padding: 1rem 1.1rem;
    background: var(--qq-surface, var(--qq-card));
}
.qq-redeem-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    margin-top: 0.35rem;
}
.qq-redeem-balance {
    font-size: 1.6rem;
    font-weight: 800;
    color: var(--qq-brass-deep, #8a5a1e);
    margin-top: 0.15rem;
}
.qq-redeem-steps {
    margin: 0;
    padding-left: 1.1rem;
    color: var(--qq-text-muted);
    line-height: 1.9;
}

/* ---- Refer a friend (M4) ------------------------------------------------ */
.qq-refer-link {
    display: flex;
    gap: 0.5rem;
    align-items: stretch;
}
.qq-refer-link .qq-input {
    flex: 1;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.9rem;
}
.qq-refer-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
    text-align: center;
}
.qq-refer-stat {
    padding: 0.75rem 0.25rem;
    border-radius: 10px;
    background: var(--qq-surface, rgba(0, 0, 0, 0.03));
}
.qq-refer-stat-num {
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--qq-brass-deep, #8a5a1e);
}
.qq-refer-stat-lbl {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--qq-text-muted);
    margin-top: 0.15rem;
}

/* ==== Seller promotions v2 (paper/brass builder) ========================= */
.qq-promo-head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.qq-promo-title { font-size: 30px; font-weight: 700; letter-spacing: -0.03em; margin: 0 0 2px; color: var(--qq-text); }
.qq-promo-dot { color: #d9a94e; }
.qq-promo-count, .qq-promo-ledger-count {
    font-family: 'Space Mono', ui-monospace, monospace; font-size: 12px; color: var(--qq-text-muted);
}
.qq-promo-intro { color: var(--qq-text-body); margin: 0 0 22px; max-width: 760px; }

.qq-promo-grid { display: grid; grid-template-columns: 7fr 5fr; gap: 22px; align-items: start; }
@media (max-width: 900px) { .qq-promo-grid { grid-template-columns: 1fr; } }

/* -- ledger -- */
.qq-promo-ledger { background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 18px; overflow: hidden; }
.qq-promo-ledger-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 15px 18px; border-bottom: 1px solid var(--qq-border); font-weight: 700; color: var(--qq-text);
}
.qq-promo-empty { padding: 40px 18px; text-align: center; color: var(--qq-text-muted); }
.qq-promo-row { display: flex; align-items: center; gap: 13px; padding: 14px 18px; border-bottom: 1px solid var(--qq-border-soft); }
.qq-promo-row:last-child { border-bottom: none; }
.qq-promo-row.dim { opacity: 0.72; }
.qq-promo-badge {
    width: 46px; height: 46px; border-radius: 12px; flex-shrink: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    font-family: 'Space Mono', ui-monospace, monospace; line-height: 1;
    background: var(--qq-mute-bg); color: var(--qq-text-faint);
}
.qq-promo-badge.on { background: var(--qq-ink); color: var(--qq-brass); }
.qq-promo-badge .v { font-size: 15px; font-weight: 700; }
.qq-promo-badge .u { font-size: 7.5px; margin-top: 3px; letter-spacing: 0.06em; }
.qq-promo-row-body { flex: 1; min-width: 0; }
.qq-promo-row-name { font-size: 14.5px; font-weight: 700; color: var(--qq-text); display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.qq-promo-chip {
    font-size: 10.5px; font-weight: 700; padding: 1px 8px; border-radius: 99px;
    font-family: 'Space Mono', ui-monospace, monospace; letter-spacing: 0.03em;
}
.qq-promo-chip.code { background: var(--qq-info-bg); color: var(--qq-info-fg); }
.qq-promo-chip.auto { background: var(--qq-ok-bg); color: var(--qq-ok-fg); }
.qq-promo-chip.status.live { background: var(--qq-ok-bg); color: var(--qq-ok-fg); }
.qq-promo-chip.status.sched { background: var(--qq-info-bg); color: var(--qq-info-fg); }
.qq-promo-chip.status.capped { background: var(--qq-warn-bg); color: var(--qq-warn-fg); }
.qq-promo-chip.status.muted { background: var(--qq-mute-bg); color: var(--qq-text-muted); }
.qq-promo-row-sum { font-size: 12.5px; color: var(--qq-text-muted); margin-top: 3px; }
.qq-promo-row-usage { display: flex; align-items: center; gap: 10px; margin-top: 6px; font-size: 11.5px; color: var(--qq-text-muted); }
.qq-promo-row-usage .mono { font-family: 'Space Mono', ui-monospace, monospace; }
.qq-promo-capbar { width: 70px; height: 5px; border-radius: 99px; background: var(--qq-mute-bg); overflow: hidden; }
.qq-promo-capbar span { display: block; height: 100%; background: var(--qq-gold-bright); border-radius: 99px; }
.qq-promo-cal { font-family: 'Space Mono', ui-monospace, monospace; font-size: 10.5px; color: var(--qq-warn-fg); }
.qq-promo-row-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.qq-promo-ghost {
    border: 1px solid var(--qq-border); background: var(--qq-card); color: var(--qq-text); font-weight: 600; font-size: 12.5px;
    padding: 6px 13px; border-radius: 99px; cursor: pointer;
}
.qq-promo-ghost:hover { background: var(--qq-shell); }
.qq-promo-x { border: none; background: none; color: var(--qq-text-faint); font-size: 20px; line-height: 1; cursor: pointer; padding: 0 4px; }
.qq-promo-x:hover { color: var(--qq-bad-fg); }

/* -- builder -- */
.qq-promo-builder { background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 18px; padding: 20px; position: sticky; top: 16px; }
.qq-promo-builder-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.qq-promo-mode { font-family: 'Space Mono', ui-monospace, monospace; font-size: 10.5px; letter-spacing: 0.12em; color: var(--qq-text-faint); text-transform: uppercase; }
.qq-promo-newinstead { border: none; background: none; color: var(--qq-brass); font-weight: 600; font-size: 12px; cursor: pointer; }
.qq-promo-flabel { display: block; font-size: 12.5px; font-weight: 600; color: var(--qq-text-body); margin: 0 0 5px; }
.qq-promo-flabel .opt { color: var(--qq-text-faint); font-weight: 400; }
.qq-promo-field {
    width: 100%; border: 1px solid var(--qq-border); border-radius: 11px; padding: 11px 13px;
    font-size: 14px; background: var(--qq-card); color: var(--qq-text); outline: none; margin-bottom: 14px; font-family: inherit;
}
.qq-promo-field.mono { font-family: 'Space Mono', ui-monospace, monospace; letter-spacing: 0.05em; }
.qq-promo-field:focus, .qq-promo-date:focus { border-color: var(--qq-ink); }
.qq-promo-tworow { display: flex; gap: 12px; margin-bottom: 14px; }
.qq-promo-seg { display: flex; gap: 6px; background: var(--qq-border-soft); border-radius: 11px; padding: 4px; }
.qq-promo-seg button {
    flex: 1; text-align: center; font-size: 13px; font-weight: 600; padding: 8px 0; border-radius: 8px;
    cursor: pointer; border: none; background: none; color: var(--qq-text-muted);
}
.qq-promo-seg button.on { background: var(--qq-card); color: var(--qq-text); box-shadow: 0 1px 3px rgba(23,21,18,.1); }
.qq-promo-affix { display: flex; align-items: center; border: 1px solid var(--qq-border); border-radius: 11px; background: var(--qq-card); padding: 0 12px; }
.qq-promo-affix .a { color: var(--qq-text-faint); font-size: 14px; }
.qq-promo-affix input { flex: 1; min-width: 0; border: none; outline: none; padding: 11px 6px; font-size: 14px; background: transparent; color: var(--qq-text); text-align: center; }
.qq-promo-pickstack { display: flex; flex-direction: column; gap: 5px; }
.qq-promo-pickstack button {
    text-align: left; font-size: 12.5px; font-weight: 600; padding: 8px 12px; border-radius: 9px;
    cursor: pointer; border: 1px solid var(--qq-border-soft); background: var(--qq-paper); color: var(--qq-text-muted);
}
.qq-promo-pickstack button.on { background: var(--qq-ink); color: var(--qq-paper); border-color: var(--qq-ink); }
.qq-promo-check { display: flex; align-items: flex-start; gap: 9px; margin-bottom: 16px; cursor: pointer; }
.qq-promo-check.disabled { opacity: 0.55; }
.qq-promo-check input { margin-top: 2px; }
.qq-promo-check .t { display: block; font-size: 13px; font-weight: 600; color: var(--qq-text); }
.qq-promo-check .h { display: block; font-size: 11.5px; color: var(--qq-text-muted); margin-top: 1px; }
.qq-promo-radios { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.qq-promo-radio {
    display: flex; align-items: center; gap: 11px; text-align: left; cursor: pointer;
    border: 1px solid var(--qq-border); border-radius: 12px; padding: 11px 13px; background: var(--qq-card); width: 100%;
}
.qq-promo-radio.on { border-color: var(--qq-ink); background: var(--qq-paper); }
.qq-promo-radio .dot { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--qq-track-off); flex-shrink: 0; position: relative; }
.qq-promo-radio.on .dot { border-color: var(--qq-ink); }
.qq-promo-radio.on .dot::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--qq-ink); }
.qq-promo-radio .l { display: block; font-size: 13px; font-weight: 600; color: var(--qq-text); }
.qq-promo-radio .s { display: block; font-size: 11.5px; color: var(--qq-text-muted); margin-top: 1px; }
.qq-promo-daterow { display: flex; gap: 8px; align-items: flex-start; margin-bottom: 16px; }
.qq-promo-daterow > div { flex: 1; }
.qq-promo-daterow .arrow { align-self: flex-start; padding-top: 11px; color: var(--qq-text-faint); }
.qq-promo-date { width: 100%; border: 1px solid var(--qq-border); border-radius: 10px; padding: 10px 12px; font-size: 13px; font-family: inherit; background: var(--qq-card); color: var(--qq-text); outline: none; }
.qq-promo-daterow .cap { font-size: 10.5px; color: var(--qq-text-faint); text-align: center; margin-top: 4px; }
.qq-promo-toggle { display: flex; align-items: center; gap: 10px; cursor: pointer; margin-bottom: 18px; }
.qq-promo-toggle .track { width: 38px; height: 22px; border-radius: 99px; background: var(--qq-track-off); position: relative; transition: background .15s; flex-shrink: 0; }
.qq-promo-toggle .track.on { background: #3f7a52; }
.qq-promo-toggle .knob { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: var(--qq-ink); box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: left .15s, background .15s; }
.qq-promo-toggle .track.on .knob { left: 18px; background: #fff; }
.qq-promo-toggle .lbl { font-size: 13.5px; font-weight: 600; color: var(--qq-text-body); }
.qq-promo-actions { display: flex; gap: 10px; }
.qq-promo-save { flex: 1; text-align: center; background: var(--qq-ink); color: var(--qq-paper); font-weight: 600; font-size: 14px; padding: 12px 0; border-radius: 99px; cursor: pointer; border: none; }
.qq-promo-save:disabled { opacity: 0.6; cursor: default; }
.qq-promo-cancel { border: 1px solid var(--qq-border); background: var(--qq-card); color: var(--qq-text); font-weight: 600; font-size: 14px; padding: 12px 22px; border-radius: 99px; cursor: pointer; }

/* -- previews -- */
.qq-promo-preview-wrap { margin-bottom: 18px; }
.qq-promo-preview-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.qq-promo-preview-head > span { font-family: 'Space Mono', ui-monospace, monospace; font-size: 9.5px; letter-spacing: 0.1em; color: var(--qq-text-faint); }
.qq-promo-preview-tabs { display: flex; gap: 4px; background: var(--qq-border-soft); border-radius: 8px; padding: 3px; }
.qq-promo-preview-tabs button { font-size: 11px; font-weight: 600; padding: 5px 11px; border-radius: 6px; cursor: pointer; border: none; background: none; color: var(--qq-text-muted); }
.qq-promo-preview-tabs button.on { background: var(--qq-card); color: var(--qq-text); box-shadow: 0 1px 2px rgba(23,21,18,.1); }
.qq-promo-offercard { background: #171512; border-radius: 16px; padding: 16px; position: relative; overflow: hidden; }
.qq-promo-offercard-glow { position: absolute; top: -30px; right: -30px; width: 96px; height: 96px; border-radius: 50%; background: radial-gradient(circle, #d9a94e33, transparent 70%); }
.qq-promo-offercard-top { display: flex; align-items: flex-start; gap: 12px; position: relative; }
.qq-promo-offercard-badge { width: 52px; height: 52px; border-radius: 13px; background: #d9a94e; color: #171512; display: flex; flex-direction: column; align-items: center; justify-content: center; flex-shrink: 0; font-family: 'Space Mono', ui-monospace, monospace; line-height: 1; }
.qq-promo-offercard-badge .v { font-size: 17px; font-weight: 700; }
.qq-promo-offercard-badge .u { font-size: 8px; margin-top: 2px; letter-spacing: 0.06em; }
.qq-promo-offercard-headline { flex: 1; min-width: 0; }
.qq-promo-offercard-headline .eyebrow { display: flex; align-items: center; gap: 7px; font-family: 'Space Mono', ui-monospace, monospace; font-size: 8.5px; letter-spacing: 0.14em; font-weight: 700; color: #d9a94e; }
.qq-promo-offercard-headline .eyebrow .sched { letter-spacing: 0.06em; color: #b3aa99; font-weight: 400; }
.qq-promo-offercard-headline .label { color: #faf8f4; font-weight: 700; font-size: 15px; letter-spacing: -0.01em; line-height: 1.25; margin-top: 3px; }
.qq-promo-offercard-apply { margin-top: 13px; position: relative; }
.qq-promo-offercard-apply .code { display: flex; align-items: center; gap: 8px; border: 1px dashed #4a4436; border-radius: 10px; padding: 8px 12px; }
.qq-promo-offercard-apply .code .k { font-family: 'Space Mono', ui-monospace, monospace; font-size: 9px; letter-spacing: 0.1em; color: #8a8272; }
.qq-promo-offercard-apply .code .c { font-family: 'Space Mono', ui-monospace, monospace; font-size: 13px; font-weight: 700; color: #faf8f4; letter-spacing: 0.06em; }
.qq-promo-offercard-apply .code .a { margin-left: auto; font-size: 11.5px; font-weight: 600; color: #d9a94e; }
.qq-promo-offercard-apply .autorow { display: block; border: 1px solid #2a251e; border-radius: 10px; padding: 8px 12px; background: #26221c; font-size: 12px; color: #c9c1b0; }
.qq-promo-offercard-fine { display: flex; flex-wrap: wrap; gap: 6px 12px; margin-top: 12px; padding-top: 11px; border-top: 1px solid #2a251e; position: relative; }
.qq-promo-offercard-fine span { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: #a39a88; }
.qq-promo-offercard-fine .dot { width: 3px; height: 3px; border-radius: 50%; background: #6b6353; }
.qq-promo-checkoutcard { background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 16px; padding: 16px 18px; }
.qq-promo-checkoutcard-eyebrow { font-family: 'Space Mono', ui-monospace, monospace; font-size: 9px; letter-spacing: 0.12em; color: var(--qq-text-faint); margin-bottom: 12px; }
.qq-promo-checkoutcard .row { display: flex; justify-content: space-between; font-size: 13.5px; color: var(--qq-text-body); margin-bottom: 9px; }
.qq-promo-checkoutcard .row.disc { align-items: flex-start; gap: 12px; }
.qq-promo-checkoutcard .row.disc .lbl { display: flex; align-items: center; gap: 7px; min-width: 0; color: var(--qq-brass); font-weight: 600; font-size: 13px; }
.qq-promo-checkoutcard .codechip { font-family: 'Space Mono', ui-monospace, monospace; font-size: 10px; font-weight: 700; background: var(--qq-brass-tint); color: var(--qq-brass); padding: 1px 6px; border-radius: 5px; }
.qq-promo-checkoutcard .row.disc .amt { color: var(--qq-brass); font-weight: 700; white-space: nowrap; }
.qq-promo-checkoutcard .rule { border-top: 1px solid var(--qq-border-soft); margin: 12px 0 10px; }
.qq-promo-checkoutcard .row.total { align-items: baseline; }
.qq-promo-checkoutcard .row.total .t { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; color: var(--qq-text); }
.qq-promo-checkoutcard .saved { display: flex; align-items: center; gap: 7px; background: var(--qq-ok-bg); border-radius: 9px; padding: 8px 11px; margin-top: 12px; font-size: 12px; font-weight: 600; color: var(--qq-ok-fg); }
.qq-promo-checkout-prompt { font-size: 12.5px; color: var(--qq-text-muted); padding: 8px 0; }

/* -- analytics -- */
.qq-promo-analytics { background: var(--qq-paper); border: 1px solid var(--qq-border); border-radius: 14px; padding: 16px; margin-bottom: 18px; }
.qq-promo-analytics-head { display: flex; align-items: center; margin-bottom: 12px; font-family: 'Space Mono', ui-monospace, monospace; font-size: 9.5px; letter-spacing: 0.1em; color: var(--qq-text-faint); }
.qq-promo-analytics-head .dim { margin-left: auto; color: var(--qq-text-faint); }
.qq-promo-figs { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; margin-bottom: 14px; }
.qq-promo-figs .n { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; color: var(--qq-text); }
.qq-promo-figs .n.brass { color: var(--qq-brass); }
.qq-promo-figs .l { font-size: 11px; color: var(--qq-text-muted); }
.qq-promo-bars { display: flex; align-items: flex-end; gap: 4px; height: 38px; padding: 0 1px; margin-bottom: 12px; }
.qq-promo-bars span { flex: 1; background: #d9a94e; border-radius: 3px 3px 0 0; min-height: 2px; }
.qq-promo-analytics-foot { display: flex; justify-content: space-between; margin-top: 7px; font-size: 11px; color: var(--qq-text-muted); }
.qq-promo-analytics-foot .dim { color: var(--qq-text-faint); }
.qq-promo-analytics-empty { font-size: 12.5px; color: var(--qq-text-muted); line-height: 1.5; }

/* ==== Seller gift cards v2 (artwork + schedule) ========================== */
/* Artwork themes set CSS vars the card/mini/swatch read. */
.art-espresso { --art-bg: linear-gradient(135deg,#26221c,#171512); --art-accent: #d9a94e; --art-glow: #d9a94e; }
.art-midnight { --art-bg: linear-gradient(135deg,#20304a,#0f141c); --art-accent: #8fbde6; --art-glow: #6ea8d8; }
.art-plum     { --art-bg: linear-gradient(135deg,#3a2140,#181015); --art-accent: #d9a0d9; --art-glow: #c98ac9; }
.art-forest   { --art-bg: linear-gradient(135deg,#1f3a29,#0f1712); --art-accent: #98d3a6; --art-glow: #7fbf8f; }

.qq-gift-paybanner {
    display: flex; align-items: center; gap: 12px;
    background: var(--qq-brass-tint); border: 1px solid var(--qq-brass-soft); color: var(--qq-brass-deep);
    border-radius: 14px; padding: 13px 16px; font-size: 0.9rem;
}
.qq-gift-paybanner .ico { font-size: 1.1rem; }
.qq-gift-paybtn {
    flex: none; background: #6d4b12; color: #faf8f4; text-decoration: none;
    font-weight: 600; font-size: 0.82rem; padding: 6px 13px; border-radius: 99px;
}

/* Ledger mini card badge */
.qq-gift-mini {
    width: 58px; height: 40px; border-radius: 9px; flex-shrink: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    background: var(--art-bg); color: #fff; font-family: 'Space Mono', ui-monospace, monospace; line-height: 1.1;
}
.qq-gift-mini.off { filter: grayscale(0.85); opacity: 0.75; }
.qq-gift-mini .w { font-size: 6.5px; letter-spacing: 0.1em; color: var(--art-accent); }
.qq-gift-mini .v { font-size: 13px; font-weight: 700; }

/* Builder preview gift card */
.qq-gift-card {
    position: relative; overflow: hidden; border-radius: 16px; padding: 16px 18px;
    background: var(--art-bg); color: #faf8f4; min-height: 168px;
    display: flex; flex-direction: column; justify-content: space-between;
}
.qq-gift-glow {
    position: absolute; top: -40px; right: -40px; width: 130px; height: 130px; border-radius: 50%;
    background: radial-gradient(circle, color-mix(in srgb, var(--art-glow) 35%, transparent), transparent 70%);
}
.qq-gift-top { display: flex; align-items: center; gap: 9px; position: relative; }
.qq-gift-logo {
    width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0; overflow: hidden;
    display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.9rem;
    background: color-mix(in srgb, var(--art-accent) 22%, transparent); color: var(--art-accent);
}
.qq-gift-logo img { width: 100%; height: 100%; object-fit: cover; }
.qq-gift-store { font-weight: 700; font-size: 0.95rem; }
.qq-gift-tag {
    margin-left: auto; font-family: 'Space Mono', ui-monospace, monospace; font-size: 8px;
    letter-spacing: 0.14em; font-weight: 700; color: var(--art-accent);
}
.qq-gift-mid { position: relative; }
.qq-gift-vlabel {
    font-family: 'Space Mono', ui-monospace, monospace; font-size: 9px; letter-spacing: 0.1em; color: #c9c1b0;
}
.qq-gift-value { font-size: 2.1rem; font-weight: 800; letter-spacing: -0.02em; color: var(--art-accent); }
.qq-gift-foot {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    font-size: 0.78rem; color: #c9c1b0; position: relative;
}
.qq-gift-bonuschip {
    flex: none; font-size: 0.72rem; font-weight: 700; padding: 2px 8px; border-radius: 99px;
    background: color-mix(in srgb, var(--art-accent) 20%, transparent); color: var(--art-accent);
}

/* Artwork swatches */
.qq-gift-swatches { display: flex; gap: 8px; margin-bottom: 14px; }
.qq-gift-swatch {
    width: 32px; height: 32px; border-radius: 8px; cursor: pointer; padding: 0;
    background: var(--art-bg); border: 2px solid transparent;
}
.qq-gift-swatch.on { border-color: var(--qq-ink); box-shadow: 0 0 0 2px var(--qq-card) inset; }

.qq-gift-bonushint { font-size: 0.8rem; margin: -4px 0 14px; }

/* ==== Seller reports v2 ================================================== */
.qq-rpt-rangebar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 18px; }
.qq-rpt-presets { width: auto; }
.qq-rpt-arrow { color: var(--qq-text-faint); }
.qq-rpt-csv { padding: 9px 14px; font-size: 0.82rem; text-decoration: none; }
a.qq-rpt-csv.qq-promo-cancel { display: inline-flex; align-items: center; }

.qq-rpt-kpis { display: grid; grid-template-columns: 1.4fr repeat(4, 1fr); gap: 12px; margin-bottom: 18px; }
@media (max-width: 900px) { .qq-rpt-kpis { grid-template-columns: 1fr 1fr; } }
.qq-rpt-hero {
    background: #171512; color: #faf8f4; border-radius: 16px; padding: 16px 18px;
    display: flex; flex-direction: column; justify-content: center;
}
.qq-rpt-hero .lbl { font-family: 'Space Mono', ui-monospace, monospace; font-size: 9.5px; letter-spacing: 0.1em; color: #c9c1b0; }
.qq-rpt-hero .val { font-size: 1.9rem; font-weight: 800; letter-spacing: -0.02em; margin: 2px 0; }
.qq-rpt-kpi { background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 16px; padding: 14px 16px; position: relative; }
.qq-rpt-kpi .dot { width: 8px; height: 8px; border-radius: 50%; position: absolute; top: 16px; right: 16px; }
.qq-rpt-kpi .val { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.02em; color: var(--qq-text); }
.qq-rpt-kpi .lbl, .qq-rpt-hero .val + .delta { }
.qq-rpt-kpi .lbl { font-size: 0.78rem; color: var(--qq-text-muted); }
.delta { font-family: 'Space Mono', ui-monospace, monospace; font-size: 0.72rem; font-weight: 700; margin-top: 4px; }
.delta.up { color: var(--qq-ok-fg); }
.delta.down { color: var(--qq-bad-fg); }
.delta.flat, .delta { color: var(--qq-text-faint); }
.delta.up { color: var(--qq-ok-fg); } .delta.down { color: var(--qq-bad-fg); }
.qq-rpt-hero .delta.up { color: #98d3a6; } .qq-rpt-hero .delta.down { color: #e6a99e; } .qq-rpt-hero .delta.flat { color: #b3aa99; }

.qq-rpt-charts { display: grid; grid-template-columns: 1.55fr 1fr; gap: 16px; }
@media (max-width: 900px) { .qq-rpt-charts { grid-template-columns: 1fr; } }
.qq-rpt-chart-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; font-weight: 700; color: var(--qq-text); }
.qq-rpt-legend { display: flex; gap: 12px; font-size: 0.72rem; font-weight: 400; color: var(--qq-text-muted); }
.qq-rpt-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 4px; vertical-align: middle; }
.qq-rpt-bars { display: flex; align-items: flex-end; gap: 6px; height: 110px; }
.qq-rpt-barcol { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 5px; }
.qq-rpt-bar { display: flex; flex-direction: column-reverse; width: 100%; max-width: 30px; }
.qq-rpt-bar .ord { background: #d9a94e; border-radius: 3px 3px 0 0; }
.qq-rpt-bar .book { background: #41597a; }
.qq-rpt-bar .book:only-child { border-radius: 3px 3px 0 0; }
.qq-rpt-barlbl { font-family: 'Space Mono', ui-monospace, monospace; font-size: 8.5px; color: var(--qq-text-faint); white-space: nowrap; }
.qq-rpt-peak { font-family: 'Space Mono', ui-monospace, monospace; font-size: 10px; color: var(--qq-text-muted); margin-top: 10px; }

.qq-rpt-statusbar { display: flex; height: 12px; border-radius: 99px; overflow: hidden; background: var(--qq-mute-bg); margin-bottom: 14px; }
.qq-rpt-statusbar span { display: block; height: 100%; }
.qq-rpt-statuslegend { display: flex; flex-direction: column; gap: 7px; }
.qq-rpt-statuslegend > div { display: flex; align-items: center; gap: 7px; font-size: 0.82rem; color: var(--qq-text-body); }
.qq-rpt-statuslegend .d { width: 9px; height: 9px; border-radius: 2px; }
.qq-rpt-statuslegend .n { margin-left: auto; font-family: 'Space Mono', ui-monospace, monospace; font-size: 0.75rem; color: var(--qq-text-muted); }
.qq-rpt-substrip { display: flex; gap: 22px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--qq-border-soft); }
.qq-rpt-substrip .v { font-size: 1.2rem; font-weight: 700; color: var(--qq-text); display: block; }
.qq-rpt-substrip .l { font-size: 0.72rem; color: var(--qq-text-muted); }

.qq-rpt-top { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--qq-border-soft); }
.qq-rpt-top:last-child { border-bottom: none; }
.qq-rpt-top .rank { width: 22px; height: 22px; border-radius: 6px; background: #171512; color: #d9a94e; font-family: 'Space Mono', ui-monospace, monospace; font-size: 0.72rem; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.qq-rpt-top .nm { font-weight: 600; font-size: 0.9rem; flex: 0 0 30%; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qq-rpt-top .bar { flex: 1; height: 8px; border-radius: 99px; background: var(--qq-mute-bg); overflow: hidden; }
.qq-rpt-top .bar span { display: block; height: 100%; background: #d9a94e; border-radius: 99px; }
.qq-rpt-top .qty { font-family: 'Space Mono', ui-monospace, monospace; font-size: 0.75rem; color: var(--qq-text-muted); white-space: nowrap; }
.qq-rpt-top .rev { font-weight: 700; color: var(--qq-brass); white-space: nowrap; min-width: 4rem; text-align: right; }

/* Lock background scroll while a mobile nav drawer is open (js/nav-drawer.js). */
body.qq-drawer-open {
    overflow: hidden;
}

/* ---- Mobile overflow fixes ---------------------------------------------------- */

/* Rows built from fixed-width blocks (time ranges, day labels + inputs, action
   buttons) can't fit on one line on a phone. Opt these specific rows into
   wrapping, and give their flexible middle block a full-width line so its own
   fixed-width children (e.g. two time inputs) have room instead of overflowing.
   Used by /seller/appointments, /seller/availability, /seller/hours. */
@media (max-width: 640px) {
    /* Generic list/detail rows never wrapped, so any row carrying action buttons
       or fixed-width blocks (admin "needs attention" rows, seller lists, etc.)
       could push its controls off-screen. Wrapping on phones keeps every control
       reachable — far better than letting the overflow backstop clip a button. */
    .qq-row {
        flex-wrap: wrap;
    }

    .qq-row-wrap-sm > .flex-grow-1 {
        min-width: 0;
        flex-basis: 100%;
    }
}

/* The admin feature matrix is intrinsically wide (a lead column plus one column
   per plan). On narrow screens let it scroll sideways within its own card
   instead of clipping the off-screen plan columns (overflow-y stays hidden from
   the base rule, so the rounded corners are preserved). */
@media (max-width: 820px) {
    .qq-feat-matrix {
        overflow-x: auto;
    }
}

/* Segmented pill tracks (support status tabs, date-range presets) are
   inline-flex rows of fixed-size pills: they can't wrap without breaking the
   rounded track, so on a phone they were setting the page's scroll width and
   dragging every card off-screen with them. Scroll inside the track instead —
   same rule the grids above follow. Clipping is not an option here: the last
   pill ("Resolved", "Custom") would become permanently unreachable.

   No media query — capping at the container width is self-correcting, so this
   also covers a track placed in a narrow card or drawer at any viewport. */
.qq-seg,
.qq-rp-seg {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* The pills are their own affordance, and a scrollbar across a rounded
       track looks like damage. The part-visible last pill is the cue. */
    scrollbar-width: none;
}

.qq-seg::-webkit-scrollbar,
.qq-rp-seg::-webkit-scrollbar {
    display: none;
}

/* Flex children shrink by default; these must keep their size and scroll. */
.qq-seg > a,
.qq-seg > button,
.qq-seg > span,
.qq-rp-seg > button {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* Data-dense grids/cards (admin stats, home, reports, etc.) can be pushed wider
   than a phone by real content: grid & flex items default to min-width:auto, so
   a long store name or a large currency figure refuses to shrink and forces the
   whole page to scroll sideways. Two-part fix below. */
@media (max-width: 820px) {
    /* 1) Let the flex/grid items actually shrink, and let long unbreakable
          values (currency, counts) wrap rather than dictate width. */
    .stats-grid > *, .stats-duo > *, .overview-grid > *, .heat-grid > *,
    .mix-card > *, .mix-rows, .mix-rows *, .buyer-row, .pipe-legend-row,
    .attention-row, .attention-row *,
    .qq-rpt-kpis > *, .qq-rpt-charts > *, .qq-rpt-top, .qq-rpt-top * {
        min-width: 0;
    }

    .band-value, .attn-count, .stat-value, .donut-pct, .spend,
    .qq-rpt-kpis .v, .qq-rpt-substrip .v, .qq-rpt-top .rev {
        overflow-wrap: anywhere;
    }

    /* 2) Backstop: clip any horizontal overflow at the content wrapper so the
          page itself can never scroll sideways. These wrappers are auto-height
          (their shells are min-height:100vh), so overflow-y is unaffected and
          vertical scrolling still works; the sticky topbars and fixed nav
          drawers live outside these boxes, and QuickGrid tables keep their own
          inner horizontal scroll. */
    .admin-content,
    .seller-content {
        overflow-x: clip;
    }
}

/* Promotions / vouchers builder (/seller/promotions, /seller/vouchers): the
   two-up field rows and the schedule date pair are flex rows whose flex:1
   children default to min-width:auto, so the native date/number inputs refuse
   to shrink and push the builder column — and the whole page — wider than a
   phone (the clip backstop was then cutting the right column off). Letting the
   grid columns and these flex children shrink at every width makes the builder
   reflow to fit. */
.qq-promo-grid > *,
.qq-promo-tworow > div,
.qq-promo-daterow > div,
.qq-promo-date {
    min-width: 0;
}

/* ---- Receipts (spec 010): a printable sheet. Print rules are global on
   purpose: scoped CSS can't reach the layout chrome, and hiding nav/footer
   when printing is right for every page, not just receipts. ---- */
.qq-receipt { max-width: 42rem; }
.qq-receipt-actions { display: flex; justify-content: space-between; gap: .75rem; margin-bottom: 1rem; }
.qq-receipt-sheet {
  background: var(--qq-card, #fff);
  border: 1px solid var(--qq-border, #e5e0d8);
  border-radius: .75rem;
  padding: 2rem;
}
.qq-receipt-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 1.5rem; }
.qq-receipt-brand { font-weight: 700; font-size: 1.35rem; letter-spacing: -.02em; }
.qq-receipt-brand span { color: var(--qq-brass, #b8860b); }
.qq-receipt-stamp {
  border: 2px solid var(--qq-ok, #3f7a52); color: var(--qq-ok, #3f7a52);
  border-radius: .35rem; padding: .1rem .6rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; font-size: .8rem;
}
.qq-receipt-meta { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.qq-receipt-strong { font-weight: 600; }
.qq-receipt-lines { width: 100%; border-collapse: collapse; margin-bottom: 1rem; }
.qq-receipt-lines th, .qq-receipt-lines td { padding: .45rem 0; border-bottom: 1px solid var(--qq-border, #e5e0d8); text-align: left; }
.qq-receipt-lines th { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--qq-text-muted, #777); }
.qq-receipt-lines .num { text-align: right; }
.qq-receipt-selections { font-size: .85rem; color: var(--qq-text-muted, #777); }
.qq-receipt-totals { margin-left: auto; max-width: 20rem; }
.qq-receipt-totals .row-line { display: flex; justify-content: space-between; padding: .2rem 0; }
.qq-receipt-totals .deduct { color: var(--qq-ok, #3f7a52); }
.qq-receipt-totals .total { font-weight: 700; border-top: 2px solid var(--qq-ink, #171512); margin-top: .35rem; padding-top: .5rem; }
.qq-receipt-payment { margin-top: 1.5rem; }
.qq-receipt-ref { font-size: .85rem; color: var(--qq-text-muted, #777); word-break: break-all; }
.qq-receipt-foot { margin-top: 2rem; text-align: center; font-size: .85rem; color: var(--qq-text-muted, #777); }

@media print {
  nav, footer, .qq-mc, #blazor-error-ui, .qq-help-launcher, .qq-toast-host { display: none !important; }
  /* The studio and console shells: their chrome is aside/header elements the
     nav rule above never touches, so the seller's subscription invoice printed
     wrapped in the whole studio while buyer receipts printed clean. Global
     rules still match scoped-CSS class names; !important beats the scoped
     bundle either way. */
  .seller-sidebar, .seller-topbar, .seller-scrim,
  .admin-sidebar, .admin-topbar, .admin-scrim, .admin-maintenance-band { display: none !important; }
  .seller-shell, .admin-shell { display: block !important; background: #fff !important; }
  .seller-content, .admin-content { padding: 0 !important; margin: 0 !important; max-width: none !important; }
  body { background: #fff !important; }
  .content, main, .container { padding: 0 !important; margin: 0 !important; max-width: none !important; }
  .qq-receipt-sheet { border: none; padding: 0; }
}

/* Seller appointment: who it is with, and the folded-away detail list. */
.qq-appt-with {
    font-size: .83rem;
    color: var(--qq-brass-text);
    font-weight: 600;
}

.qq-appt-detail {
    display: grid;
    grid-template-columns: minmax(7rem, max-content) 1fr;
    gap: .3rem 1rem;
    margin: .6rem 0 0;
    padding: .75rem 0 .25rem;
    border-top: 1px solid var(--qq-border);
    font-size: .85rem;
}

.qq-appt-detail dt {
    color: var(--qq-text-muted);
    font-weight: 500;
}

.qq-appt-detail dd {
    margin: 0;
    color: var(--qq-ink);
}

/* The one line a seller must not skim past. */
.qq-appt-detail dd.warn { color: var(--qq-brass-text); font-weight: 600; }

.qq-appt-detail-note {
    display: block;
    font-size: .78rem;
    color: var(--qq-text-muted);
    font-weight: 400;
}

@media (max-width: 575.98px) {
    .qq-appt-detail { grid-template-columns: 1fr; gap: .1rem; }
    .qq-appt-detail dt { margin-top: .5rem; }
}

/* Seller topbar: the guided tour, deliberately prominent. A seller who cannot
   find the tour has no tour, so it sits beside the theme and notification
   controls rather than at the foot of a drawer they may never open. */
.seller-tour-btn {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .35rem .7rem;
    border-radius: 999px;
    border: 1px solid var(--qq-brass);
    background: color-mix(in srgb, var(--qq-brass) 12%, transparent);
    color: var(--qq-brass-text);
    font-size: .82rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

.seller-tour-btn:hover {
    background: color-mix(in srgb, var(--qq-brass) 22%, transparent);
    color: var(--qq-brass-text-hover);
}

.seller-tour-btn svg { width: 15px; height: 15px; flex-shrink: 0; }

/* On a phone the icon carries it — the topbar has no room for the word. */
@media (max-width: 575.98px) {
    .seller-tour-btn-text { display: none; }
    .seller-tour-btn { padding: .35rem .5rem; }
}

/* Connect-done (spec 021): the compact page the payment-provider tab lands on. */
.qq-connect-done {
    max-width: 26rem;
    margin: 14vh auto 0;
    padding: 2rem 1.5rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    align-items: center;
}

.qq-connect-done h1 {
    font-size: 1.25rem;
    margin: 0;
}

.qq-connect-done p {
    color: var(--qq-text-muted);
    font-size: 0.92rem;
    margin: 0;
}

.qq-connect-done-badge {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.3rem;
}

.qq-connect-done-badge.is-ok { background: var(--qq-ok-bg, #e8f0e6); color: var(--qq-ok-fg, #3f7a52); }
.qq-connect-done-badge.is-bad { background: var(--qq-bad-bg, #f6e5df); color: var(--qq-bad-fg, #93381f); }

/* ---- Spec 021/022: payout verification modal ---- */
.qq-verify-backdrop {
    position: fixed; inset: 0; z-index: 1080;
    display: flex; align-items: center; justify-content: center; padding: 20px;
    background: color-mix(in srgb, #14100b 52%, transparent);
    backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
    animation: qq-verify-fade .18s ease-out;
}
.qq-verify-card {
    width: min(420px, 100%);
    background: var(--qq-card); color: var(--qq-text);
    border: 1px solid var(--qq-border); border-radius: 22px;
    padding: 34px 30px 24px; text-align: center;
    box-shadow: 0 30px 80px -20px rgba(20, 14, 5, .5),
                0 0 0 1px color-mix(in srgb, var(--qq-brass) 12%, transparent);
    animation: qq-verify-pop .24s cubic-bezier(.2, .9, .3, 1.12);
}
.qq-verify-badge {
    width: 58px; height: 58px; margin: 0 auto 16px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, #905e26, #d9a94e 62%, #f5ec9b);
    color: #241a08;
    box-shadow: 0 12px 26px -10px color-mix(in srgb, #905e26 70%, transparent);
}
.qq-verify-badge svg { width: 26px; height: 26px; }
.qq-verify-title { font-size: 1.3rem; font-weight: 700; margin: 0 0 8px; }
.qq-verify-lead { font-size: .9rem; color: var(--qq-text-muted); line-height: 1.55; margin: 0 0 8px; }
.qq-verify-email {
    display: inline-block; margin: 0 0 16px; padding: 4px 14px; border-radius: 999px;
    background: color-mix(in srgb, var(--qq-brass) 12%, transparent);
    color: var(--qq-brass); font-weight: 600; font-size: .85rem;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qq-verify-error {
    margin: 0 0 12px; padding: 9px 14px; border-radius: 12px; font-size: .85rem;
    color: var(--qq-bad-fg);
    background: color-mix(in srgb, var(--qq-bad-fg) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--qq-bad-fg) 25%, transparent);
    animation: qq-verify-shake .3s ease-out;
}
.qq-verify-input {
    display: block; width: 100%; max-width: 240px; margin: 0 auto 16px;
    padding: 10px 0 10px .55em; /* pad-left offsets the trailing letter-space so digits sit centered */
    font-size: 1.65rem; font-weight: 700; letter-spacing: .55em; text-align: center;
    font-variant-numeric: tabular-nums;
    background: transparent; color: var(--qq-text);
    border: 1.5px solid var(--qq-border); border-radius: 14px; outline: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.qq-verify-input:focus {
    border-color: var(--qq-brass);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--qq-brass) 18%, transparent);
}
.qq-verify-input::placeholder { color: var(--qq-text-faint); font-weight: 400; }
.qq-verify-primary { width: 100%; border-radius: 999px; padding: 11px 16px; }
.qq-verify-links {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    margin-top: 12px; color: var(--qq-text-faint); font-size: .85rem;
}
.qq-verify-link {
    background: none; border: 0; padding: 4px 2px; cursor: pointer;
    color: var(--qq-text-muted); font-size: .85rem; font-weight: 500;
    text-decoration: underline; text-underline-offset: 3px;
    text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
}
.qq-verify-link:hover:not(:disabled) { color: var(--qq-brass); }
.qq-verify-link:disabled { opacity: .5; cursor: default; }
@keyframes qq-verify-fade { from { opacity: 0; } }
@keyframes qq-verify-pop { from { opacity: 0; transform: translateY(14px) scale(.96); } }
@keyframes qq-verify-shake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-5px); } 55% { transform: translateX(4px); } 80% { transform: translateX(-2px); }
}
@media (prefers-reduced-motion: reduce) {
    .qq-verify-backdrop, .qq-verify-card, .qq-verify-error { animation: none; }
}

/* ---- Explore v4 (spec 025): permanent facet rail + one blended stream ---- */
.qq-ex4 { max-width: 1440px; margin: 0 auto; }
.qq-ex4-head {
    display: flex; align-items: flex-end; gap: 22px; flex-wrap: wrap;
    margin-bottom: 22px; position: relative;
}
.qq-ex4-head > :first-child { flex: none; }
.qq-ex4-title { font-size: 34px; font-weight: 700; letter-spacing: -.04em; margin: 4px 0 0; }
.qq-ex4-tools { display: flex; align-items: center; gap: 10px; position: relative; flex: 1; min-width: 0; }
.qq-ex4-microlabel {
    font-family: ui-monospace, "Space Mono", monospace; font-size: 10.5px;
    letter-spacing: .07em; text-transform: uppercase; color: var(--qq-text-faint);
}
.qq-ex4-search {
    display: flex; align-items: center; gap: 9px; background: var(--qq-card);
    border: 1px solid var(--qq-border); border-radius: 14px; padding: 0 14px;
    box-shadow: 0 2px 10px rgba(23, 21, 18, .04); flex: 1; min-width: 0;
}
.qq-ex4-search svg { color: var(--qq-text-faint); flex: none; }
.qq-ex4-search input {
    border: 0; background: none; outline: none; font-size: 15px; width: 100%;
    color: var(--qq-text); font-family: inherit; padding: 14px 0; min-width: 0;
}
/* The "/" affordance from the design. Hidden on touch, where there is no key
   to press and it would just be furniture. */
.qq-ex4-slash {
    flex: none; font-family: ui-monospace, "Space Mono", monospace; font-size: 11px;
    color: var(--qq-text-faint); border: 1px solid var(--qq-border);
    border-radius: 6px; padding: 3px 8px;
}
@media (hover: none) { .qq-ex4-slash { display: none; } }
.qq-ex4-clear {
    border: 0; background: var(--qq-seg, #eeeae2); color: var(--qq-text-body);
    width: 24px; height: 24px; border-radius: 50%; cursor: pointer; line-height: 1;
}
.qq-ex4-sort {
    display: flex; flex-direction: column; gap: 1px; background: var(--qq-card);
    border: 1px solid var(--qq-border); border-radius: 14px; padding: 7px 14px;
    box-shadow: 0 2px 10px rgba(23, 21, 18, .04); cursor: pointer;
    flex: none; white-space: nowrap;
}
.qq-ex4-sort select {
    border: 0; background: none; outline: none; font-size: 13.5px; font-weight: 600;
    color: var(--qq-text); font-family: inherit; cursor: pointer; padding: 0;
}
.qq-ex4-star {
    flex: none; width: 48px; height: 48px; border-radius: 14px; background: var(--qq-card);
    border: 1px solid var(--qq-border); font-size: 19px; cursor: pointer;
    color: var(--qq-text); box-shadow: 0 2px 10px rgba(23, 21, 18, .04);
}
.qq-ex4-star.is-idle { color: var(--qq-text-faint); cursor: default; }
.qq-ex4-star.is-saved {
    background: #f7f2e7; border-color: var(--qq-brass-deep); color: var(--qq-brass-deep);
}
.qq-ex4-savepop {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 40; width: 320px;
    background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 16px;
    padding: 14px; box-shadow: 0 18px 44px rgba(23, 21, 18, .18); display: grid; gap: 8px;
}
.qq-ex4-savepop-sub { font-size: 12.5px; color: var(--qq-text-muted); margin: 0; }
.qq-ex4-savepop-note { font-size: 11.5px; color: var(--qq-text-faint); margin: 0; }
.qq-ex4-savepop-actions { display: flex; gap: 8px; justify-content: flex-end; }

.qq-ex4-body { display: grid; grid-template-columns: 272px 1fr; gap: 26px; align-items: start; }
.qq-ex4-rail {
    position: sticky; top: 16px; background: var(--qq-card); border: 1px solid var(--qq-border);
    border-radius: 20px; padding: 6px 14px 12px; display: grid; gap: 2px;
}
.qq-ex4-facet { padding: 12px 0; border-bottom: 1px solid var(--qq-border-soft, #f2eee6); display: grid; gap: 5px; }
.qq-ex4-facet:last-child { border-bottom: 0; }
.qq-ex4-row {
    display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
    background: none; border: 0; border-radius: 8px; padding: 6px 8px; cursor: pointer;
    font-size: 13.5px; color: var(--qq-text-body); font-family: inherit;
}
.qq-ex4-row:hover:not(:disabled) { background: var(--qq-paper); }
.qq-ex4-row.is-on { background: #f7f2e7; color: var(--qq-brass-deep); font-weight: 600; }
.qq-ex4-row.is-empty, .qq-ex4-row:disabled { color: #c2b9a6; cursor: default; }
.qq-ex4-row-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qq-ex4-count { font-family: ui-monospace, "Space Mono", monospace; font-size: 11.5px; color: inherit; opacity: .75; }
.qq-ex4-dot { width: 8px; height: 8px; border-radius: 2px; flex: none; background: var(--qq-text-faint); }
.qq-ex4-dot.store { background: var(--qq-text); }
.qq-ex4-dot.dish { background: var(--qq-brass); }
.qq-ex4-dot.service { background: #1d3557; }
.qq-ex4-days { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.qq-ex4-day {
    display: grid; gap: 1px; justify-items: center; padding: 6px 2px; border-radius: 8px;
    border: 1px solid var(--qq-border); background: var(--qq-card); cursor: pointer;
    font-size: 11.5px; color: var(--qq-text-body); font-family: inherit;
}
.qq-ex4-day.is-on { background: var(--qq-text); color: var(--qq-paper); border-color: var(--qq-text); }
.qq-ex4-day.is-empty, .qq-ex4-day:disabled { color: #c2b9a6; cursor: default; }
.qq-ex4-hint { font-size: 11.5px; color: var(--qq-text-faint); margin: 2px 0 0; line-height: 1.45; }
.qq-ex4-seg {
    display: flex; gap: 2px; background: var(--qq-seg, #eeeae2); border-radius: 999px; padding: 3px;
}
.qq-ex4-seg button {
    flex: 1; border: 0; background: none; border-radius: 999px; padding: 5px 10px;
    font-size: 12.5px; cursor: pointer; color: var(--qq-text-body); font-family: inherit;
}
.qq-ex4-seg button.is-on { background: var(--qq-card); font-weight: 600; color: var(--qq-text); }
.qq-ex4-seg button:disabled { color: #c2b9a6; cursor: default; }
.qq-ex4-seg-sm { flex: none; }
.qq-ex4-clearall {
    display: flex; align-items: center; justify-content: space-between; width: 100%;
    background: none; border: 1px solid var(--qq-border); border-radius: 8px;
    padding: 7px 9px; cursor: pointer; font-size: 13px; color: var(--qq-text); font-family: inherit;
}
.qq-ex4-empty-row {
    border: 1px dashed var(--qq-border); border-radius: 8px; padding: 9px;
    font-size: 12px; color: var(--qq-text-faint); margin: 0; line-height: 1.45;
}
.qq-ex4-saved-row { display: flex; align-items: center; gap: 4px; border-radius: 8px; }
.qq-ex4-saved-row.is-current { background: #f7f2e7; }
.qq-ex4-saved-row.is-current .qq-ex4-saved-label { color: var(--qq-brass-deep); font-weight: 600; }
.qq-ex4-saved-apply {
    display: flex; align-items: center; gap: 7px; flex: 1; min-width: 0; text-align: left;
    background: none; border: 0; padding: 6px 8px; cursor: pointer; font-size: 13px;
    color: var(--qq-text-body); font-family: inherit;
}
.qq-ex4-saved-star { color: var(--qq-gold-bright); flex: none; }
.qq-ex4-saved-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qq-ex4-facet-x {
    border: 0; background: none; color: var(--qq-text-faint); cursor: pointer;
    font-size: 16px; line-height: 1; padding: 4px 6px;
}
.qq-ex4-recent { display: flex; gap: 6px; }
.qq-ex4-recent-dot {
    width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
    color: #fff; font-weight: 700; font-size: 13px; text-decoration: none;
}

.qq-ex4-results { display: grid; gap: 12px; }
.qq-ex4-results-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.qq-ex4-h2 { font-size: 20px; font-weight: 700; letter-spacing: -.02em; margin: 0; }
.qq-ex4-sub { font-size: 12.5px; color: var(--qq-text-muted); margin: 3px 0 0; }
.qq-ex4-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.qq-ex4-chip {
    display: inline-flex; align-items: center; gap: 7px; background: var(--qq-text);
    color: var(--qq-paper); border: 0; border-radius: 999px; padding: 5px 12px;
    font-size: 12.5px; cursor: pointer; font-family: inherit;
}

.qq-ex4-stream { display: grid; gap: 10px; }
.qq-ex4-row-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.qq-ex4-row-title a { font-size: 14.5px; font-weight: 700; color: var(--qq-text); text-decoration: none; }
.qq-ex4-row-title a:hover { color: var(--qq-brass-deep); }
.qq-ex4-stream > .qq-ex4-row {
    display: flex; align-items: center; gap: 14px; background: var(--qq-card);
    border: 1px solid var(--qq-border); border-radius: 16px; padding: 15px 18px;
    cursor: default;
}
.qq-ex4-stream > .qq-ex4-row:hover { border-color: color-mix(in srgb, var(--qq-brass) 35%, var(--qq-border)); }
.qq-ex4-av {
    flex: none; display: grid; place-items: center; color: #fff;
    font-weight: 700; font-size: 17px; object-fit: cover;
}
.qq-ex4-av-store { width: 48px; height: 48px; border-radius: 12px; }
.qq-ex4-av-service { width: 42px; height: 42px; border-radius: 99px; }
.qq-ex4-av-dish { width: 42px; height: 42px; border-radius: 12px; }
.qq-ex4-av-blank {
    background: repeating-linear-gradient(135deg, #f4f0e8, #f4f0e8 10px, #efeadf 10px, #efeadf 20px);
}
.qq-ex4-row-main { flex: 1; min-width: 0; display: grid; gap: 4px; }
.qq-ex4-row-meta { font-size: 12.5px; color: var(--qq-text-muted); }
.qq-ex4-badge {
    font-family: ui-monospace, "Space Mono", monospace; font-size: 9.5px; letter-spacing: .07em;
    border-radius: 5px; padding: 2px 6px; flex: none;
}
.qq-ex4-badge-store { background: var(--qq-text); color: var(--qq-paper); }
.qq-ex4-badge-dish { background: var(--qq-brass-tint, #f0e6d2); color: var(--qq-brass-deep); }
.qq-ex4-badge-service { background: #e4ecf3; color: #1d3557; }
/* Goods get their own colour rather than borrowing the dish tint: the
   badge is the only thing on the row that says what sort of thing this is,
   so two kinds sharing one swatch defeats the point (spec 032). */
.qq-ex4-badge-goods { background: #e7eee9; color: #26543c; }
.qq-ex4-featured {
    background: var(--qq-brass-tint, #f0e6d2); color: var(--qq-brass-deep);
    font-size: 10.5px; border-radius: 999px; padding: 2px 8px; font-weight: 600;
}
.qq-ex4-tops { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 2px; }
.qq-ex4-top {
    background: var(--qq-paper); border-radius: 999px; padding: 3px 9px;
    font-size: 11.5px; color: var(--qq-text-body);
}
.qq-ex4-row-price { text-align: right; flex: none; display: grid; gap: 2px; }
.qq-ex4-price { font-size: 14px; font-weight: 700; color: var(--qq-brass-deep); }
.qq-ex4-status { font-size: 11.5px; }
.qq-ex4-status.is-good { color: var(--qq-open-green, #1d6b3f); }
.qq-ex4-status.is-warn { color: var(--qq-closed-amber, #a05a2c); }
.qq-ex4-slots { display: flex; gap: 5px; flex: none; align-items: center; }
.qq-ex4-slot {
    font-family: ui-monospace, "Space Mono", monospace; font-size: 11.5px;
    border: 1px solid var(--qq-border); background: var(--qq-card); border-radius: 8px;
    padding: 5px 8px; cursor: pointer; color: var(--qq-text-body);
}
.qq-ex4-slot.is-on { background: var(--qq-text); color: var(--qq-paper); border-color: var(--qq-text); }
.qq-ex4-slot-more { font-size: 11px; color: var(--qq-text-faint); }
.qq-ex4-cta {
    flex: none; border-radius: 999px; padding: 8px 16px; font-size: 13px; font-weight: 600;
    text-decoration: none; border: 1px solid var(--qq-border); background: var(--qq-card);
    color: var(--qq-text);
}
.qq-ex4-cta.is-ink { background: var(--qq-text); color: var(--qq-paper); border-color: var(--qq-text); }
.qq-ex4-more { display: flex; justify-content: center; padding: 6px 0 2px; }

.qq-ex4-rail-sec { display: grid; gap: 10px; margin-bottom: 8px; }
.qq-ex4-rail-sec header { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; }
.qq-ex4-rail-sec h3 { font-size: 16px; font-weight: 700; letter-spacing: -.02em; margin: 0; }
.qq-ex4-rail-sec header p { font-size: 12.5px; color: var(--qq-text-muted); margin: 2px 0 0; }
.qq-ex4-seeall {
    background: none; border: 0; color: var(--qq-brass); font-size: 13px; cursor: pointer;
    font-family: inherit; font-weight: 600;
}
.qq-ex4-cards { display: grid; gap: 12px; }
.qq-ex4-cards-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.qq-ex4-cards-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.qq-ex4-card {
    background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 16px;
    overflow: hidden; text-decoration: none; color: inherit; display: grid;
}
.qq-ex4-card:hover { border-color: color-mix(in srgb, var(--qq-brass) 35%, var(--qq-border)); }
.qq-ex4-card-band { height: 76px; position: relative; }
.qq-ex4-card-band-dish {
    background: repeating-linear-gradient(135deg, #f4f0e8, #f4f0e8 10px, #efeadf 10px, #efeadf 20px);
}
.qq-ex4-card-band-deal { background: linear-gradient(150deg, var(--qq-brass), var(--qq-gold-bright)); }
.qq-ex4-card-badge {
    position: absolute; top: 8px; left: 8px; background: rgba(255, 255, 255, .92);
    font-family: ui-monospace, "Space Mono", monospace; font-size: 9.5px; letter-spacing: .07em;
    border-radius: 5px; padding: 2px 6px; color: var(--qq-text);
}
.qq-ex4-card-flag {
    position: absolute; top: 8px; right: 8px; background: var(--qq-brass-tint, #f0e6d2);
    color: var(--qq-brass-deep); font-size: 10.5px; border-radius: 999px; padding: 2px 8px; font-weight: 600;
}
.qq-ex4-card-body { padding: 11px 13px 13px; display: grid; gap: 3px; }
.qq-ex4-card-name { font-size: 13.5px; font-weight: 700; }
.qq-ex4-card-meta { font-size: 12px; color: var(--qq-text-muted); }
.qq-ex4-card-tail { font-size: 12.5px; font-weight: 700; color: var(--qq-brass-deep); }

.qq-ex4-nores {
    display: grid; gap: 10px; justify-items: center; text-align: center;
    padding: 46px 20px; background: var(--qq-card); border: 1px solid var(--qq-border);
    border-radius: 20px;
}
.qq-ex4-nores-badge {
    width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center;
    background: var(--qq-brass-tint, #f0e6d2); color: var(--qq-brass-deep); font-size: 22px;
}
.qq-ex4-nores h3 { margin: 0; font-size: 17px; }
.qq-ex4-nores p { margin: 0; font-size: 13px; color: var(--qq-text-muted); }

.qq-ex4-bookbar {
    position: sticky; bottom: 0; z-index: 30; margin-top: 14px;
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    background: var(--qq-text); color: var(--qq-paper); border-radius: 16px; padding: 12px 18px;
}
.qq-ex4-bookbar .qq-ex4-microlabel { color: rgba(255, 255, 255, .6); }

/* Below the rail's own width the facets fold back to a panel above the results,
   which is where they lived before v4 -- with their counts, so it is still an
   upgrade on the old Filters button. */
@media (max-width: 1080px) {
    .qq-ex4-body { grid-template-columns: 1fr; }
    .qq-ex4-rail { position: static; }
    .qq-ex4-cards-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .qq-ex4-cards-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
    /* The toolbar is one elastic row on a desktop; here the sort control and
       the star would squeeze the field down to nothing, so the search takes a
       line of its own and they sit under it. */
    .qq-ex4-head { flex-direction: column; align-items: stretch; gap: 14px; }
    .qq-ex4-tools { flex-wrap: wrap; }
    .qq-ex4-search { flex: 1 0 100%; }
    .qq-ex4-savepop { left: 0; right: auto; width: 100%; }
    .qq-ex4-stream > .qq-ex4-row { flex-wrap: wrap; padding: 12px 16px; }
    .qq-ex4-row-main { flex-basis: 100%; order: 2; }
    .qq-ex4-slots, .qq-ex4-cta { order: 3; }
    .qq-ex4-cards-4, .qq-ex4-cards-3 { grid-template-columns: 1fr; }
    .qq-ex4-search { min-width: 0; }
}

/* Read state on your own messages (spec 027): one tick sent, two ticks seen. */
.qq-msg-seen { margin-left: 5px; color: var(--qq-text-faint); letter-spacing: -1px; }
.qq-msg-seen.is-seen { color: var(--qq-brass); }

/* Reading the email and phone back before sign-up (spec 030). The values are
   the point, so they get the weight — a typo has to be legible to be caught. */
.qq-confirm-label {
    margin: 14px 0 2px; font-size: .72rem; font-weight: 600; letter-spacing: .09em;
    text-transform: uppercase; color: var(--qq-text-faint);
}
.qq-confirm-value {
    margin: 0; font-size: 1.05rem; font-weight: 600; line-height: 1.4;
    word-break: break-all; color: var(--qq-text);
}
.qq-confirm-value:last-of-type { margin-bottom: 20px; }
body.qq-noscroll { overflow: hidden; }

/* Stock state on a storefront card, and the store's return policy (spec 032).
   Only finite things get these — a food product shows nothing at all. */
.sf-stock { display: block; margin-top: .35rem; font-size: .78rem; font-weight: 600; }
.sf-stock-low { color: var(--qq-brass); }
.sf-stock-out { color: var(--qq-text-faint); }
.sf-store-returns { margin: .5rem 0 0; font-size: .82rem; color: var(--sf-muted, var(--qq-text-muted)); }
.qq-receipt-returns { margin-top: 1rem; font-size: .82rem; color: var(--qq-text-muted); }

/* Reports: the food/goods split and the stock panel (spec 032 follow-up). Both
   are conditional sections — a food-only shop sees neither — so they style as
   self-contained cards rather than assuming a neighbour. */
.qq-rpt-split, .qq-rpt-stock {
    background: var(--qq-card); border: 1px solid var(--qq-border);
    border-radius: 16px; padding: 14px 16px; margin-bottom: 14px;
}
.qq-rpt-split-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.qq-rpt-split-head > span:first-child { font-size: 13px; font-weight: 700; }
.qq-rpt-split-bar {
    display: flex; height: 12px; border-radius: 999px; overflow: hidden;
    background: var(--qq-paper);
}
.qq-rpt-split-bar .food { background: #d9a94e; }
.qq-rpt-split-bar .goods { background: #26543c; }
.qq-rpt-split-keys { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 10px; font-size: 12.5px; }
.qq-rpt-split-keys i { display: inline-block; width: 9px; height: 9px; border-radius: 3px; margin-right: 6px; }
.qq-rpt-split-keys i.food { background: #d9a94e; }
.qq-rpt-split-keys i.goods { background: #26543c; }
.qq-rpt-split-keys b { margin-left: 6px; }

.qq-rpt-stock-list { display: grid; gap: 6px; margin-top: 8px; }
.qq-rpt-stock-row {
    display: flex; align-items: center; gap: 10px; text-decoration: none; color: inherit;
    padding: 7px 10px; border-radius: 10px; background: var(--qq-paper);
}
.qq-rpt-stock-row:hover { background: color-mix(in srgb, var(--qq-brass) 12%, var(--qq-paper)); }
.qq-rpt-stock-row .nm { flex: 1; min-width: 0; font-size: 13px; }
.qq-promo-chip.is-out { background: var(--qq-danger-bg, #f7e3e0); color: var(--qq-danger-fg, #8d3a30); }
.qq-promo-chip.is-low { background: var(--qq-brass-tint, #f0e6d2); color: var(--qq-brass-deep); }

/* ---------------------------------------------------------------------------
   Seller schedule — /seller/appointments (design handoff: "Seller Appointments")

   Three views of the same bookings: an hour RAIL for one day, a LIST of
   everything upcoming, and PAST. The rail is the reason this exists: a day is
   a shape — where the gaps are, how long they run — and a vertical list of
   rows cannot show a shape. Everything here is absolute-positioned against a
   56px hour, so every offset is (minutes / 60) * 56.
--------------------------------------------------------------------------- */

.qq-seller-page { max-width: 1080px; }

/* --- page header ---------------------------------------------------------- */
.qq-seller-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 24px; margin-bottom: 22px; flex-wrap: wrap;
}
.qq-seller-eyebrow {
    font: 700 10.5px/1 var(--qq-admin-mono); letter-spacing: .14em;
    color: var(--qq-text-faint); margin-bottom: 10px;
}
.qq-seller-title {
    margin: 0; font: 400 44px/1 'Instrument Serif', Georgia, serif;
    letter-spacing: -.01em; color: var(--qq-ink);
}
.qq-seller-headright { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.qq-seller-search {
    width: 276px; max-width: 100%; box-sizing: border-box;
    background: var(--qq-card); border: 1px solid var(--qq-border);
    border-radius: 10px; padding: 9px 13px;
    font: 400 13px/1.2 'Space Grotesk', system-ui, sans-serif;
    color: var(--qq-text); outline: none;
}
.qq-seller-search:focus { border-color: var(--qq-brass); }
.qq-seller-switch {
    display: inline-flex; background: var(--qq-mute-bg);
    border-radius: 10px; padding: 3px; gap: 2px;
}
.qq-seller-switch button {
    appearance: none; border: 0; background: none; border-radius: 8px;
    padding: 7px 15px; font: 500 12.5px/1 'Space Grotesk', system-ui, sans-serif;
    color: var(--qq-text-muted); cursor: pointer;
}
.qq-seller-switch button:hover { color: var(--qq-ink); }
.qq-seller-switch button.is-on {
    background: var(--qq-card); box-shadow: 0 1px 3px rgba(23, 21, 18, .12);
    font-weight: 600; color: var(--qq-ink);
}

/* --- day strip ------------------------------------------------------------ */
.qq-appt-nav { position: relative; }
.qq-appt-striprow { display: flex; align-items: stretch; gap: 8px; margin-bottom: 8px; }
.qq-appt-strip { display: flex; align-items: stretch; gap: 8px; flex: 1; min-width: 0; }
.qq-appt-monthstack {
    display: flex; flex-direction: column; justify-content: center; padding-right: 4px;
    font: 700 10.5px/1.5 var(--qq-admin-mono); letter-spacing: .1em;
    color: var(--qq-text-faint);
}
.qq-appt-step {
    appearance: none; align-self: stretch; width: 30px; flex: 0 0 30px;
    background: var(--qq-card); border: 1px solid var(--qq-border);
    border-radius: 10px; cursor: pointer;
    font: 400 14px/1 var(--qq-admin-mono); color: var(--qq-text-muted);
    transition: border-color .12s ease, color .12s ease;
}
.qq-appt-step:hover { border-color: var(--qq-brass); color: var(--qq-ink); }

.qq-appt-daytab {
    appearance: none; display: flex; flex-direction: column; align-items: center;
    gap: 2px; padding: 9px 15px; border-radius: 12px; cursor: pointer;
    background: var(--qq-card); border: 1px solid var(--qq-border);
    color: var(--qq-ink); transition: border-color .12s ease, background .12s ease;
}
.qq-appt-daytab:hover { border-color: var(--qq-brass); }
.qq-appt-daytab .wd { font: 700 9.5px/1 var(--qq-admin-mono); letter-spacing: .1em; color: var(--qq-text-faint); }
.qq-appt-daytab .dt { font: 400 22px/1.05 'Instrument Serif', Georgia, serif; }
.qq-appt-daytab .ct { font: 700 9.5px/1 var(--qq-admin-mono); letter-spacing: .06em; color: var(--qq-text-faint); }
.qq-appt-daytab .ct.has { color: var(--qq-text-muted); }
.qq-appt-daytab.is-today { border-color: var(--qq-gold-soft); }
.qq-appt-daytab.is-today .wd { color: var(--qq-brass); }
.qq-appt-daytab.is-closed { background: var(--qq-paper); border-style: dashed; border-color: var(--qq-border); color: var(--qq-text-faint); }
.qq-appt-daytab.is-closed .wd, .qq-appt-daytab.is-closed .ct { color: var(--qq-text-faint); }
.qq-appt-daytab.is-on { background: var(--qq-ink); border-color: var(--qq-ink); color: var(--qq-paper); }
.qq-appt-daytab.is-on .wd { color: inherit; opacity: .72; }
/* Drawn ON an ink fill, which inverts in dark — so this cannot be gold. */
.qq-appt-daytab.is-on .ct, .qq-appt-daytab.is-on .ct.has { color: var(--qq-on-ink-accent); }
.qq-appt-daytab.is-on.is-closed { border-style: dashed; border-color: var(--qq-text-body); }

.qq-appt-jump {
    appearance: none; align-self: center; background: var(--qq-card);
    border: 1px solid var(--qq-border); color: var(--qq-text-body);
    font: 600 12px/1 'Space Grotesk', system-ui, sans-serif;
    padding: 9px 13px; border-radius: 9px; cursor: pointer;
    transition: border-color .12s ease, color .12s ease;
}
.qq-appt-jump:hover { border-color: var(--qq-brass); color: var(--qq-ink); }

/* --- month popover -------------------------------------------------------- */
.qq-appt-cal {
    position: absolute; top: 100%; right: 0; margin-top: 6px; width: 306px;
    background: var(--qq-card); border: 1px solid var(--qq-border);
    border-radius: 14px; box-shadow: 0 14px 40px rgba(23, 21, 18, .16);
    padding: 14px; z-index: 20; box-sizing: border-box;
}
.qq-appt-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.qq-appt-cal-head span { font: 400 17px/1 'Instrument Serif', Georgia, serif; color: var(--qq-ink); }
.qq-appt-cal-head button {
    appearance: none; border: 0; background: none; cursor: pointer; padding: 2px 6px;
    font: 400 11px/1 var(--qq-admin-mono); letter-spacing: .06em; color: var(--qq-text-muted);
}
.qq-appt-cal-head button:hover { color: var(--qq-ink); }
.qq-appt-cal-dow, .qq-appt-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.qq-appt-cal-dow { margin-bottom: 4px; }
.qq-appt-cal-dow span {
    text-align: center; font: 700 9px/1.6 var(--qq-admin-mono);
    letter-spacing: .06em; color: var(--qq-text-faint);
}
.qq-appt-cal-cell {
    position: relative; appearance: none; height: 34px; border: 1px solid transparent;
    border-radius: 8px; background: none; cursor: pointer;
    font: 400 13px/1 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-body);
}
.qq-appt-cal-cell:hover { background: var(--qq-paper); }
.qq-appt-cal-cell.is-past { color: var(--qq-text-ghost); cursor: default; }
.qq-appt-cal-cell.is-past:hover { background: none; }
.qq-appt-cal-cell.is-today { border-color: var(--qq-gold-soft); font-weight: 700; }
.qq-appt-cal-cell.is-closed { border-style: dashed; border-color: var(--qq-border); }
.qq-appt-cal-cell.is-on { background: var(--qq-ink); color: var(--qq-paper); font-weight: 700; border-color: var(--qq-ink); }
.qq-appt-cal-cell .dot {
    position: absolute; bottom: 4px; left: 50%; width: 4px; height: 4px;
    margin-left: -2px; border-radius: 50%; background: var(--qq-gold-bright);
}
.qq-appt-cal-cell.is-on .dot { display: none; }
.qq-appt-cal-foot {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--qq-border-soft);
}
.qq-appt-cal-foot button {
    appearance: none; border: 0; background: none; padding: 0; cursor: pointer;
    font: 600 11.5px/1 'Space Grotesk', system-ui, sans-serif; color: var(--qq-brass);
}
.qq-appt-cal-foot button:hover { color: var(--qq-brass-deep); }
.qq-appt-calnote { font: 400 11.5px/1 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-faint); }

/* --- day heading ---------------------------------------------------------- */
.qq-appt-dayhead { display: flex; align-items: baseline; gap: 12px; margin: 18px 0 10px; flex-wrap: wrap; }
.qq-appt-dayhead .date { font: 400 21px/1.1 'Instrument Serif', Georgia, serif; color: var(--qq-ink); }
.qq-appt-dayhead .totals,
.qq-appt-dayhead .tz { font: 700 10.5px/1 var(--qq-admin-mono); letter-spacing: .08em; color: var(--qq-text-faint); }
.qq-appt-dayhead .tz { font-weight: 400; }
.qq-appt-dayhead .rule { flex: 1; min-width: 20px; height: 1px; background: var(--qq-border); }

/* --- the rail ------------------------------------------------------------- */
.qq-rail {
    background: var(--qq-card); border: 1px solid var(--qq-border);
    border-radius: 16px; padding: 16px 18px 20px;
}
.qq-rail-grid { position: relative; }
.qq-rail-vrule { position: absolute; left: 60px; top: 0; bottom: 0; width: 1px; background: var(--qq-border-soft); }
.qq-rail-hline { position: absolute; left: 0; right: 0; height: 1px; background: var(--qq-border-soft); }
.qq-rail-hlabel {
    position: absolute; left: 0; font: 400 10.5px/1 var(--qq-admin-mono);
    letter-spacing: .04em; color: var(--qq-text-faint);
}
/* Open time reads as texture, not as a block with content in it. */
.qq-rail-gap {
    position: absolute; left: 74px; right: 4px; border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    font: 400 11px/1 var(--qq-admin-mono); letter-spacing: .06em;
    color: var(--qq-text-ghost); overflow: hidden; text-align: center; padding: 0 8px;
    box-sizing: border-box;
    background: repeating-linear-gradient(45deg, var(--qq-paper) 0 8px, var(--qq-card) 8px 16px);
}
.qq-rail-now { position: absolute; left: 56px; right: 0; height: 1px; background: var(--qq-gold-bright); z-index: 4; }
.qq-rail-now-dot {
    position: absolute; left: 52px; width: 9px; height: 9px; margin-top: -4px;
    border-radius: 50%; background: var(--qq-gold-bright); z-index: 5;
}
.qq-rail-now-chip {
    position: absolute; right: 6px; background: var(--qq-gold-bright);
    /* Gold is the SAME value in both themes, so this text cannot be --qq-ink:
       it flips to ivory in dark and drops the chip to ~1.9:1. */
    color: #171512; font: 700 9.5px/1 var(--qq-admin-mono); letter-spacing: .06em;
    padding: 4px 6px; border-radius: 5px; z-index: 5;
}

/* --- a booking, compact --------------------------------------------------- */
.qq-rail-block {
    position: absolute; left: 74px; right: 4px; box-sizing: border-box;
    background: var(--qq-paper); border: 1px solid var(--qq-border);
    border-radius: 10px; padding: 0 14px; overflow: hidden;
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 14px; align-items: center;
    transition: background .12s ease, border-color .12s ease;
}
.qq-rail-block:hover { background: var(--qq-card); border-color: var(--qq-gold-soft); }
.qq-rail-block.is-bad { background: var(--qq-bad-bg-soft); border-color: var(--qq-bad-border); }
/* A half-hour service draws a block too short for two lines and a button. It
   keeps its real geometry — that is the whole point of a rail — and gives up
   the buyer line instead of overflowing into the next booking. */
.qq-rail-block.is-dense { padding: 0 10px; gap: 10px; }
.qq-rail-block.is-dense .qq-rail-l2, .qq-rail-block.is-dense .qq-appt-claim { display: none; }
.qq-rail-block.is-dense .qq-rail-l1 { flex-wrap: nowrap; overflow: hidden; }
.qq-rail-block.is-dense .qq-rail-l1 .svc { font-size: 13.5px; white-space: nowrap; }
.qq-rail-block.is-dense .qq-seller-btn { padding: 6px 9px; font-size: 11.5px; }
.qq-rail-block.is-bad:hover { background: var(--qq-bad-bg-soft); border-color: var(--qq-bad-border); }

/* --- a booking, expanded -------------------------------------------------- */
.qq-rail-block.is-open {
    background: var(--qq-card); border-color: var(--qq-gold-soft); border-radius: 12px;
    box-shadow: 0 8px 24px rgba(23, 21, 18, .14); padding: 12px 14px;
    display: grid; grid-template-columns: minmax(0, 1fr) 178px; gap: 16px;
    align-items: start; z-index: 6; overflow: auto;
}
.qq-rail-block.is-open.is-bad { border-color: var(--qq-bad-border-2); }

.qq-rail-l1 { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.qq-rail-l1 .t { font: 400 11px/1.5 var(--qq-admin-mono); letter-spacing: .04em; color: var(--qq-text-muted); white-space: nowrap; }
.qq-rail-l1 .svc { font: 600 14.5px/1.2 'Space Grotesk', system-ui, sans-serif; color: var(--qq-ink); }
.qq-rail-l1 .amt { font: 600 13px/1.2 'Space Grotesk', system-ui, sans-serif; color: var(--qq-brass); }
.is-open .qq-rail-l1 .svc { font-size: 15px; }
.is-open .qq-rail-l1 .amt { font-size: 13.5px; }
.qq-status-line { font: 700 10.5px/1.5 var(--qq-admin-mono); letter-spacing: .06em; color: var(--qq-text-muted); white-space: nowrap; }
.qq-status-line.ok { color: var(--qq-ok-btn); }
.qq-status-line.warn { color: var(--qq-warn-fg); }
.qq-status-line.bad { color: var(--qq-bad-fg); }
.qq-rail-l2 { font: 400 12.5px/1.4 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted); margin-top: 3px; }
.is-open .qq-rail-l2 { line-height: 1.5; margin-top: 4px; }
.qq-appt-claim {
    font: italic 400 12.5px/1.4 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted);
    margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* The value column is minmax(0,1fr), which is what stops a long code + payment
   line from being clipped the way the old <dl> clipped it. */
.qq-appt-dl {
    display: grid; grid-template-columns: max-content minmax(0, 1fr);
    gap: 6px 14px; margin: 9px 0 0; align-items: baseline;
}
.qq-appt-dl dt {
    font: 700 9.5px/1.4 var(--qq-admin-mono); letter-spacing: .1em;
    color: var(--qq-text-faint); margin: 0;
}
.qq-appt-dl dd {
    font: 500 12.5px/1.4 'Space Grotesk', system-ui, sans-serif;
    color: var(--qq-ink); margin: 0; min-width: 0;
}
.qq-appt-dl dt.warn, .qq-appt-dl dd.warn { color: var(--qq-warn-fg); }

.qq-appt-disputebox {
    background: var(--qq-bad-bg-soft); border: 1px solid var(--qq-bad-border);
    border-radius: 9px; padding: 10px 12px; margin-top: 9px;
}
.qq-appt-disputebox .lbl { font: 700 9.5px/1.4 var(--qq-admin-mono); letter-spacing: .1em; color: var(--qq-bad-fg); }
.qq-appt-disputebox .said { font: italic 400 12.5px/1.5 'Space Grotesk', system-ui, sans-serif; color: var(--qq-ink); }
.qq-appt-disputebox .when { font: 400 10.5px/1.5 var(--qq-admin-mono); color: var(--qq-text-faint); }

.qq-seller-links { display: flex; gap: 16px; margin-top: 9px; flex-wrap: wrap; }
.qq-seller-links button {
    appearance: none; border: 0; background: none; padding: 0; cursor: pointer;
    font: 600 12px/1 'Space Grotesk', system-ui, sans-serif;
}
.qq-seller-links .hide { color: var(--qq-ink); }
.qq-seller-links .hide:hover { color: var(--qq-brass); }
.qq-seller-links .chat { color: var(--qq-brass); }
.qq-seller-links .chat:hover { color: var(--qq-brass-deep); }

/* --- actions -------------------------------------------------------------- */
.qq-seller-inline { display: flex; gap: 7px; align-items: center; }
.qq-seller-actions { display: flex; flex-direction: column; gap: 7px; }
.qq-seller-btn {
    appearance: none; border: 1px solid transparent; border-radius: 8px;
    padding: 9px 12px; cursor: pointer; text-align: center;
    font: 600 12px/1 'Space Grotesk', system-ui, sans-serif;
    transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.qq-seller-actions .qq-seller-btn { width: 100%; border-radius: 9px; padding: 10px 12px; font-size: 12.5px; }
.qq-seller-btn:disabled { opacity: .55; cursor: default; }
.qq-seller-btn.ink { background: var(--qq-ink); color: var(--qq-paper); }
.qq-seller-btn.ink:hover:not(:disabled) { background: var(--qq-ink-hover); }
/* --qq-ok-btn is LIGHT green in dark mode, so the text follows the card, not
   white. Both directions pass; hard-coding #fff would fail one of them. */
.qq-seller-btn.ok { background: var(--qq-ok-btn); color: var(--qq-card); }
.qq-seller-btn.ok:hover:not(:disabled) { background: var(--qq-ok-btn-hover); }
.qq-seller-btn.sec { background: var(--qq-paper); border-color: var(--qq-border); color: var(--qq-text-body); }
.qq-seller-btn.sec:hover:not(:disabled) { border-color: var(--qq-brass); color: var(--qq-ink); }
.qq-seller-btn.ghost { background: var(--qq-card); border-color: var(--qq-border); color: var(--qq-text-body); }
.qq-seller-btn.ghost:hover:not(:disabled) { border-color: var(--qq-brass); color: var(--qq-ink); }
.qq-seller-btn.danger { background: none; border-color: transparent; color: var(--qq-bad-fg); padding: 3px 0 0; }
.qq-seller-btn.danger:hover:not(:disabled) { color: var(--qq-bad-fg-hover); }
.qq-seller-cap { font: 400 10.5px/1.4 var(--qq-admin-mono); color: var(--qq-text-faint); }
.qq-seller-noaction { font: 400 11px/1 var(--qq-admin-mono); color: var(--qq-text-faint); white-space: nowrap; }

/* --- below the rail ------------------------------------------------------- */
.qq-appt-more { font: 400 12px/1.5 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted); margin-top: 12px; }
.qq-appt-more button {
    appearance: none; border: 0; background: none; padding: 0; cursor: pointer;
    font: 600 12px/1.5 'Space Grotesk', system-ui, sans-serif; color: var(--qq-brass);
}
.qq-appt-more button:hover { color: var(--qq-brass-deep); }

/* --- empty / closed day --------------------------------------------------- */
.qq-seller-empty {
    background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 16px;
    padding: 64px 24px; text-align: center;
}
.qq-seller-empty.is-closed {
    border-style: dashed; border-color: var(--qq-border);
    background: repeating-linear-gradient(45deg, var(--qq-paper) 0 10px, var(--qq-card) 10px 20px);
}
.qq-seller-empty h2 { font: 400 26px/1.2 'Instrument Serif', Georgia, serif; color: var(--qq-ink); margin: 0 0 8px; }
.qq-seller-empty p { font: 400 13px/1.6 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted); margin: 0 auto 16px; max-width: 34rem; }
.qq-seller-empty .acts { display: flex; gap: 9px; justify-content: center; flex-wrap: wrap; }

/* --- list / past ---------------------------------------------------------- */
.qq-seller-listhead { display: flex; align-items: baseline; gap: 12px; margin: 4px 0 10px; flex-wrap: wrap; }
.qq-seller-listhead .h { font: 400 21px/1.1 'Instrument Serif', Georgia, serif; color: var(--qq-ink); }
.qq-seller-listhead .m { font: 700 10.5px/1 var(--qq-admin-mono); letter-spacing: .08em; color: var(--qq-text-faint); }
.qq-seller-listhead .rule { flex: 1; min-width: 20px; height: 1px; background: var(--qq-border); }
.qq-seller-clear {
    appearance: none; background: var(--qq-brass-tint); border: 1px solid var(--qq-brass-soft);
    color: var(--qq-brass-deep); border-radius: 999px; padding: 5px 11px; cursor: pointer;
    font: 600 11.5px/1 'Space Grotesk', system-ui, sans-serif;
}
.qq-seller-card { background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 16px; overflow: hidden; }
.qq-appt-divider {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    background: var(--qq-paper); border-bottom: 1px solid var(--qq-border);
    padding: 11px 18px; font: 700 10.5px/1 var(--qq-admin-mono); letter-spacing: .1em;
    color: var(--qq-ink);
}
.qq-appt-divider .n { color: var(--qq-text-faint); }
.qq-appt-row {
    display: grid; grid-template-columns: 130px minmax(0, 1fr) auto; gap: 16px;
    align-items: center; padding: 13px 18px; border-bottom: 1px solid var(--qq-border-soft);
}
.qq-appt-row:last-child { border-bottom: 0; }
.qq-appt-row:hover { background: var(--qq-row-hover); }
.qq-appt-row .when { font: 400 11.5px/1.5 var(--qq-admin-mono); letter-spacing: .04em; color: var(--qq-text-body); }
.qq-appt-row.is-bad, .qq-appt-row.is-bad:hover { background: var(--qq-bad-bg-soft); }
/* Money you owe is a job, not a record — it is lifted to the top and tinted. */
.qq-appt-row.is-owed, .qq-appt-row.is-owed:hover { background: var(--qq-warn-bg); border-bottom-color: var(--qq-warn-border); }
.qq-appt-row.is-owed .when { color: var(--qq-warn-fg); }
.qq-appt-row.is-quiet .qq-rail-l1 .svc { color: var(--qq-text-body); font-weight: 500; }
.qq-appt-row.is-quiet .qq-rail-l1 .amt { color: var(--qq-text-muted); }
.qq-appt-meta {
    font: 400 11px/1.5 var(--qq-admin-mono); letter-spacing: .02em;
    color: var(--qq-text-faint); margin-top: 3px;
}

/* --- chat drawer ---------------------------------------------------------- */
/* Fixed, not inline: the old inline panel made the row thousands of pixels
   tall and pushed its own composer off the bottom of the page. */
.qq-scrim { position: fixed; inset: 0; background: rgba(23, 21, 18, .28); z-index: 1040; border: 0; padding: 0; }
.qq-drawer {
    position: fixed; top: 50%; right: 0; transform: translateY(-50%);
    width: 372px; max-width: 100vw; height: 620px; max-height: 92vh;
    background: var(--qq-card); border: 1px solid var(--qq-border); border-right: 0;
    border-radius: 18px 0 0 18px; box-shadow: -14px 0 44px rgba(23, 21, 18, .22);
    z-index: 1041; display: flex; flex-direction: column; overflow: hidden;
}

/* Docked variant, for chat opened from a STOREFRONT.
   The modal treatment — a dark wash over the whole page and a card floating in
   the middle of it — is right on an admin list, where the list is the only
   thing on screen. Over a shop it reads as the page having broken: the photos
   and the theme go grey and a panel appears detached in the middle of them.
   Docked, it reads as what it is: a chat you opened, with the shop still there
   behind it. Lifted clear of the help button, which is fixed in the same
   corner at the same z-index. */
.qq-drawer.is-docked {
    top: auto;
    bottom: calc(max(1.25rem, env(safe-area-inset-bottom)) + 3.25rem + 0.75rem);
    right: max(1.25rem, env(safe-area-inset-right));
    transform: none;
    height: min(560px, calc(100dvh - 10rem));
    border-radius: 18px;
    border-right: 1px solid var(--qq-border);
}

/* The docked chat is position:fixed, but a fixed element still PAINTS inside
   its ancestors' stacking context — and .sf-identity (z-index: 2, so the card
   floats over the cover photo) is one. Trapped at an effective z of 2, the
   chat lost to the sticky tab bar at z 40, and the sort dropdown drew on top
   of the conversation. Boosted only while a drawer is actually open inside it:
   the rest of the time the card keeps its normal layer, so it cannot ride over
   the sticky bar during ordinary scrolling. */
.sf-identity:has(.qq-drawer) { z-index: 1041; }

/* On a phone there is no room to dock beside anything: take the width and sit
   above the help button. */
@media (max-width: 560px) {
    .qq-drawer.is-docked {
        left: max(0.75rem, env(safe-area-inset-left));
        right: max(0.75rem, env(safe-area-inset-right));
        width: auto;
        height: min(70dvh, calc(100dvh - 9rem));
    }
}

.qq-drawer-head {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
    padding: 16px 18px; border-bottom: 1px solid var(--qq-border-soft);
}
.qq-drawer-head .k { font: 700 10px/1.4 var(--qq-admin-mono); letter-spacing: .1em; color: var(--qq-text-faint); }
.qq-drawer-head .n { font: 600 15.5px/1.3 'Space Grotesk', system-ui, sans-serif; color: var(--qq-ink); }
.qq-drawer-head .s { font: 400 12px/1.4 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted); }
.qq-drawer-close {
    appearance: none; width: 28px; height: 28px; flex: 0 0 28px;
    background: var(--qq-paper); border: 1px solid var(--qq-border); border-radius: 8px;
    color: var(--qq-text-body); cursor: pointer; line-height: 1;
}
.qq-drawer-close:hover { border-color: var(--qq-brass); color: var(--qq-ink); }
.qq-drawer-body { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.qq-drawer-body > * { flex: 1; min-height: 0; }
/* MessageThread keeps its own markup — bubbles, timestamps, read ticks, emoji
   palette, composer. Only the CONTAINER changes: it stops being a 46rem card
   with a fixed 24rem scroller and becomes the drawer's flexible middle, so the
   composer is always reachable however long the thread is. */
.qq-drawer-body .qq-msg-thread {
    max-width: none; border: 0; border-radius: 0; box-shadow: none;
    background: transparent; flex: 1; min-height: 0;
}
.qq-drawer-body .qq-msg-head { display: none; }
.qq-drawer-body .qq-msg-scroll { height: auto; flex: 1; min-height: 0; }
.qq-drawer-body .mt-2.w-100 { display: flex; flex-direction: column; flex: 1; min-height: 0; margin-top: 0 !important; }

/* --- propose a new time --------------------------------------------------- */
.qq-seller-dialog {
    position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 416px; max-width: calc(100vw - 32px); box-sizing: border-box;
    background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 20px;
    box-shadow: 0 24px 60px rgba(23, 21, 18, .28); padding: 20px; z-index: 1051;
    /* NOT overflow:auto. The date and time pickers open an absolutely
       positioned popover that is taller and wider than this box, so clipping it
       gave the dialog two scrollbars and cut the picker in half the moment you
       touched a field. Below 768px the pickers become fixed bottom sheets and
       escape on their own, so the scroll guard is reinstated there — see the
       media query below. */
    overflow: visible;
}
@media (max-width: 768px) {
    .qq-seller-dialog { max-height: calc(100vh - 32px); overflow: auto; }
}
.qq-seller-dialog .k { font: 700 10.5px/1.4 var(--qq-admin-mono); letter-spacing: .1em; color: var(--qq-text-faint); margin-bottom: 8px; }
.qq-seller-dialog .lead { font: 400 13px/1.55 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted); margin: 0 0 14px; }
.qq-seller-dialog .hint { font: 400 12px/1.55 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted); margin: 0 0 16px; }
.qq-seller-dialog textarea {
    width: 100%; box-sizing: border-box; background: var(--qq-paper);
    border: 1px solid var(--qq-border); border-radius: 12px; padding: 10px 12px;
    font: 400 13px/1.5 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text);
    resize: vertical; margin-bottom: 14px;
}
.qq-seller-dialog .acts { display: flex; gap: 8px; }
.qq-seller-dialog .acts .qq-seller-btn { border-radius: 10px; padding: 12px 16px; font-size: 13px; }

/* --- responsive ----------------------------------------------------------- */
@media (max-width: 1150px) {
    .qq-seller-title { font-size: 34px; }
    .qq-seller-head { align-items: stretch; }
    .qq-seller-headright { align-items: stretch; width: 100%; }
    .qq-seller-search { width: 100%; }
    .qq-seller-switch { align-self: flex-start; }
    /* The strip scrolls rather than wraps: a week is a row, and a wrapped week
       stops reading as one. Snap points and a right-edge fade so that the row
       admits there is more of it. */
    .qq-appt-striprow { flex-direction: column; align-items: stretch; }
    .qq-appt-strip {
        overflow-x: auto; padding-bottom: 4px; scrollbar-width: thin;
        scroll-snap-type: x proximity;
        -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 28px), transparent 100%);
        mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 28px), transparent 100%);
    }
    .qq-appt-daytab { scroll-snap-align: start; }
    .qq-appt-jump { align-self: flex-end; }
    .qq-appt-cal { right: auto; left: 0; }
    /* The rail's geometry is the one thing that cannot survive a narrow
       screen — an absolutely-positioned hour grid has nowhere to go — so the
       day becomes an ordinary stack of the same blocks. */
    .qq-rail-grid { height: auto !important; }
    .qq-rail-grid .qq-rail-vrule, .qq-rail-grid .qq-rail-hline,
    .qq-rail-grid .qq-rail-hlabel, .qq-rail-grid .qq-rail-gap,
    .qq-rail-grid .qq-rail-now, .qq-rail-grid .qq-rail-now-dot,
    .qq-rail-grid .qq-rail-now-chip { display: none; }
    .qq-rail-block {
        position: static !important; height: auto !important; top: auto !important;
        /* The rail's cap is measured against the NEXT block's offset, which
           stops existing the moment the blocks become a stack — leaving it on
           would clip the action buttons off the bottom of the card. */
        max-height: none !important; width: auto !important;
        left: auto; right: auto; margin-bottom: 8px; padding: 12px 14px;
        grid-template-columns: minmax(0, 1fr); gap: 10px; align-items: start;
    }
    .qq-rail-block.is-dense .qq-rail-l2, .qq-rail-block.is-dense .qq-appt-claim { display: block; }
    .qq-rail-block.is-dense .qq-rail-l1 { flex-wrap: wrap; overflow: visible; }
    .qq-rail-block.is-dense .qq-rail-l1 .svc { font-size: 14.5px; white-space: normal; }
    .qq-rail-block.is-dense .qq-seller-btn { padding: 9px 12px; font-size: 12px; }
    .qq-rail-block.is-open { grid-template-columns: minmax(0, 1fr); }
    .qq-seller-actions { flex-direction: row; flex-wrap: wrap; }
    .qq-seller-actions .qq-seller-btn { width: auto; flex: 1 1 auto; }
    .qq-appt-row { grid-template-columns: minmax(0, 1fr); gap: 8px; }
    .qq-drawer {
        width: 100vw; height: 100dvh; max-height: 100dvh; top: 0; right: 0;
        transform: none; border-radius: 0; border-left: 0;
    }

    /* --- 44px minimum on anything a thumb has to hit ---------------------- */
    /* Padding alone left these between 28 and 36px. min-height rather than a
       taller padding so the label keeps its own vertical rhythm, and flex
       centring so a one-line label still sits in the middle of the target. */
    .qq-seller-btn,
    .qq-seller-switch button,
    .qq-appt-jump,
    .qq-seller-clear,
    .qq-seller-links button,
    .qq-appt-more button,
    .qq-appt-cal-foot button {
        min-height: 44px;
        display: inline-flex; align-items: center; justify-content: center;
    }
    /* The danger action is a text button with no box, so it needs the target
       without gaining a border or a background. */
    .qq-seller-btn.danger { padding: 0 4px; }
    /* Links sit in a row of two — keep them left-aligned inside their target. */
    .qq-seller-links button { justify-content: flex-start; padding: 0 2px; }
    .qq-appt-step { min-width: 44px; }
    .qq-drawer-close { width: 44px; height: 44px; }
    .qq-appt-cal-cell { height: 44px; }
    /* MessageThread's palette renders inside the drawer, so its cells are a
       seller-facing target here even though the component is shared. Three
       classes deep on purpose: the palette is styled in MessageThread.razor.css,
       which compiles to `.qq-msg-emoji[b-xxxxx]` and loads AFTER app.css, so a
       two-class selector ties it and loses. */
    .qq-drawer .qq-drawer-body .qq-msg-emoji { grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); }
    .qq-drawer .qq-drawer-body .qq-msg-emoji button { min-height: 44px; }
    .qq-drawer .qq-drawer-body .qq-msg-emoji-toggle { min-width: 44px; min-height: 44px; }
}

/* Below 520px the two-up action row starts breaking labels ("Propose new
   time" over three lines), so the actions become one per row. */
@media (max-width: 520px) {
    .qq-seller-actions .qq-seller-btn { flex: 1 1 100%; }
    .qq-seller-inline { flex-wrap: wrap; }
    .qq-seller-inline .qq-seller-btn { flex: 1 1 auto; }
}

/* ---------------------------------------------------------------------------
   Seller orders — /seller/orders (design handoff: "Seller Orders")

   Companion to the schedule: same shell (qq-seller-*), same hour rail
   (qq-rail-*). What differs is the spine — appointments are organised by the
   clock, orders by what the order is WAITING FOR. So the queue is the default
   and the rail is the second view, the other way round from Appointments.
--------------------------------------------------------------------------- */

.qq-order-sub { font: 400 13px/1.5 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted); margin: 6px 0 0; }

/* --- filter chips --------------------------------------------------------- */
.qq-order-chips { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; margin-bottom: 16px; }
.qq-order-chip {
    appearance: none; background: var(--qq-card); border: 1px solid var(--qq-border);
    color: var(--qq-text-body); border-radius: 999px; padding: 9px 14px; cursor: pointer;
    font: 600 12.5px/1 'Space Grotesk', system-ui, sans-serif;
    transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.qq-order-chip:hover { border-color: var(--qq-brass); color: var(--qq-ink); }
.qq-order-chip .n { font: 700 11px/1 var(--qq-admin-mono); color: var(--qq-text-faint); }
.qq-order-chip .n.urgent { color: var(--qq-brass); }
.qq-order-chip.is-on { background: var(--qq-ink); border-color: var(--qq-ink); color: var(--qq-paper); }
/* Drawn on an ink fill, which inverts in dark — so not --qq-gold-bright. */
.qq-order-chip.is-on .n, .qq-order-chip.is-on .n.urgent { color: var(--qq-on-ink-accent); }
.qq-order-chips .rule { flex: 1; min-width: 20px; height: 1px; background: var(--qq-border); }
.qq-order-chips .inplay { font: 700 10.5px/1 var(--qq-admin-mono); letter-spacing: .08em; color: var(--qq-text-faint); }

/* --- one order ------------------------------------------------------------ */
.qq-order-list { display: flex; flex-direction: column; gap: 10px; }
.qq-order-card {
    background: var(--qq-card); border: 1px solid var(--qq-border);
    border-radius: 14px; padding: 16px 18px;
}
/* Money owed is the one thing on this page that is a debt rather than a job. */
.qq-order-card.is-owed { border-color: var(--qq-warn-border); }

/* A WRAPPING FLEX ROW, deliberately not a four-track grid: fixed tracks
   collapsed the content column to 95px below 1100px. Money and actions drop
   under the content instead of crushing it. */
.qq-order-row { display: flex; flex-wrap: wrap; gap: 18px; align-items: flex-start; }
.qq-order-meta { width: 136px; flex-shrink: 0; }
.qq-order-meta .code { font: 700 12.5px/1 var(--qq-admin-mono); letter-spacing: .04em; color: var(--qq-ink); }
.qq-order-meta .l { font: 400 11px/1.5 var(--qq-admin-mono); color: var(--qq-text-faint); }
.qq-order-meta .l:first-of-type { margin-top: 6px; }
.qq-order-body { min-width: 0; flex: 1 1 320px; }
.qq-order-money {
    width: 100px; flex-shrink: 0; text-align: right;
    font: 400 26px/1 'Instrument Serif', Georgia, serif; color: var(--qq-ink);
    font-variant-numeric: tabular-nums;
}
.qq-order-act { width: 178px; flex-shrink: 0; display: flex; flex-direction: column; gap: 7px; }

.qq-order-statusrow { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.qq-order-mark { font: 700 10.5px/1 var(--qq-admin-mono); letter-spacing: .06em; color: var(--qq-text-muted); }
.qq-order-items { font: 400 13px/1.6 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-body); margin-top: 7px; }
.qq-order-items .sel { color: var(--qq-text-faint); }
.qq-order-where { font: 400 12.5px/1.5 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted); margin-top: 4px; }
.qq-order-note { font: italic 400 13px/1.5 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-muted); margin-top: 5px; }

/* --- the two panels promoted out of the details --------------------------- */
/* Both are money or a decision, and both were previously behind a toggle. */
.qq-order-panel { margin-top: 11px; padding: 12px 14px; border-radius: 10px; }
.qq-order-panel.owed { background: var(--qq-warn-bg); border: 1px solid var(--qq-warn-border); }
.qq-order-panel.owed .h { font: 700 12.5px/1.4 'Space Grotesk', system-ui, sans-serif; color: var(--qq-warn-fg); }
.qq-order-panel.owed .b { font: 400 12.5px/1.55 'Space Grotesk', system-ui, sans-serif; color: var(--qq-warn-fg); margin-top: 3px; }
.qq-order-panel.owed .b code { font-family: var(--qq-admin-mono); color: inherit; background: none; padding: 0; }
.qq-order-panel.asked { background: var(--qq-brass-tint); border: 1px solid var(--qq-brass-soft); }
.qq-order-panel.asked .k { font: 700 9.5px/1.4 var(--qq-admin-mono); letter-spacing: .1em; color: var(--qq-brass-deep); margin-bottom: 4px; }
.qq-order-panel.asked .b { font: 500 12.5px/1.5 'Space Grotesk', system-ui, sans-serif; color: var(--qq-ink); }
.qq-order-panel .acts { display: flex; gap: 7px; margin-top: 10px; flex-wrap: wrap; }

/* --- details -------------------------------------------------------------- */
/* Four tracks, and the minmax(0,1fr) value columns are what stop the long
   values (address, cancel note, refund trail) being clipped the way the old
   <dd> clipped them. */
/* Four tracks only when the CONTENT COLUMN can hold them — not when the
   viewport can. The details sit inside .qq-order-body, which is flex:1 1 320px
   beside a 136px meta, 100px money and 178px action column, so a 1280px window
   still leaves it around 400px: four tracks there put two words on a line and
   ran "Pat Guest" into "no account". A container query asks the right box. */
.qq-order-body { container-type: inline-size; }
.qq-order-dl {
    display: grid; grid-template-columns: max-content minmax(0, 1fr);
    gap: 10px 20px; align-items: baseline; margin: 14px 0 0;
    padding-top: 14px; border-top: 1px solid var(--qq-border-soft);
}
@container (min-width: 560px) {
    .qq-order-dl { grid-template-columns: max-content minmax(0, 1fr) max-content minmax(0, 1fr); }
}
.qq-order-dl dt { font: 700 9.5px/1.4 var(--qq-admin-mono); letter-spacing: .1em; color: var(--qq-text-faint); margin: 0; }
.qq-order-dl dd { font: 500 12.5px/1.4 'Space Grotesk', system-ui, sans-serif; color: var(--qq-ink); margin: 0; min-width: 0; }
.qq-order-dl dd.strong { font-weight: 700; }
.qq-order-dl dt.warn, .qq-order-dl dd.warn { color: var(--qq-warn-fg); }
.qq-order-dl dd .aside { color: var(--qq-text-muted); font-weight: 400; }
.qq-order-dl dd .aside::before { content: " · "; }

/* --- handoffs rail extras ------------------------------------------------- */
/* The rail's blocks are sized in pixels against content that wraps, so the
   canvas gets a floor and the card scrolls sideways rather than squeezing a
   one-line block into three and spilling into the next handoff. The vertical
   axis is pinned so a stray scrollbar never appears on the card. */
.qq-rail.is-wide { overflow: auto hidden; }
.qq-rail.is-wide .qq-rail-grid { min-width: 880px; }
.qq-order-hblock { display: flex; flex-direction: column; gap: 6px; padding: 7px 14px; }
.qq-order-hblock .top { display: flex; gap: 14px; align-items: center; }
/* A proposed time is NOT a slot: it renders inside the agreed block, never as
   its own block on the rail, because nothing is agreed at that hour. */
.qq-order-asked {
    display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
    background: var(--qq-brass-tint); border: 1px dashed var(--qq-gold-soft);
    border-radius: 8px; padding: 5px 10px;
}
.qq-order-asked .k { font: 700 10px/1.4 var(--qq-admin-mono); letter-spacing: .08em; color: var(--qq-brass-deep); flex-shrink: 0; }
.qq-order-asked .sp { flex: 1; min-width: 0; }
.qq-order-untimed {
    margin-top: 14px; padding: 14px 16px; background: var(--qq-card);
    border: 1px solid var(--qq-border); border-radius: 14px;
    display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
}
.qq-order-untimed .k { font: 700 10.5px/1 var(--qq-admin-mono); letter-spacing: .1em; color: var(--qq-text-faint); }
.qq-order-untimed .b { font: 400 13px/1.5 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-body); margin-top: 5px; }

/* --- done ----------------------------------------------------------------- */
.qq-order-done-row {
    display: flex; flex-wrap: wrap; gap: 18px; align-items: center;
    padding: 14px 18px; border-bottom: 1px solid var(--qq-border-soft);
}
.qq-order-done-row:last-child { border-bottom: 0; }
.qq-order-done-row:hover { background: var(--qq-row-hover); }
.qq-order-done-row .qq-order-meta { width: auto; }
.qq-order-done-row .qq-order-meta .code { font-size: 12px; color: var(--qq-text-body); }
.qq-order-done-row .qq-order-money { font-size: 20px; color: var(--qq-text-body); }
.qq-order-done-row .qq-order-money.nothing { color: var(--qq-text-faint); }
.qq-order-done-row .what { font: 600 14px/1.2 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-body); }
.qq-order-done-row .closed { font: 400 12.5px/1.4 'Space Grotesk', system-ui, sans-serif; color: var(--qq-text-faint); margin-top: 3px; }

/* --- narrow --------------------------------------------------------------- */
/* The card's flex wrap does most of the work on its own; these are the two
   places it needs telling. */
@media (max-width: 1150px) {
    .qq-order-meta { width: 100%; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
    .qq-order-meta .l:first-of-type { margin-top: 0; }
    .qq-order-act { width: 100%; flex-direction: row; flex-wrap: wrap; }
    .qq-order-act .qq-seller-btn { flex: 1 1 auto; }
    .qq-order-money { text-align: left; width: auto; }
    .qq-order-chip { min-height: 44px; display: inline-flex; align-items: center; gap: 5px; }
    .qq-order-dl { grid-template-columns: max-content minmax(0, 1fr); }
    /* The rail dissolves into a stack exactly as the schedule's does, so the
       floor width and the sideways scroll go with it. */
    .qq-rail.is-wide { overflow: visible; }
    .qq-rail.is-wide .qq-rail-grid { min-width: 0; }
    .qq-order-hblock { height: auto !important; }
}

@media (max-width: 520px) {
    .qq-order-act .qq-seller-btn { flex: 1 1 100%; }
}


/* ---------------------------------------------------------------------------
   .qq-table — the payout tables (seller + admin)

   These carried `class="table qq-table"` where `.qq-table` styled NOTHING, so
   they were pure Bootstrap: `--bs-table-bg: #fff` and near-black text, baked in
   and blind to the theme. On a dark page the table stayed a white slab with a
   white header — the one element on the page that had not heard about dark
   mode. Bootstrap drives its table entirely through those --bs-table-*
   variables, so re-pointing them at our tokens is the whole fix, in both
   themes at once.
--------------------------------------------------------------------------- */
.qq-table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--qq-text-body);
    --bs-table-border-color: var(--qq-border-soft);
    --bs-table-striped-bg: var(--qq-paper);
    --bs-table-striped-color: var(--qq-text-body);
    --bs-table-hover-bg: var(--qq-row-hover);
    --bs-table-hover-color: var(--qq-text);
    color: var(--qq-text-body);
    border-color: var(--qq-border-soft);
    vertical-align: middle;
}
.qq-table > thead th {
    font: 700 10.5px/1.6 var(--qq-admin-mono);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--qq-text-faint);
    background: transparent;
    border-bottom: 1px solid var(--qq-border);
    padding: 0 .75rem .6rem;
}
.qq-table > tbody td {
    background: transparent;
    border-top: 1px solid var(--qq-border-soft);
    border-bottom: 0;
    padding: .75rem;
    font-size: .92rem;
}
.qq-table > tbody tr:first-child td { border-top: 0; }
/* A detail row is a continuation of the row above it, not a new one. */
.qq-table > tbody tr.qq-table-sub td { border-top: 0; padding-top: 0; }
.qq-table a { color: var(--qq-brass); }
.qq-table a:hover { color: var(--qq-brass-deep); }


/* --- dashboard: what is running out (spec 034) ---------------------------- */
.qq-stock-warn { padding: 1rem 1.15rem; border-color: var(--qq-warn-border); }
.qq-stock-warn-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; margin-bottom: .75rem;
}
.qq-stock-warn-body { font-size: .88rem; color: var(--qq-text-muted); margin-top: .25rem; }
.qq-stock-warn-list { display: flex; flex-wrap: wrap; gap: .5rem; }
.qq-stock-warn-item {
    display: inline-flex; align-items: center; gap: .55rem;
    padding: .45rem .7rem; border-radius: 999px;
    background: var(--qq-paper); border: 1px solid var(--qq-border);
    text-decoration: none; color: var(--qq-text-body); font-size: .88rem;
    transition: border-color .12s ease;
}
.qq-stock-warn-item:hover { border-color: var(--qq-brass); color: var(--qq-ink); }
.qq-stock-warn-item .nm { font-weight: 600; }


/* --- buyer list tails ------------------------------------------------------
   The status line and one primary action, carried over from the seller pages.
   The remaining actions are real but none of them is what the row is FOR, so
   they sit quieter and to one side rather than as equal buttons. */
.qq-appt-tail {
    display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
    margin-left: auto;
}
.qq-appt-tail-rest { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.qq-status-line.mute { color: var(--qq-text-muted); }

/* Money the seller owes this buyer, promoted out of the order's own page and
   onto the row. Warn-tinted for the same reason the seller's is: it is a debt
   with a person waiting on it, not a status. */
.qq-order-owed {
    background: var(--qq-warn-bg); border: 1px solid var(--qq-warn-border);
    border-radius: 10px; padding: .7rem .85rem;
}
.qq-order-owed .h { font-weight: 700; font-size: .92rem; color: var(--qq-warn-fg); }
.qq-order-owed .b { font-size: .88rem; color: var(--qq-warn-fg); margin-top: .15rem; }
.qq-status-line.info { color: var(--qq-info-fg); }


/* --- product video (spec 035) ----------------------------------------------
   The play affordance sits ON the cover because that is the claim it is
   making — this thing moves — which the photo underneath cannot make about
   itself. The duration rides with it so pressing play is an informed choice
   about somebody's data, not a surprise. */
.sf-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    flex-direction: column;
    text-decoration: none;
    /* No dark scrim over the whole photo: the product is what the buyer came
       to look at. The glyph carries its own contrast instead. */
    background: transparent;
    transition: background .16s ease;
}
.sf-play:hover, .sf-play:focus-visible { background: rgba(23, 21, 18, .18); }

.sf-play-glyph {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: rgba(251, 248, 242, .94);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: #23201a;
    font-size: 1.05rem;
    /* The glyph is a right-pointing triangle; centring its bounding box makes
       it look left of centre, so it is nudged back. */
    padding-left: 3px;
    box-shadow: 0 2px 10px rgba(23, 21, 18, .28);
    transition: transform .16s ease;
}
.sf-play:hover .sf-play-glyph, .sf-play:focus-visible .sf-play-glyph { transform: scale(1.08); }

.sf-play-time {
    font-family: "Space Mono", ui-monospace, monospace;
    font-size: .6875rem;
    letter-spacing: .04em;
    color: #23201a;
    background: rgba(251, 248, 242, .92);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border-radius: 999px;
    padding: .15rem .45rem;
}

@media (prefers-reduced-motion: reduce) {
    .sf-play, .sf-play-glyph { transition: none; }
    .sf-play:hover .sf-play-glyph, .sf-play:focus-visible .sf-play-glyph { transform: none; }
}

/* In the lightbox the video takes the same box the image does. */
.qq-lightbox-video {
    max-width: 92vw;
    max-height: 84vh;
    border-radius: 12px;
    background: #000;
    outline: none;
}

/* The seller's video tile: the poster with its duration, so the strip reads as
   media rather than as a file list. */
.qq-video-tile a { position: relative; display: block; }
.qq-video-tile .qq-video-time {
    position: absolute; right: 4px; bottom: 4px;
    font-family: "Space Mono", ui-monospace, monospace; font-size: .625rem;
    background: rgba(23, 21, 18, .78); color: #fbf8f2;
    border-radius: 999px; padding: .1rem .35rem;
}
.qq-video-blank {
    display: flex; align-items: center; justify-content: center;
    width: 100%; height: 100%; min-height: 72px;
    background: var(--qq-mute-bg); color: var(--qq-text-muted); font-size: 1.1rem;
}

/* Reviewing a clip before it is sent (spec 035). The slot is always in the
   markup so the script has somewhere to put the preview the instant a file is
   chosen; empty it collapses to nothing. */
.qq-video-preview-slot:empty { display: none; }
.qq-video-preview {
    display: block; width: 100%; max-width: 420px; margin-top: .5rem;
    border-radius: var(--qq-radius, 8px); border: 1px solid var(--qq-border);
    background: #000; /* letterboxing reads as deliberate rather than as a gap */
}
.qq-video-review { margin-top: .5rem; }
.qq-video-frame-ok { margin-left: .4rem; color: var(--qq-good-fg); font-weight: 600; }

/* Reporting and blocking (guideline 1.2). Deliberately quiet: these are for
   the rare bad moment, and a loud Report button beside every message invites
   the wrong kind of attention. */
.qq-msg-report {
    background: none; border: 0; padding: 0 .25rem; cursor: pointer;
    font-size: .625rem; color: var(--qq-text-faint); align-self: flex-start;
    opacity: 0; transition: opacity .12s ease;
}
.qq-msg:hover .qq-msg-report,
.qq-msg-report:focus-visible { opacity: 1; }
/* Touch has no hover, so it is simply always there. */
@media (hover: none) { .qq-msg-report { opacity: .7; } }

.qq-msg-blocked {
    margin: 0 .75rem .5rem; padding: .5rem .75rem;
    border: 1px solid var(--qq-border); border-radius: var(--qq-radius, 8px);
    background: var(--qq-mute-bg); color: var(--qq-text-muted); font-size: .8125rem;
}

.qq-report-dialog { max-width: 26rem; }
.qq-radio { display: flex; align-items: center; gap: .5rem; cursor: pointer; }

.sf-review-report {
    display: inline-block; margin-top: .35rem;
    font-size: .6875rem; color: var(--qq-text-faint); text-decoration: none;
}
.sf-review-report:hover { color: var(--qq-text-muted); text-decoration: underline; }

/* The reported text in the admin queue: quoted so nobody mistakes it for the
   platform speaking, and pre-wrap because a message keeps its line breaks. */
.qq-report-quote {
    margin: 0; padding: .5rem .75rem;
    border-left: 3px solid var(--qq-border);
    background: var(--qq-mute-bg); color: var(--qq-text);
    font-size: .875rem; white-space: pre-wrap; word-break: break-word;
}

/* Confirm-dialog primitives. Promoted from ConfirmDialog.razor.css: CSS
   isolation scoped them to that one component, so every page that borrowed
   the class names for its own dialog markup (AdminVerification's revoke,
   recopy, and document-type dialogs) rendered them as unstyled flow content
   at the bottom of the page. These are design-system classes; they live here
   with the rest of qq-*. Tokens carry the admin dark theme; the literals are
   only fallbacks. */
.qq-confirm-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(23, 21, 18, .55);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1095; /* above the review dialog, which is 1090 */
    padding: 1rem;
}

.qq-confirm-card {
    background: var(--qq-admin-card, #fff);
    color: var(--qq-admin-ink, #171512);
    border-radius: 14px;
    padding: 1.5rem 1.6rem;
    max-width: 30rem;
    width: 100%;
    box-shadow: 0 16px 56px rgba(0, 0, 0, .35);
}

.qq-confirm-badge {
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    background: rgba(217, 169, 78, .18);
    color: #b07d1e;
    margin-bottom: .7rem;
}

.qq-confirm-title {
    font-size: 1.08rem;
    font-weight: 700;
    margin: 0 0 .4rem;
}

.qq-confirm-body {
    font-size: .9rem;
    color: var(--qq-admin-muted, #6b6459);
    margin: 0 0 1rem;
}

.qq-confirm-actions {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}


/* Spec 038: the seller settings hub - title row meter + tab rail. Drawn to
   the design canvas: white pill rail, ink-filled active tab, checklist dots,
   and a brass lock chip on plan-gated tabs. */
.qq-sethub-meter {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 999px;
    padding: 0.5rem 1rem;
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
}

.qq-sethub-meter-track {
    display: inline-block;
    width: 90px;
    height: 6px;
    background: var(--qq-brass-tint);
    border-radius: 999px;
    overflow: hidden;
}

.qq-sethub-meter-fill {
    display: block;
    height: 100%;
    background: var(--qq-gold-bright);
}

.qq-sethub-tabs {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    background: var(--qq-card);
    border: 1px solid var(--qq-border);
    border-radius: 16px;
    padding: 0.35rem;
    margin-top: 0.9rem;
}

.qq-sethub-tab {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 1rem;
    border-radius: 11px;
    font-size: 0.9rem;
    color: var(--qq-text-body);
    text-decoration: none;
}

.qq-sethub-tab:hover {
    background: var(--qq-brass-tint);
    color: var(--qq-brass-deep);
    text-decoration: none;
}

.qq-sethub-tab.active {
    background: var(--qq-ink);
    color: var(--qq-paper);
    font-weight: 600;
}

.qq-sethub-tab.active:hover {
    background: var(--qq-ink-hover);
    color: var(--qq-paper);
}

.qq-sethub-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
}

.qq-sethub-dot.ok { background: var(--qq-ok-fg); }
.qq-sethub-dot.bad { background: var(--qq-bad-fg); }

.qq-sethub-lock {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    background: var(--qq-brass-tint);
    color: var(--qq-brass-deep);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
}

/* The chip flips to gold on the ink-filled active tab so it stays loud. */
.qq-sethub-tab.active .qq-sethub-lock {
    background: var(--qq-gold-bright);
    color: var(--qq-ink);
}


/* The use-my-location row on store settings. The Clear button wore browser
   defaults for a while (the grey box caught on a real device, 2026-08-26) -
   the row now speaks the house language: outline button, green confirmed
   state, ghost-danger Clear. */
.qq-locate {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.qq-locate-on {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--qq-ok-fg);
    font-size: 0.85rem;
    font-weight: 600;
}

.qq-locate-msg {
    font-size: 0.85rem;
    color: var(--qq-text-muted);
}


/* Spec 039: headings take the heading font; everything else inherits the
   body font from the page root. One-font themes set both to the same family,
   so legacy rendering is untouched. */
.sf-page h1, .sf-page h2, .sf-page h3 {
    font-family: var(--sf-font-head, inherit);
}


/* Spec 039 phase B: structural layout variants. Nothing here fires until a
   store's LayoutVariant selects it. */

/* Boutique: two large cards per row, tall media - short premium menus. */
.sf-layout-boutique .sf-grid {
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.sf-layout-boutique .sf-product-img {
    height: 230px;
}

/* Single column: mobile rhythm on desktop - one capped, centred column. */
.sf-layout-single-column .sf-grid {
    grid-template-columns: 1fr;
}

.sf-layout-single-column :is(.sf-grid, .sf-service-card, .sf-giftcards, .sf-section-title, .sf-list) {
    max-width: 560px;
    margin-left: auto;
    margin-right: auto;
}

/* Split hero: cover left, identity right, no overlap. Collapses back to the
   overlap card on narrow screens - a 44% cover is a sliver on a phone. */
.sf-hero-split {
    display: flex;
    align-items: center;
    gap: 24px;
}

.sf-hero-split .sf-cover {
    width: 44%;
    min-height: 340px;
    flex-shrink: 0;
}

.sf-hero-split > .px-3 {
    flex: 1;
}

.sf-hero-split .sf-identity {
    margin-top: 0;
}

@media (max-width: 900px) {
    .sf-hero-split {
        display: block;
    }

    .sf-hero-split .sf-cover {
        width: 100%;
        min-height: 180px;
    }

    .sf-hero-split .sf-identity {
        margin-top: -72px;
    }
}

/* Compact list: menu + goods as dense text rows in one bordered card. The
   row wears the same add control as the grid card. */
.sf-list {
    max-width: 900px;
    background: var(--sf-card);
    border: 1px solid var(--sf-border);
    border-radius: var(--sf-r-card, 18px);
}

.sf-product-row {
    display: grid;
    grid-template-columns: 52px minmax(0, 1fr) auto auto;
    gap: 14px;
    align-items: center;
    padding: 13px 18px;
    border-bottom: 1px solid var(--sf-hair);
    position: relative;
}

.sf-product-row:last-child {
    border-bottom: 0;
}

.sf-row-thumb img,
.sf-row-thumb .sf-no-photo {
    width: 52px;
    height: 52px;
    object-fit: cover;
    border-radius: var(--sf-r-inner, 12px);
    background: color-mix(in srgb, var(--sf-text) 8%, var(--sf-bg));
    display: block;
}

.sf-row-main .fw-bold {
    font-size: 14.5px;
}

.sf-row-main .sf-product-desc {
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.sf-row-price {
    font-weight: 700;
    font-size: 14.5px;
    color: var(--sf-accent);
    white-space: nowrap;
}

.sf-product-row .sf-card-foot {
    padding-top: 0;
}

.sf-product-row .sf-btn-block {
    width: auto;
    padding-left: 14px;
    padding-right: 14px;
    white-space: nowrap;
}

@media (max-width: 640px) {
    .sf-product-row {
        grid-template-columns: 52px minmax(0, 1fr) auto;
    }

    .sf-row-price {
        grid-column: 2;
        justify-self: start;
    }
}


/* Spec 039 phase C: the branding editor - control column + live preview. */
.qq-brand-grid {
    display: grid;
    grid-template-columns: 372px 1fr;
    gap: 24px;
    align-items: start;
}

@media (max-width: 991px) {
    .qq-brand-grid {
        grid-template-columns: 1fr;
    }
}

.qq-brand-controls {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.qq-brand-tiles {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.qq-brand-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 9px 7px;
    border: 1.5px solid var(--qq-border);
    border-radius: 12px;
    background: var(--qq-card);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--qq-text-body);
    cursor: pointer;
}

.qq-brand-tile.on {
    border-color: var(--qq-ink);
    box-shadow: 0 0 0 1px var(--qq-ink);
    color: var(--qq-text);
}

.qq-brand-thumb {
    /* Wireframe tones ride the console theme, not the storefront's: canvas +
       strong/mid/faint blocks, re-pointed in the dark block below so the
       sketches keep their contrast steps on a dark card. */
    --th-bg: #f1ede3;
    --th-a: #c8c1b0;
    --th-b: #d8d2c4;
    --th-c: #e3ded1;
    width: 100%;
    height: 46px;
    border-radius: 7px;
    background: var(--th-bg);
    background-repeat: no-repeat;
    display: block;
}

html[data-theme="dark"] .qq-brand-thumb {
    --th-bg: #2b2721;
    --th-a: #7d7261;
    --th-b: #564e40;
    --th-c: #3c362c;
}

/* Wireframe thumbnails: three tones sketch each layout's anatomy. */
.qq-thumb-standard { background-image: linear-gradient(var(--th-a), var(--th-a)), linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-c), var(--th-c)); background-size: 100% 12px, 46% 40%, 46% 40%, 100% 20%; background-position: 0 0, 8% 62%, 92% 62%, 0 100%; }
.qq-thumb-services-first { background-image: linear-gradient(var(--th-a), var(--th-a)), linear-gradient(var(--th-c), var(--th-c)), linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-b), var(--th-b)); background-size: 100% 12px, 100% 26%, 46% 30%, 46% 30%; background-position: 0 0, 0 40%, 8% 100%, 92% 100%; }
.qq-thumb-gallery { background-image: linear-gradient(var(--th-a), var(--th-a)), linear-gradient(var(--th-b), var(--th-b)); background-size: 100% 12px, 100% 74%; background-position: 0 0, 0 100%; }
.qq-thumb-market { background-image: linear-gradient(var(--th-a), var(--th-a)), linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-b), var(--th-b)); background-size: 100% 12px, 30% 62%, 30% 62%, 30% 62%; background-position: 0 0, 2% 90%, 50% 90%, 98% 90%; }
.qq-thumb-split-hero { background-image: linear-gradient(var(--th-a), var(--th-a)), linear-gradient(var(--th-c), var(--th-c)); background-size: 44% 100%, 50% 70%; background-position: 0 0, 96% 50%; }
.qq-thumb-compact-list { background-image: linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-b), var(--th-b)); background-size: 100% 15%, 100% 15%, 100% 15%, 100% 15%; background-position: 0 4%, 0 34%, 0 64%, 0 94%; }
.qq-thumb-boutique { background-image: linear-gradient(var(--th-a), var(--th-a)), linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-b), var(--th-b)); background-size: 100% 12px, 47% 74%, 47% 74%; background-position: 0 0, 0 100%, 100% 100%; }
.qq-thumb-single-column { background-image: linear-gradient(var(--th-a), var(--th-a)), linear-gradient(var(--th-b), var(--th-b)), linear-gradient(var(--th-b), var(--th-b)); background-size: 40% 12px, 40% 34%, 40% 34%; background-position: 50% 0, 50% 52%, 50% 100%; }

.qq-brand-aa {
    font-size: 17px;
    font-weight: 700;
    line-height: 1;
}

.qq-brand-segrow {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
}

.qq-brand-segrow:last-child {
    margin-bottom: 0;
}

.qq-brand-seglabel {
    width: 84px;
    flex-shrink: 0;
    font-size: 0.8rem;
    font-weight: 600;
}

/* A label plus three segments at the shared .qq-seg's text-sized padding is
   wider than the 372px control column, so the last option was being clipped
   off the card — and French runs longer still ("Arrondis", "Compacte"). The
   segments share the row's leftover width instead of sizing to their text,
   and the whole control drops to its own full-width line if even that is too
   tight. */
.qq-brand-segrow {
    flex-wrap: wrap;
}

.qq-brand-segrow .qq-seg {
    flex: 1 1 220px;
    min-width: 0;
}

.qq-brand-segrow .qq-seg > button {
    flex: 1 1 0;
    min-width: 0;
    padding-left: 0.45rem;
    padding-right: 0.45rem;
    text-align: center;
}

/* Stock cover art: six ready-made banners for a seller with no photo. The
   swatch IS the design — the same CSS background the storefront paints, from
   StockBannerCatalog — so what you pick is literally what buyers get. The art
   is fixed hex by nature; only the chrome around it follows the console
   theme, and a border colour is exempt from the fixed-surface/fixed-ink rule
   because it sits beside the art rather than on it. */
.qq-stock-tiles {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 8px;
}

.qq-stock-tile {
    aspect-ratio: 4 / 1;
    border: 1px solid var(--qq-border);
    border-radius: 8px;
    padding: 0;
    cursor: pointer;
}

.qq-stock-tile.on {
    border-color: var(--qq-ink);
    box-shadow: 0 0 0 2px var(--qq-ink);
}

.qq-stock-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 8px;
}

.qq-stock-none {
    border: 1px solid var(--qq-border);
    background: var(--qq-card);
    color: var(--qq-text-body);
    border-radius: 999px;
    padding: 5px 13px;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    flex-shrink: 0;
}

.qq-stock-none.on {
    background: var(--qq-ink);
    border-color: var(--qq-ink);
    color: var(--qq-paper);
}

.qq-brand-preview-col {
    min-width: 0;
}

/* Both preview frames scale their fixed-width artboard to exactly fill the
   frame's own content box, so the preview never leaves a gutter beside
   itself. The WIDTH fit is pure CSS: the frame is a size container, and the
   transform below reads tan(atan2(100cqw, Wpx)) = the frame's content width
   ÷ the artboard's natural width. Container queries re-resolve on every
   layout with no script involved, so this is right before, without and
   after branding-preview.js, which only trims the scroll HEIGHT.

   The scrollbar is thinned, not hidden: it is the only cue that a 620px
   window onto a much taller storefront has more below, and the only handle
   for anyone who does not scroll by wheel. scrollbar-gutter reserves its
   width up front, which keeps the fit from oscillating as the bar appears
   and disappears around the height threshold. The frames carry the console's
   own surface — the artboard covers their full width, so what shows is the
   reserved gutter, which must not be a strip of cream in a dark console. */
.qq-bp-frame {
    border: 1px solid var(--qq-border);
    border-radius: 16px;
    background: var(--qq-shell);
    box-shadow: 0 10px 30px rgba(23, 21, 18, 0.08);
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-gutter: stable;
    /* Tall previews scroll inside 620px; a short one shrinks to fit rather
       than trailing dead background below the storefront. */
    height: auto;
    max-height: 620px;
    max-width: 1104px;
    container-type: inline-size;
}

.qq-bp-frame,
.qq-bp-bezel {
    scrollbar-width: thin;
    scrollbar-color: var(--qq-border) transparent;
}

.qq-bp-frame::-webkit-scrollbar,
.qq-bp-bezel::-webkit-scrollbar {
    width: 6px;
}

.qq-bp-frame::-webkit-scrollbar-track,
.qq-bp-bezel::-webkit-scrollbar-track {
    background: transparent;
}

.qq-bp-frame::-webkit-scrollbar-thumb,
.qq-bp-bezel::-webkit-scrollbar-thumb {
    background: var(--qq-border);
    border-radius: 3px;
}

/* NEVER scale these with the zoom property: container units re-resolve
   inside a zoomed element on some Chrome versions, so a zoom computed from
   cqw feeds back on itself and the artboard lands at roughly scale-squared.
   transform is safe - it doesn't affect unit resolution. */
.qq-bp-scale {
    width: 1080px;
    transform-origin: top left;
    transform: scale(0.44);
    transform: scale(min(1, tan(atan2(100cqw, 1080px))));
}

/* A transform scales what you see but not the layout box, so the frame would
   otherwise scroll for the artboard's full UNSCALED height — a long dead tail
   below the storefront. branding-preview.js gives this wrapper the scaled
   height to trim that. Without JS it stays auto and only the tail comes
   back; the preview is still the right size. */
.qq-bp-crop {
    overflow: hidden;
}

/* The phone keeps a fixed silhouette — a device is a device — so its screen
   scrolls inside the bezel however tall the storefront runs. */
.qq-bp-bezel {
    width: 268px;
    height: 508px;
    border: 9px solid #171512;
    border-radius: 36px;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-gutter: stable;
    margin-top: 18px;
    background: var(--qq-shell);
    container-type: inline-size;
}

/* An ink phone body is invisible against the dark console (#171512 on a
   #1d1913 shell). Dark mode gets a lighter device instead of a black one. */
html[data-theme="dark"] .qq-bp-bezel {
    border-color: var(--qq-border);
}

.qq-bp-scale-m {
    width: 390px;
    transform-origin: top left;
    transform: scale(0.6);
    transform: scale(tan(atan2(100cqw, 390px)));
}

.qq-bp-cap {
    font-family: var(--qq-admin-mono);
    font-size: 11px;
    color: var(--qq-text-faint);
    margin-top: 8px;
    letter-spacing: 0.04em;
}

.qq-bp-ph {
    background: linear-gradient(135deg, color-mix(in srgb, var(--sf-primary) 18%, #e9dfc9), color-mix(in srgb, var(--sf-primary) 8%, #f4eee0));
}

.sf-dark .qq-bp-ph {
    background: linear-gradient(135deg, #2b2620, #38322a);
}

/* --- Seller media uploader (spec 040) ------------------------------------------------
   The design ships a literal light palette; every value here is the matching console
   token instead, so the card follows the console theme rather than pinning itself to
   one. Where a surface IS fixed — the ink scrim over a thumbnail — the ink on it is
   fixed too, per the pairing rule. */
.qq-mu {
    position: relative;
    background: var(--qq-paper);
    border: 1px solid var(--qq-border);
    border-radius: 20px;
    box-shadow: 0 8px 32px rgba(23, 21, 18, 0.12);
    padding: clamp(16px, 3.5%, 30px);
}

.qq-mu.is-dragover::after {
    content: "";
    position: absolute;
    inset: 0;
    border: 2px solid var(--qq-brass);
    border-radius: 20px;
    background: color-mix(in srgb, var(--qq-brass) 12%, transparent);
    pointer-events: none;
}

.qq-mu-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 14px;
}

.qq-mu-titles {
    flex: 1 1 220px;
    min-width: 0;
}

.qq-mu-title {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1.15;
}

.qq-mu-sub {
    font-size: 13px;
    color: var(--qq-text-muted);
    margin-top: 2px;
}

.qq-mu-cluster {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-left: auto;
}

.qq-mu-counts {
    font-family: var(--qq-admin-mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    color: var(--qq-text-faint);
}

.qq-mu-live {
    color: var(--qq-brass);
}

/* The picker is a label wrapping a real input: it opens the dialog with no script of
   its own and stays in the tab order, which is the keyboard path to a drop zone. */
.qq-mu-add {
    background: var(--qq-ink);
    color: var(--qq-paper);
    border-radius: 999px;
    padding: 8px 16px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    position: relative;
}

.qq-mu-add input[type="file"],
.qq-mu-empty input[type="file"],
.qq-mu-more input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
}

.qq-mu-add:has(input:disabled) {
    opacity: 0.5;
    cursor: default;
}

.qq-mu-add:has(input:focus-visible),
.qq-mu-empty:has(input:focus-visible),
.qq-mu-more:has(input:focus-visible) {
    outline: 2px solid var(--qq-brass);
    outline-offset: 2px;
}

.qq-mu-track {
    height: 3px;
    border-radius: 3px;
    background: var(--qq-mute-bg);
    overflow: hidden;
    margin-bottom: 12px;
}

.qq-mu-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--qq-brass), var(--qq-gold-bright));
    transition: width 0.15s linear;
}

.qq-mu-note,
.qq-mu-warn {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    border-radius: 12px;
    padding: 9px 13px;
    font-size: 12.5px;
    margin-bottom: 12px;
}

.qq-mu-note {
    background: var(--qq-shell);
    color: var(--qq-text-body);
}

.qq-mu-warn {
    background: var(--qq-bad-bg);
    border: 1px solid var(--qq-bad-border);
    color: var(--qq-bad-fg);
}

.qq-mu-empty {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 170px;
    padding: 28px 16px;
    background: var(--qq-shell);
    border-radius: 16px;
    cursor: pointer;
    text-align: center;
}

.qq-mu-corner {
    position: absolute;
    width: 20px;
    height: 20px;
    border: 2px solid var(--qq-ink);
}

.qq-mu-corner.tl { top: 12px; left: 12px; border-right: 0; border-bottom: 0; }
.qq-mu-corner.tr { top: 12px; right: 12px; border-left: 0; border-bottom: 0; }
.qq-mu-corner.bl { bottom: 12px; left: 12px; border-right: 0; border-top: 0; }
.qq-mu-corner.br { bottom: 12px; right: 12px; border-left: 0; border-top: 0; }

.qq-mu-arrow {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--qq-ink);
    color: var(--qq-paper);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 19px;
}

.qq-mu-empty-title {
    font-size: 17px;
    font-weight: 700;
}

.qq-mu-spec {
    font-family: var(--qq-admin-mono);
    font-size: 11px;
    color: var(--qq-text-faint);
}

.qq-mu-browse {
    font-size: 12.5px;
    color: var(--qq-brass);
    font-weight: 600;
}

.qq-mu-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
    gap: 14px;
}

.qq-mu-cell {
    min-width: 0;
}

.qq-mu-tile {
    position: relative;
    aspect-ratio: 1;
    border-radius: 14px;
    background: var(--qq-mute-bg);
    overflow: hidden;
    display: block;
}

.qq-mu-tile img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.qq-mu-tile > a {
    display: block;
    width: 100%;
    height: 100%;
}

.qq-mu-blank {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 26px;
    color: var(--qq-text-faint);
}

/* Fixed ink scrims: their labels are fixed light ink, never a theme token, because
   the surface under them does not flip with the theme. */
.qq-mu-cover,
.qq-mu-time,
.qq-mu-chip {
    position: absolute;
    font-family: var(--qq-admin-mono);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    border-radius: 6px;
    padding: 3px 6px;
    background: rgba(23, 21, 18, 0.8);
    color: #f2ede4;
}

.qq-mu-cover {
    top: 7px;
    left: 7px;
    color: #e0a13c;
}

.qq-mu-time { bottom: 7px; right: 7px; }
.qq-mu-chip { bottom: 7px; left: 7px; }

.qq-mu-actions {
    position: absolute;
    inset: auto 0 0 0;
    display: flex;
    gap: 6px;
    padding: 7px;
    background: linear-gradient(180deg, rgba(23, 21, 18, 0), rgba(23, 21, 18, 0.72));
    opacity: 0;
    transition: opacity 0.14s ease;
}

.qq-mu-tile:hover .qq-mu-actions,
.qq-mu-tile:focus-within .qq-mu-actions {
    opacity: 1;
}

.qq-mu-act {
    border: 0;
    border-radius: 999px;
    padding: 4px 9px;
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    background: #f2ede4;
    color: #171512;
}

.qq-mu-act.dark {
    background: rgba(23, 21, 18, 0.82);
    color: #f2ede4;
}

/* Queued: the photo sits under a pale veil, waiting its turn. */
.qq-mu-veil {
    position: absolute;
    inset: 0 0 auto 0;
    height: 100%;
    background: rgba(250, 248, 244, 0.55);
}

/* Uploading: the veil is only as tall as the part that has NOT gone yet, so
   the picture develops upward as the bytes leave — the height comes from the
   real byte count, inline. The lit bottom edge is the water line. */
.qq-mu-veil.is-live {
    background: rgba(23, 21, 18, 0.34);
    backdrop-filter: blur(5px) grayscale(1);
    border-bottom: 2px solid var(--qq-gold-bright);
    box-shadow: 0 2px 14px rgba(224, 161, 60, 0.6);
    transition: height 0.15s linear;
}

.qq-mu-pct {
    position: absolute;
    top: 7px;
    right: 7px;
    font-family: var(--qq-admin-mono);
    font-size: 11px;
    font-weight: 700;
    border-radius: 6px;
    padding: 3px 6px;
    background: rgba(23, 21, 18, 0.55);
    color: #f2ede4;
}

/* Optimizing: the bytes are up and the server is re-encoding. Nothing to
   measure, so this one sweeps. */
.qq-mu-chip.is-work {
    left: 7px;
    right: 7px;
    overflow: hidden;
}

.qq-mu-chip.is-work::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.28), transparent);
    animation: qq-mu-sweep 1.1s linear infinite;
}

@keyframes qq-mu-sweep {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(220%); }
}

@media (prefers-reduced-motion: reduce) {
    .qq-mu-chip.is-work::after { animation: none; }
    .qq-mu-veil.is-live { transition: none; }
}

.qq-mu-tile.is-error {
    background: var(--qq-bad-bg);
    border: 1px solid var(--qq-bad-border);
}

.qq-mu-errbody {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 5px;
    padding: 9px;
    height: 100%;
}

.qq-mu-errchip {
    font-family: var(--qq-admin-mono);
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.06em;
    border-radius: 5px;
    padding: 2px 5px;
    background: var(--qq-bad-border);
    color: var(--qq-bad-fg);
}

.qq-mu-errtext {
    font-size: 11.5px;
    line-height: 1.3;
    color: var(--qq-bad-fg);
    overflow: hidden;
}

.qq-mu-errbody .qq-mu-act {
    margin-top: auto;
    background: transparent;
    border: 1px solid var(--qq-bad-border);
    color: var(--qq-bad-fg);
}

.qq-mu-cap {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 6px;
    margin-top: 5px;
    font-family: var(--qq-admin-mono);
}

.qq-mu-name {
    font-size: 10.5px;
    color: var(--qq-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qq-mu-size {
    font-size: 10px;
    color: var(--qq-text-faint);
    flex-shrink: 0;
}

.qq-mu-more {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    background: var(--qq-shell);
    border: 1px dashed var(--qq-border);
    color: var(--qq-text-muted);
    font-size: 20px;
    cursor: pointer;
}

.qq-mu-more-label {
    font-size: 11px;
    font-weight: 600;
}

/* The poster-frame review, inside the clip's own tile (phase C). It used to be
   a panel under the card that could only ever describe one clip; keyed staging
   means two can wait here at once, each on its own frame. */
.qq-mu-vp,
.qq-mu-vp video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: #171512;
}

.qq-mu-review-scrim {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 5px;
    padding: 9px;
    /* A fixed ink scrim over the clip, so every label on it is fixed ink too. */
    background: rgba(23, 21, 18, 0.48);
    pointer-events: none;
}

/* The controls are the only live thing: the scrim must not eat the scrub bar. */
.qq-mu-review-row {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    pointer-events: auto;
}

.qq-mu-review-label {
    font-family: var(--qq-admin-mono);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: #e0a13c;
}

.qq-mu-review-copy {
    font-size: 11px;
    line-height: 1.25;
    color: #f2ede4;
}

.qq-mu-frame-ok {
    color: #7fc9a2;
    font-weight: 600;
    margin-left: 4px;
}

.qq-mu-act.accent {
    background: #e0a13c;
    color: #171512;
}

/* --- Single-image slot (spec 040) ------------------------------------------------
   A logo, a banner, a person's photo: one image replaced in place. It borrows the
   gallery card's reading of progress — the veil covers what has not been sent — and
   none of its gallery furniture. */
.qq-ms {
    position: relative;
}

.qq-ms-frame {
    position: relative;
    width: 100%;
    border-radius: 14px;
    overflow: hidden;
    border: 2px dashed var(--qq-track-off);
    background: var(--qq-border-soft);
    display: flex;
    align-items: center;
    justify-content: center;
}

.qq-ms.is-dragover .qq-ms-frame {
    border-style: solid;
    border-color: var(--qq-brass);
    background: color-mix(in srgb, var(--qq-brass) 12%, var(--qq-border-soft));
}

.qq-ms-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.qq-ms-empty {
    color: var(--qq-text-faint);
    font-size: 12.5px;
    text-align: center;
    padding: 8px;
}

/* Top-anchored, so the picture develops upward as the bytes leave. */
.qq-ms-veil {
    position: absolute;
    inset: 0 0 auto 0;
    background: rgba(23, 21, 18, 0.34);
    backdrop-filter: blur(4px) grayscale(1);
    border-bottom: 2px solid var(--qq-gold-bright);
    transition: height 0.15s linear;
}

.qq-ms-pct {
    position: absolute;
    top: 7px;
    right: 7px;
    font-family: var(--qq-admin-mono);
    font-size: 11px;
    font-weight: 700;
    border-radius: 6px;
    padding: 3px 6px;
    /* Fixed scrim, so fixed ink. */
    background: rgba(23, 21, 18, 0.55);
    color: #f2ede4;
}

.qq-ms-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 8px;
}

.qq-ms-pick {
    position: relative;
    cursor: pointer;
}

.qq-ms-pick input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
}

.qq-ms-pick:has(input:focus-visible) {
    outline: 2px solid var(--qq-brass);
    outline-offset: 2px;
}

.qq-ms-error {
    margin-top: 6px;
    font-size: 12.5px;
    color: var(--qq-bad-fg);
}

/* --- Verification document slot (spec 040) ---------------------------------------
   A document is not a photo: it may be a PDF with no useful thumbnail, it lives
   behind the authenticated /media door, and it carries a reviewer's verdict that
   has nothing to do with whether the upload worked. */
.qq-ds {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.qq-ds-frame {
    position: relative;
    height: 120px;
    border-radius: 10px;
    overflow: hidden;
    border: 2px dashed var(--qq-border);
    background: var(--qq-border-soft);
    display: flex;
    align-items: center;
    justify-content: center;
}

.qq-ds.is-dragover .qq-ds-frame {
    border-style: solid;
    border-color: var(--qq-brass);
    background: color-mix(in srgb, var(--qq-brass) 12%, var(--qq-border-soft));
}

.qq-ds-frame a,
.qq-ds-frame img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.qq-ds-empty {
    color: var(--qq-text-faint);
    font-size: 12.5px;
}

.qq-ds-busy {
    position: absolute;
    inset: 0;
    background: var(--qq-mute-bg);
}

.qq-ds-veil {
    position: absolute;
    inset: 0 0 auto 0;
    background: rgba(23, 21, 18, 0.34);
    border-bottom: 2px solid var(--qq-gold-bright);
    transition: height 0.15s linear;
}

.qq-ds-note {
    font-size: 0.82rem;
    color: var(--qq-bad-fg);
    margin-bottom: 4px;
}

.qq-ds-locked {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

/* --- QuickRide (spec 045) ------------------------------------------------- */
/* Route line: solid brass dot → dashed brass line → duration pill → dashed line → hollow dot. */
.qq-route { display: flex; align-items: center; min-width: 80px; flex: 1; }
.qq-route-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--qq-gold-bright); flex-shrink: 0; display: inline-block; }
.qq-route-dot.hollow { background: var(--qq-card); border: 2px solid var(--qq-gold-bright); }
.qq-route-dash { flex: 1; height: 2px; background: repeating-linear-gradient(90deg, var(--qq-gold-bright) 0 6px, transparent 6px 11px); }
.qq-route-pill { font-family: var(--qq-admin-mono); font-size: 10.5px; color: var(--qq-brass); background: var(--qq-brass-tint); padding: 2px 9px; border-radius: 99px; white-space: nowrap; }
.qq-route.muted .qq-route-dot { background: var(--qq-text-faint); border-color: var(--qq-text-faint); }
.qq-route.muted .qq-route-dash { background: repeating-linear-gradient(90deg, var(--qq-text-faint) 0 6px, transparent 6px 11px); }
.qq-route.muted .qq-route-pill { color: var(--qq-text-muted); background: var(--qq-mute-bg); }

/* Seats left: green, amber when one, grey pill when full. */
.qq-seats-left { font-size: 12.5px; font-weight: 700; color: var(--qq-ok-fg); }
.qq-seats-left.one { color: #b3822e; }
.qq-seats-full { font-family: var(--qq-admin-mono); font-size: 11px; font-weight: 700; color: var(--qq-text-muted); background: var(--qq-mute-bg); padding: 3px 10px; border-radius: 99px; }
.qq-seatbar { display: inline-block; flex: 1; max-width: 180px; height: 6px; border-radius: 99px; background: var(--qq-mute-bg); overflow: hidden; }
.qq-seatbar > span { display: block; height: 100%; background: var(--qq-gold-bright); border-radius: 99px; }

/* Journey card (B2) */
.qq-ride-card { display: flex; background: var(--qq-card); border: 1px solid var(--qq-border); border-radius: 16px; overflow: hidden; color: inherit; text-decoration: none; transition: border-color .15s, box-shadow .15s; }
.qq-ride-card:hover { border-color: var(--qq-gold-bright); box-shadow: 0 6px 20px rgba(23, 21, 18, .08); color: inherit; }
.qq-ride-card.is-full { opacity: .62; }
.qq-ride-cover { width: 250px; flex-shrink: 0; background: linear-gradient(145deg, #8f8b80, #6d6a61); background-size: cover; background-position: center; position: relative; min-height: 150px; }
.qq-ride-cover-badge { position: absolute; left: 10px; top: 10px; background: rgba(23, 21, 18, .75); color: #f4f0e8; font-family: var(--qq-admin-mono); font-size: 10px; padding: 3px 8px; border-radius: 5px; }
.qq-ride-body { flex: 1; padding: 18px 24px; display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.qq-ride-ends { display: flex; align-items: center; gap: 12px; }
.qq-ride-city { font-size: 18px; font-weight: 700; }
.qq-ride-time { font-family: var(--qq-admin-mono); font-size: 11px; color: var(--qq-text-muted); }
.qq-ride-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; color: var(--qq-text-body); }
.qq-ride-chip { background: var(--qq-mute-bg); border-radius: 99px; padding: 2px 9px; font-size: 11.5px; font-weight: 600; color: var(--qq-text-muted); }
.qq-ride-price { display: flex; align-items: baseline; gap: 10px; margin-top: auto; }
.qq-ride-price .amt { font-size: 20px; font-weight: 700; }
.qq-ride-price .per { font-size: 12px; color: var(--qq-text-muted); }
.qq-ride-star { color: #b8891f; }
@media (max-width: 720px) {
    .qq-ride-card { flex-direction: column; }
    .qq-ride-cover { width: auto; height: 130px; min-height: 0; }
    .qq-ride-body { padding: 13px 15px; }
    .qq-ride-city { font-size: 16px; }
}

/* Segmented search bar (B2) */
.qq-ride-search { position: relative; z-index: 5; display: flex; align-items: stretch; background: var(--qq-paper); border: 1px solid var(--qq-border); border-radius: 10px; box-shadow: 0 4px 14px rgba(23, 21, 18, .07); overflow: hidden; }
/* The bar clips for its rounded corners, which would slice the date popover in half (the same trap as .qq-card, above): un-clip only while the picker is open. */
.qq-ride-search:has(.qq-dt.is-open) { overflow: visible; }
.qq-ride-search .qq-dt-field { width: 100%; }
.qq-ride-search > .seg { flex: 1.2; padding: 10px 18px; border-right: 1px solid var(--qq-border-soft); min-width: 0; }
.qq-ride-search > .seg.date { flex: 1; }
.qq-ride-search > .seg.seats { flex: 0 0 120px; }
.qq-ride-search .k { font-family: var(--qq-admin-mono); font-size: 10px; color: var(--qq-text-faint); letter-spacing: .06em; }
.qq-ride-search input, .qq-ride-search .v { border: 0; outline: 0; background: transparent; font: 600 14.5px/1.4 inherit; font-family: inherit; color: var(--qq-text); width: 100%; padding: 2px 0; }
.qq-ride-search .swap { display: flex; align-items: center; color: var(--qq-gold-bright); font-size: 15px; cursor: pointer; padding: 0 2px; background: none; border: 0; }
.qq-ride-search .go { display: flex; align-items: center; padding: 0 30px; background: var(--qq-ink); color: var(--qq-paper); font-size: 14px; font-weight: 600; border: 0; cursor: pointer; }
.qq-ride-search .step { display: flex; align-items: center; gap: 10px; font-size: 14.5px; font-weight: 600; padding: 2px 0; }
.qq-ride-search .step button { background: none; border: 0; cursor: pointer; color: var(--qq-text); font-size: 15px; padding: 0 2px; }
.qq-ride-search .step button:disabled { color: var(--qq-text-faint); }
@media (max-width: 720px) {
    .qq-ride-search { flex-wrap: wrap; border-radius: 14px; }
    .qq-ride-search > .seg { flex: 1 1 45%; border-bottom: 1px solid var(--qq-border-soft); }
    /* Three classes here beat the desktop .seg.date / .seg.seats rules, which otherwise keep flex:1 and squeeze the date into whatever is left of the row. */
    .qq-ride-search > .seg.date { flex: 1 1 100%; }
    .qq-ride-search > .seg.seats { flex: 1 1 100%; }
    .qq-ride-search .swap { display: none; }
    .qq-ride-search .go { flex: 1 1 100%; padding: 14px; justify-content: center; }
}
.qq-day-chip { border: 1px solid var(--qq-border); background: var(--qq-paper); border-radius: 99px; padding: 5px 12px; font-size: 12.5px; font-weight: 600; color: var(--qq-text); text-decoration: none; white-space: nowrap; }
.qq-day-chip:hover { border-color: var(--qq-gold-bright); color: var(--qq-text); }

/* Seat map: photo hotspots or schematic (B4, D1, D3) */
.qq-seatmap-photo { position: relative; height: 250px; border-radius: 14px; background: linear-gradient(160deg, #4a463e, #2e2b26 60%, #232019); background-size: cover; background-position: center; overflow: hidden; }
.qq-seatmap-compact .qq-seatmap-photo { height: 120px; }
.qq-seat-marker { position: absolute; transform: translate(-50%, -50%); width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-family: var(--qq-admin-mono); font-size: 10px; font-weight: 700; cursor: pointer; border: 2px solid; }
.qq-seatmap-car { border: 2px solid var(--qq-border); border-radius: 26px 26px 18px 18px; padding: 16px 18px 14px; background: var(--qq-paper); position: relative; }
.qq-seatmap-compact .qq-seatmap-car { padding: 10px 10px 8px; border-radius: 18px 18px 12px 12px; }
.qq-seatmap-nose { position: absolute; left: 50%; top: -2px; transform: translateX(-50%); width: 90px; height: 8px; border-radius: 0 0 8px 8px; background: var(--qq-border); }
.qq-seatmap-compact .qq-seatmap-nose { width: 54px; height: 6px; }
.qq-seatmap-row { display: grid; gap: 10px; margin-bottom: 10px; }
.qq-seatmap-row:last-child { margin-bottom: 0; }
.qq-seatmap-compact .qq-seatmap-row { gap: 6px; margin-bottom: 6px; }
.qq-seat-cell { height: 64px; border-radius: 12px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; cursor: pointer; border: 2px solid; padding: 0; }
.qq-seatmap-compact .qq-seat-cell { height: 38px; border-radius: 9px; }
.qq-seat-glyph { font-family: var(--qq-admin-mono); font-size: 13px; font-weight: 700; }
.qq-seatmap-compact .qq-seat-glyph { font-size: 11px; }
.qq-seat-label { font-size: 10.5px; font-weight: 600; }
.qq-seat-marker.is-open, .qq-seat-cell.is-open { background: var(--qq-card); color: var(--qq-text); border-color: #b8891f; border-style: solid; }
.qq-seat-marker.is-selected, .qq-seat-cell.is-selected { background: var(--qq-ink); color: var(--qq-paper); border-color: var(--qq-ink); border-style: solid; }
.qq-seat-marker.is-taken, .qq-seat-cell.is-taken { background: var(--qq-mute-bg); color: var(--qq-text-faint); border-color: var(--qq-mute-bg); border-style: solid; cursor: default; }
.qq-seat-marker.is-driver, .qq-seat-cell.is-driver { background: var(--qq-paper); color: var(--qq-text-faint); border-color: var(--qq-gold-soft); border-style: dashed; cursor: default; }
.qq-seat-marker.is-off, .qq-seat-cell.is-off { background: var(--qq-paper); color: var(--qq-text-faint); border-color: var(--qq-border); border-style: dotted; cursor: default; opacity: .6; }
.qq-seat-marker:disabled, .qq-seat-cell:disabled { cursor: default; }
.qq-seat-legend { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 10px; font-size: 11px; color: var(--qq-text-muted); }
.qq-seat-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 3px; vertical-align: -1px; margin-right: 3px; }
.qq-any-seat { margin-top: 12px; border: 1px dashed var(--qq-border); border-radius: 12px; padding: 10px 14px; text-align: center; font-size: 13px; font-weight: 600; color: var(--qq-text-body); background: transparent; width: 100%; cursor: pointer; }
.qq-any-seat.on { background: var(--qq-ink); color: var(--qq-paper); border-color: var(--qq-ink); }

/* Hotspot editor (D1) */
.qq-hotspot-host { position: relative; height: 230px; border-radius: 14px; background: linear-gradient(160deg, #4a463e, #2e2b26 60%, #232019); background-size: cover; background-position: center; overflow: hidden; touch-action: none; user-select: none; }
.qq-hotspot { position: absolute; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; gap: 3px; cursor: grab; }
.qq-hotspot.is-dragging { cursor: grabbing; }
.qq-hotspot-dot { width: 34px; height: 34px; border-radius: 50%; background: rgba(217, 169, 78, .92); color: #171512; display: flex; align-items: center; justify-content: center; font-family: var(--qq-admin-mono); font-size: 12px; font-weight: 700; border: 2px solid #f4f0e8; box-shadow: 0 3px 10px rgba(0, 0, 0, .4); pointer-events: none; }
.qq-hotspot.is-dragging .qq-hotspot-dot { border-color: #d9a94e; }
.qq-hotspot-label { font-size: 10px; font-weight: 700; color: #f4f0e8; background: rgba(23, 21, 18, .7); padding: 1px 7px; border-radius: 99px; white-space: nowrap; pointer-events: none; }

/* Layout tiles (D1) */
.qq-layout-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.qq-layout-tile { border: 2px solid var(--qq-border); background: var(--qq-card); border-radius: 14px; padding: 12px 10px; text-align: center; cursor: pointer; }
.qq-layout-tile .n { display: block; font-family: var(--qq-admin-mono); font-size: 17px; font-weight: 700; color: var(--qq-text-faint); }
.qq-layout-tile .nm { display: block; font-size: 12px; font-weight: 600; margin-top: 2px; color: var(--qq-text); }
.qq-layout-tile.on { border-color: var(--qq-ink); background: var(--qq-paper); }
.qq-layout-tile.on .n { color: var(--qq-text); }

/* Per-seat Offered rows (D3) and preference chips (D2) */
.qq-offer-row { display: flex; align-items: center; gap: 10px; border: 1px solid var(--qq-border); background: var(--qq-card); border-radius: 11px; padding: 9px 13px; cursor: pointer; width: 100%; text-align: left; font-size: 13px; color: var(--qq-text); }
.qq-offer-row:not(.on) { background: var(--qq-paper); border-color: var(--qq-border-soft); color: var(--qq-text-faint); }
.qq-offer-row:disabled { cursor: default; opacity: .8; }
.qq-offer-box { width: 18px; height: 18px; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; border: 2px solid var(--qq-track-off); background: var(--qq-card); color: var(--qq-paper); flex-shrink: 0; }
.qq-offer-row.on .qq-offer-box { background: var(--qq-ink); border-color: var(--qq-ink); }
.qq-pref-chip { font-size: 12.5px; font-weight: 600; color: var(--qq-text-body); border: 1px solid var(--qq-border); background: var(--qq-paper); padding: 7px 16px; border-radius: 99px; cursor: pointer; }
.qq-pref-chip.on { background: var(--qq-ink); color: var(--qq-paper); border-color: var(--qq-ink); font-weight: 700; }
.qq-input-sm { padding: 6px 10px; font-size: .88rem; }

/* Dashboard tile (D5) and home card (B1): fixed ink surfaces, fixed inks. */
.qq-ride-tile { position: relative; overflow: hidden; background: #171512; color: #f4f0e8; border-radius: 18px; padding: 20px 24px; }
.qq-ride-tile-line { position: absolute; right: -20px; top: 24px; width: 120px; height: 2px; background: repeating-linear-gradient(90deg, #d9a94e 0 6px, transparent 6px 11px); opacity: .3; }
.qq-ride-tile-eyebrow { font-family: var(--qq-admin-mono); font-size: 10.5px; letter-spacing: .14em; color: #d9a94e; }
.qq-ride-tile-title { font-size: 20px; font-weight: 700; letter-spacing: -.02em; margin-top: 6px; color: #f4f0e8; }
.qq-ride-tile .qq-seatbar > span { background: #d9a94e; }
.qq-home-ride { background: #171512; border-radius: 18px; padding: 22px 24px; display: flex; flex-direction: column; color: #f4f0e8; position: relative; overflow: hidden; min-height: 200px; }
.qq-home-ride .cta { margin-top: auto; display: flex; align-items: center; justify-content: center; background: #d9a94e; color: #171512; font-size: 14px; font-weight: 700; padding: 11px; border-radius: 99px; text-decoration: none; }
.qq-home-ride .cta:hover { background: #e7c078; color: #171512; }
.qq-home-ride .count { display: flex; align-items: center; gap: 8px; margin-top: 14px; font-size: 12.5px; color: #a39a88; }
.qq-home-ride .count i { width: 8px; height: 8px; border-radius: 50%; background: #7fb08a; display: inline-block; }

/* Buyer pages (B2–B5): the /rides shell, the departure page grid with its sticky
   booking card, the gallery, the confirm-step payment options, the ride card on
   the booking page and the storefront's departures block. */
.qq-rides { max-width: 1040px; margin: 0 auto; padding: 8px 0 40px; }
.qq-ride-page { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 22px; align-items: start; }
.qq-ride-side { position: sticky; top: 84px; padding: 20px 22px; }
@media (max-width: 900px) {
    .qq-ride-page { grid-template-columns: 1fr; }
    .qq-ride-side { position: static; }
}
.qq-ride-hero { display: block; height: 320px; border-radius: 18px; background: linear-gradient(160deg, #4a463e, #2e2b26 60%, #232019) center/cover no-repeat; position: relative; overflow: hidden; }
.qq-ride-thumbs { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; margin-top: 8px; }
.qq-ride-thumbs > a { display: flex; align-items: center; justify-content: center; height: 64px; border-radius: 10px; background: var(--qq-mute-bg) center/cover no-repeat; color: #f4f0e8; text-decoration: none; }
.qq-ride-thumbs > a.is-video > span { background: rgba(23, 21, 18, .7); border-radius: 50%; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; }
.qq-pay-opt { text-align: left; width: 100%; border: 1.5px solid var(--qq-border); background: var(--qq-card); border-radius: 12px; padding: 10px 14px; cursor: pointer; color: var(--qq-text); }
.qq-pay-opt.on { border-color: var(--qq-ink); background: var(--qq-paper); box-shadow: 0 0 0 1px var(--qq-ink) inset; }
.qq-as-ride { display: flex; flex-wrap: wrap; gap: 18px; align-items: flex-start; }
.qq-as-ride > div:first-child { flex: 0 0 200px; max-width: 100%; }
.qq-as-ride > div:last-child { flex: 1 1 220px; min-width: 0; }
.qq-as-ride-plate { display: inline-block; font-family: var(--qq-admin-mono); font-weight: 700; letter-spacing: .12em; border: 2px solid var(--qq-ink); color: var(--qq-text); border-radius: 6px; padding: 2px 10px; margin-top: 4px; }
.qq-home-ride-band { max-width: 1140px; margin: 1.5rem auto 1.5rem; padding: 0 1rem; }
.qq-home-ride.wide { flex-direction: row; align-items: center; gap: 24px; min-height: 0; }
.qq-home-ride.wide .cta { margin-top: 0; padding: 11px 22px; white-space: nowrap; }
@media (max-width: 640px) {
    .qq-home-ride.wide { flex-direction: column; align-items: stretch; }
    .qq-home-ride.wide .cta { margin-top: 14px; }
}
.sf-ride-row { text-decoration: none; color: inherit; }
.sf-ride-row:hover { color: inherit; }
