/* Focus Project — application stylesheet (2026 redesign).
 * Built on tokens.css. Hand-rolled, no third-party deps.
 * Drop-in replacement for app.css. All existing class names are preserved
 * so the ~20 admin templates inherit the new look without changes.
 */

@import url("https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap");

/* ───────────────────────────────────────────── reset + base ──── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; min-height: 100%; }
body {
    font-family: var(--font-sans);
    font-size: var(--fs-md);
    line-height: 1.45;
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    /* Geist-specific feature flags: ss01 alt zero/r, cv11 narrowed
       digits. tnum keeps numerals aligned in tables. */
    font-feature-settings: "ss01", "cv11";
    font-variant-numeric: tabular-nums;
    min-height: 100vh;
    /* Layered backdrop: ambient accent halo glowing from above-center
       fading into the deep-bg color at the bottom of the viewport.
       Fixed attachment so scrolling doesn't repeat the gradient. */
    background:
        radial-gradient(ellipse 1200px 600px at 50% -200px,
            color-mix(in oklch, var(--accent) 12%, transparent) 0%,
            transparent 70%),
        linear-gradient(180deg, var(--bg) 0%, var(--bg-deep) 100%);
    background-attachment: fixed;
}
/* Optional scanline overlay — toggled via the tweaks panel by
   setting body[data-chrome="scanline"]. Default ships solid. */
body[data-chrome="scanline"]::before {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    background-image: repeating-linear-gradient(0deg,
        transparent 0 2px,
        oklch(0 0 0 / 0.18) 2px 3px);
    z-index: 100;
    mix-blend-mode: multiply;
}
::selection { background: var(--accent); color: var(--text-on-accent); }
img { max-width: 100%; height: auto; display: block; }

/* ────────────────────────────────────────────── typography ──── */
/* Heading hierarchy. Tight tracking + slightly heavier weight at h1
   so the page anchor reads as confident; subsequent levels relax
   weight so the eye knows what's primary. line-height stays tight
   (1.15 at h1, gradual loosen) — generic body line-height of 1.55
   is reserved for paragraphs. */
h1, h2, h3, h4, h5, h6 {
    margin: 0 0 var(--s-3);
    line-height: 1.15;
    color: var(--text);
    font-weight: 600;
    letter-spacing: -0.022em;
    /* OpenType "small caps for numerals" is too quirky; we just want
       proportional-style fallback so headlines stop looking monospace. */
    font-variant-numeric: lining-nums proportional-nums;
}
h1 { font-size: var(--fs-2xl); letter-spacing: -0.028em; font-weight: 650; }
h2 { font-size: var(--fs-xl);  margin-top: var(--s-10); letter-spacing: -0.024em; }
h3 { font-size: var(--fs-md);  margin-top: var(--s-6); margin-bottom: var(--s-2); letter-spacing: -0.018em; }
h4 { font-size: var(--fs-base); margin-bottom: var(--s-1); font-weight: 600; }

p { margin: var(--s-2) 0; color: var(--text); }
p.lead { font-size: var(--fs-lg); line-height: 1.6; color: var(--text-muted); }

a {
    color: var(--text);
    text-decoration: underline;
    text-decoration-color: var(--border-strong);
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
    transition: color var(--t-fast) var(--ease), text-decoration-color var(--t-fast) var(--ease);
}
a:hover { color: var(--accent); text-decoration-color: var(--accent); }
a.muted { color: var(--text-muted); }
a.muted:hover { color: var(--text); text-decoration-color: var(--text-muted); }
a.unstyled, a.unstyled:hover { text-decoration: none; }

small, .muted { color: var(--text-muted); }
.faint { color: var(--text-faint); }
.eyebrow {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--text-muted);
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
/* Accent dot before eyebrow — gives the cyber tag-line feel. Add
   .no-dot to suppress. */
.eyebrow::before {
    content: "";
    width: 6px;
    height: 6px;
    background: var(--accent);
    border-radius: 50%;
    box-shadow: 0 0 10px var(--accent);
}
.eyebrow.no-dot::before { display: none; }

code, kbd {
    font-family: var(--font-mono);
    font-size: 0.92em;
    background: var(--surface-2);
    padding: 0.1em 0.4em;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    color: var(--text);
}
code.key { white-space: nowrap; font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
.mono { font-family: var(--font-mono); letter-spacing: 0.02em; }
.tabular { font-variant-numeric: tabular-nums; }

pre {
    background: var(--inset);
    border: 1px solid var(--border);
    padding: var(--s-4);
    border-radius: var(--radius-md);
    overflow-x: auto;
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--text);
    line-height: 1.6;
}
pre code { background: none; border: none; padding: 0; }

.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
}
.table-scroll > table { border: none; border-radius: 0; margin: 0; }

/* ────────────────────────────────────────────────── header ──── */
/* Floating pill nav, hairline border, glass blur. */
header.app {
    position: sticky;
    top: 0;
    z-index: 50;
    /* Flat backdrop-blur topnav (matches the FOCUS / Sigil reskin).
       Translucent surface + saturate boost + heavy blur so content
       scrolling underneath softens. The 1px border-bottom is the
       hard-edge anchor — a thin border keeps the topnav feeling
       like a navigation surface without an aggressive divider. */
    background: color-mix(in oklch, var(--bg) 75%, transparent);
    backdrop-filter: saturate(160%) blur(14px);
    -webkit-backdrop-filter: saturate(160%) blur(14px);
    border-bottom: 1px solid var(--border);
    padding: 0;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    header.app { background: var(--bg-deep); }
}
header.app nav {
    max-width: var(--container);
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: var(--s-5);
    padding: 14px 32px;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--text);
    text-decoration: none;
    font-weight: 600;
    font-size: var(--fs-md);
    letter-spacing: 0.02em;
    border: none;
    padding: 4px 4px 4px 0;
}
.brand:hover { color: var(--text); text-decoration: none; }
.brand .brand-mark {
    display: inline-flex;
    width: 22px;
    height: 22px;
    color: var(--text);
}
.brand .accent { color: var(--accent); }

header.app nav .nav-links {
    display: flex;
    gap: 4px;
    align-items: center;
}
header.app nav .nav-links a {
    position: relative;
    padding: 7px 12px;
    border-radius: var(--radius);
    color: var(--text-muted);
    text-decoration: none;
    font-size: var(--fs-sm);
    font-weight: 500;
    border: none;
    transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
header.app nav .nav-links a:hover { color: var(--text); background: var(--surface); }
header.app nav .nav-links a.active {
    color: var(--text);
    background: var(--surface-2);
}
/* Active marker dot — kept as a subtle accent indicator above the
   pill, NOT inside it. */
header.app nav .nav-links a.active::before {
    content: none;
}

header.app .spacer { flex: 1; }

/* "All systems nominal" pulse pill — sits between nav links and
   the right-side controls. Pulses to communicate live status. */
.nav-status {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    background: var(--surface);
    font-weight: 500;
}
.nav-status::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 8px var(--accent);
    animation: nav-status-pulse 2s ease-in-out infinite;
}
@keyframes nav-status-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}
@media (max-width: 880px) {
    .nav-status { display: none; }
}

/* Theme toggle button. Lives in the header next to Sign in / Sign out.
   Two SVGs nested inside; CSS swaps them based on [data-theme]. The
   moon shows in dark mode (because clicking will switch you to light);
   the sun shows in light mode (click to go back to dark). */
.theme-toggle {
    appearance: none;
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-muted);
    width: 32px;
    height: 32px;
    border-radius: var(--radius-full);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color var(--t-fast) var(--ease),
                border-color var(--t-fast) var(--ease),
                background var(--t-fast) var(--ease);
}
.theme-toggle:hover {
    color: var(--text);
    border-color: var(--border-strong);
    background: var(--surface-2);
}
.theme-toggle:focus-visible {
    outline: none;
    box-shadow: var(--ring-focus);
}
.theme-toggle__icon { display: none; }
.theme-toggle__icon--moon { display: inline-flex; }
[data-theme="light"] .theme-toggle__icon--moon { display: none; }
[data-theme="light"] .theme-toggle__icon--sun  { display: inline-flex; }

header.app .pill {
    font-family: var(--font-mono);
    font-size: 10px;
    padding: 3px 9px;
    border-radius: var(--radius-full);
    border: 1px solid var(--border);
    color: var(--text-muted);
    text-transform: lowercase;
}

/* ────────────────────────────────────────────── main / sidebar ──── */
main {
    max-width: var(--container);
    margin: 0 auto;
    padding: var(--s-10) var(--s-6) var(--s-20);
    position: relative;
}
main.with-sidebar {
    display: grid;
    grid-template-columns: var(--sidebar) minmax(0, 1fr);
    gap: var(--s-10);
    align-items: start;
}
main > section { min-width: 0; }

aside.sidebar {
    position: sticky;
    top: calc(var(--header) + var(--s-6));
}
aside.sidebar ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* Section labels above groups. Plain <li> inside the <ul> with the
   .sidebar-section-label class — no extra wrapper needed. The
   uppercase mono text reads as a "header" not a clickable nav item. */
aside.sidebar li.sidebar-section-label {
    padding: var(--s-3) 12px 6px;
    font-family: var(--font-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-faint);
    pointer-events: none;
}
aside.sidebar li.sidebar-section-label:first-child { padding-top: 0; }
aside.sidebar a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px 8px 16px;
    border-radius: var(--radius);
    color: var(--text-muted);
    text-decoration: none;
    font-size: var(--fs-sm);
    border: none;
    position: relative;
    transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
aside.sidebar a:hover { color: var(--text); background: var(--surface-2); }
aside.sidebar a.active {
    color: var(--text);
    background: var(--surface-2);
}
/* Thicker (3px) accent bar on the active item — more legible at a
   glance than the previous 2px inset shadow, and survives in
   light mode where the inset shadow had low contrast. */
aside.sidebar a.active::before {
    content: "";
    position: absolute;
    left: 0;
    top: 4px;
    bottom: 4px;
    width: 3px;
    border-radius: 2px;
    background: var(--accent);
    box-shadow: 0 0 8px var(--accent-glow);
}
aside.sidebar a.active::after {
    content: "→";
    color: var(--accent);
    font-size: var(--fs-xs);
    font-family: var(--font-mono);
}

/* ──────────────────────────────────────────────────── footer ──── */
footer.app {
    border-top: 1px solid var(--border-faint);
    color: var(--text-muted);
    font-size: var(--fs-sm);
    padding: var(--s-12) var(--s-6) var(--s-8);
    margin-top: var(--s-24);
}
footer.app .footer-row {
    max-width: var(--container);
    margin: 0 auto;
    display: grid;
    grid-template-columns: 2fr 1fr 1fr auto;
    gap: var(--s-10);
    align-items: start;
}
footer.app .footer-col h4 {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--text-faint);
    font-family: var(--font-mono);
    font-weight: 500;
    margin: 0 0 12px;
}
footer.app .footer-col ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 8px;
}
footer.app .footer-col a {
    color: var(--text-muted);
    text-decoration: none;
    font-size: var(--fs-sm);
    border: none;
}
footer.app .footer-col a:hover { color: var(--text); }
footer.app .footer-brand strong {
    color: var(--text);
    font-size: var(--fs-md);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}
footer.app .footer-brand p {
    margin: 0;
    color: var(--text-faint);
    font-size: var(--fs-sm);
    max-width: 32ch;
}
footer.app .footer-status { justify-self: end; }
footer.app .status-dot {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--text-muted);
    font-size: var(--fs-sm);
}
footer.app .status-dot::before {
    content: "";
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--ok);
    box-shadow: 0 0 0 3px var(--ok-tint);
}
footer.app .footer-meta {
    max-width: var(--container);
    margin: var(--s-10) auto 0;
    padding-top: var(--s-5);
    border-top: 1px solid var(--border-faint);
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-faint);
}
@media (max-width: 800px) {
    footer.app .footer-row { grid-template-columns: 1fr 1fr; gap: var(--s-6); }
    footer.app .footer-status { justify-self: start; grid-column: 1 / -1; }
    footer.app .footer-meta { flex-direction: column; gap: 8px; }
}

/* ──────────────────────────────────────────────────── card ──── */
/* Cards are the universal container for grouped content on admin
   pages. Two-layer feel: subtle gradient surface + a 1px top-light
   highlight via inset shadow. Hover-elevation lives under
   .card.interactive — non-interactive cards stay still so the page
   doesn't feel jumpy when the cursor passes over them. */
.card {
    background: var(--grad-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--s-6);
    box-shadow: var(--shadow-card);
    position: relative;
}
.card + .card { margin-top: var(--s-4); }
.card.compact { padding: var(--s-5); max-width: 28rem; }
.card.padless { padding: 0; }
.card.interactive {
    transition: transform var(--t-base) var(--ease),
                box-shadow var(--t-base) var(--ease),
                border-color var(--t-base) var(--ease);
}
.card.interactive:hover {
    transform: translateY(var(--lift-2));
    box-shadow: var(--shadow-card-hover);
    border-color: var(--border-strong);
}
.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-3);
    margin-bottom: var(--s-4);
}

/* ────────────────────────────────────────── auth split-screen ──── */
.auth-shell {
    display: grid;
    grid-template-columns: 1.2fr 1fr;
    gap: var(--s-12);
    min-height: 70vh;
    align-items: center;
    margin: var(--s-6) auto var(--s-12);
}
.auth-shell .auth-pitch { padding: var(--s-6) 0; }
.auth-shell .auth-pitch .eyebrow { margin-bottom: var(--s-3); display: inline-block; }
.auth-shell .auth-pitch h1 {
    font-size: var(--fs-3xl);
    letter-spacing: -0.03em;
    margin: 0 0 var(--s-4);
}
.auth-shell .auth-pitch p {
    color: var(--text-muted);
    font-size: var(--fs-md);
    max-width: 42ch;
    margin: 0;
}
.auth-shell .feature-list {
    list-style: none;
    padding: 0;
    margin: var(--s-7) 0 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.auth-shell .feature-list li {
    display: grid;
    grid-template-columns: 24px 1fr;
    gap: 12px;
    font-size: var(--fs-sm);
    color: var(--text-dim);
    padding: 8px 0;
    align-items: start;
}
.auth-shell .feature-list li::before {
    content: "+";
    font: 500 16px/1 var(--font-mono);
    color: var(--accent);
    margin-top: 1px;
}

.auth-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--s-8);
    box-shadow: var(--shadow-card);
}
.auth-card .auth-head { margin-bottom: var(--s-5); }
.auth-card .auth-head h1 { font-size: var(--fs-xl); margin: 0 0 6px; }
.auth-card .auth-head p { color: var(--text-muted); margin: 0; font-size: var(--fs-sm); }
.auth-card .auth-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: var(--text-muted);
    font-size: var(--fs-xs);
    border-top: 1px solid var(--border-faint);
    padding-top: var(--s-3);
    margin-top: var(--s-3);
}
.auth-card .auth-foot a {
    color: var(--text);
    border-bottom: 1px solid var(--border-strong);
    text-decoration: none;
    padding-bottom: 1px;
}
.auth-card .auth-foot a:hover { color: var(--accent); border-color: var(--accent); }

@media (max-width: 900px) {
    .auth-shell { grid-template-columns: 1fr; gap: var(--s-8); }
}

/* ────────────────────────────────────────────── forms ──── */
form { display: grid; gap: var(--s-4); }
form.inline { display: inline; gap: 0; margin: 0; }
form.compact { max-width: 30rem; }

label {
    display: grid;
    gap: 6px;
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--text);
}
label .hint {
    color: var(--text-muted);
    font-weight: 400;
    font-size: var(--fs-xs);
    margin-left: 4px;
}
label > input,
label > select,
label > textarea { color: var(--text); font-weight: 400; }

input, select, textarea {
    font: inherit;
    font-family: var(--font-sans);
    font-size: var(--fs-sm);
    padding: 11px 14px;
    background: var(--inset);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    width: 100%;
    transition: border-color var(--t-fast) var(--ease),
                box-shadow var(--t-fast) var(--ease),
                background var(--t-fast) var(--ease);
    /* Inset 1px shadow gives the input field a "pressed in" depth
       cue at rest — reads as an input even before the user clicks. */
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
}
input::placeholder, textarea::placeholder {
    color: var(--text-faint);
    opacity: 0.75;
}
input:hover, select:hover, textarea:hover { border-color: var(--border-strong); }
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--surface-2);
    box-shadow:
        inset 0 1px 2px rgba(0, 0, 0, 0.10),
        0 0 0 3px var(--accent-ring);
}
input:disabled, select:disabled, textarea:disabled { opacity: 0.5; cursor: not-allowed; }

input.mono, .input-mono {
    font-family: var(--font-mono);
    letter-spacing: 0.04em;
}

/* ────────────────────────────────────────────── buttons ──── */
/* Three-tier button system: primary (filled accent w/ gradient),
   secondary (outlined neutral), ghost (no chrome). Each gets a
   micro-lift on hover and a subtle press depth. Primary uses the
   --grad-accent gradient + an inner highlight so it reads as a
   physical surface, not a flat blob. Sharp 6px radius keeps the
   tech-edge silhouette. */
button, .btn {
    appearance: none;
    font: inherit;
    font-family: var(--font-sans);
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: -0.005em;
    padding: 9px 16px;
    background: var(--grad-accent);
    color: var(--text-on-accent);
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    line-height: 1.2;
    white-space: nowrap;
    /* Inner highlight + outer subtle shadow give the button physical
       presence at rest. Hover and active states modulate the shadow,
       not the gradient — saves the gradient for the "snap" feel. */
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.18),
        0 1px 2px rgba(0, 0, 0, 0.25);
    transition: background var(--t-fast) var(--ease),
                border-color var(--t-fast) var(--ease),
                color var(--t-fast) var(--ease),
                box-shadow var(--t-fast) var(--ease),
                transform var(--t-fast) var(--ease);
    will-change: transform;
}
button:hover, .btn:hover {
    background: var(--grad-accent-hover);
    border-color: var(--accent-hover);
    color: var(--text-on-accent);
    transform: translateY(var(--lift-1));
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.22),
        0 6px 20px -6px var(--accent-glow),
        0 2px 4px rgba(0, 0, 0, 0.2);
}
button:active, .btn:active {
    background: var(--accent-press);
    border-color: var(--accent-press);
    transform: translateY(0.5px);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.18),
        0 0 0 1px var(--accent-press);
}
button:focus-visible, .btn:focus-visible {
    outline: none;
    box-shadow: var(--ring-focus);
}

button.secondary, .btn.secondary {
    background: var(--grad-surface);
    color: var(--text);
    border: 1px solid var(--border-strong);
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.04),
        0 1px 2px rgba(0, 0, 0, 0.20);
}
button.secondary:hover, .btn.secondary:hover {
    background: var(--surface-3);
    border-color: var(--border-strong);
    color: var(--text);
    transform: translateY(var(--lift-1));
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.06),
        0 4px 12px -4px rgba(0, 0, 0, 0.35);
}

button.ghost, .btn.ghost {
    background: transparent;
    color: var(--text-muted);
    border: 1px solid transparent;
    box-shadow: none;
}
button.ghost:hover, .btn.ghost:hover {
    background: var(--surface-2);
    color: var(--text);
    transform: none;
    box-shadow: none;
}

button.danger, .btn.danger {
    background: transparent;
    color: var(--accent);
    border: 1px solid var(--border-strong);
    box-shadow: none;
}
button.danger:hover, .btn.danger:hover {
    background: var(--accent-tint);
    color: var(--accent-hover);
    border-color: var(--accent);
    transform: translateY(var(--lift-1));
    box-shadow: 0 4px 14px -6px var(--accent-glow);
}

button.small, .btn.small { padding: 5px 11px; font-size: var(--fs-xs); }
button.large, .btn.large { padding: 12px 24px; font-size: var(--fs-md); font-weight: 600; }

button.link {
    background: none;
    border: none;
    padding: 0;
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: 3px;
    box-shadow: none;
    transform: none;
    font-weight: 500;
}
button.link:hover { background: none; transform: none; box-shadow: none; }
button:disabled, .btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}
button:disabled:hover, .btn:disabled:hover {
    transform: none;
    box-shadow: none;
}

.btn .arrow { transition: transform var(--t-base) var(--ease); display: inline-block; }
.btn:hover .arrow { transform: translateX(3px); }

/* ────────────────────────────────────────────── tables ──── */
table {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
}
thead tr { background: var(--surface-2); }
th, td {
    padding: 10px 14px;
    text-align: left;
    border-bottom: 1px solid var(--border-faint);
    font-size: var(--fs-sm);
    vertical-align: middle;
}
th {
    font-weight: 500;
    color: var(--text-faint);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-family: var(--font-mono);
}
tbody tr:last-child td { border-bottom: none; }
tbody tr {
    transition: background var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
/* Zebra striping for dense admin tables. Subtle — the even rows
   get a barely-different surface tone (not full --surface-2 which
   we reserve for hover). Light theme uses the same token system so
   contrast stays consistent. */
tbody tr:nth-child(even) {
    background: color-mix(in srgb, var(--surface-2) 55%, transparent);
}
tbody tr:hover {
    background: var(--surface-2);
    box-shadow: inset 2px 0 0 var(--accent);
}
td.actions { white-space: nowrap; text-align: right; }
td.actions form, td.actions .btn { display: inline-flex; margin-left: 6px; }

td.session-actions { white-space: normal; min-width: 14ch; }
td.session-actions .btn, td.session-actions form {
    display: inline-flex; margin: 2px 0 2px 6px;
}
td.session-actions form button { width: 100%; }

/* ────────────────────────────────────────────── badges ──── */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: var(--radius-full);
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 10px;
    font-weight: 500;
    font-family: var(--font-mono);
    text-transform: lowercase;
    letter-spacing: 0.06em;
    line-height: 1.5;
}
.badge::before {
    content: "";
    width: 5px; height: 5px;
    border-radius: 50%;
    background: currentColor;
}
.badge.unused, .badge.expired { color: var(--text-faint); }
.badge.redeemed, .badge.active, .badge.ok { color: var(--ok); border-color: rgba(95, 207, 134, 0.25); background: var(--ok-tint); }
.badge.paused, .badge.warn { color: var(--warn); border-color: rgba(232, 164, 74, 0.25); background: var(--warn-tint); }
.badge.revoked, .badge.banned, .badge.danger, .badge.admin { color: var(--accent); border-color: rgba(239, 58, 58, 0.30); background: var(--accent-tint); }
/* Role tints for quick visual triage in user lists / details.
   Reseller = green (paying partner), support = orange (operational
   helper). Owner stays accent-red (top-level), admin stays accent
   too. Tints are slightly stronger than the status badges above so
   role chips stand out next to license-status badges. */
.badge.reseller { color: var(--ok);     border-color: rgba(95, 207, 134, 0.40); background: rgba(95, 207, 134, 0.12); }
.badge.support  { color: #f0a500;       border-color: rgba(240, 165, 0, 0.40);  background: rgba(240, 165, 0, 0.12); }

/* Risk-row tints (audit log). */
.risk-row.risk-red    { background: rgba(239, 58, 58, 0.04); box-shadow: inset 3px 0 0 var(--accent); }
.risk-row.risk-yellow { background: rgba(232, 164, 74, 0.04); }
.risk-dot {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 50%;
    margin-right: 6px;
    vertical-align: middle;
}
.risk-dot.risk-red    { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.risk-dot.risk-yellow { background: var(--warn);   box-shadow: 0 0 0 3px var(--warn-tint); }
.risk-dot.risk-green  { background: var(--ok);     box-shadow: 0 0 0 3px var(--ok-tint); }

/* Security events row classes (admin/security_events.html). */
tr.sec-event-row { transition: background var(--t-fast) var(--ease); }
tr.sec-event-row:hover { background: var(--surface-2); }
tr.sec-event-red {
    background: rgba(239, 58, 58, 0.06);
    box-shadow: inset 4px 0 0 var(--accent);
}
tr.sec-event-red:hover { background: rgba(239, 58, 58, 0.10); }
tr.sec-event-warn { box-shadow: inset 4px 0 0 rgba(232, 164, 74, 0.55); }

/* ────────────────────────────────────────────── stats ──── */
.stats {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    gap: 1px;
    background: var(--border-faint);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.stat {
    background: var(--surface);
    padding: 14px 18px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    border: none;
    border-radius: 0;
}
.stat .label {
    font-size: 10px;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    font-family: var(--font-mono);
}
.stat .value {
    font-size: var(--fs-xl);
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    padding-top: 0;
    border-top: none;
    margin-top: 0;
}
.stat .delta { font-size: var(--fs-xs); color: var(--text-muted); }
.stat .delta.up { color: var(--ok); }
.stat .delta.down { color: var(--accent); }

/* ────────────────────────────────────────────── alerts ──── */
/* Banner alerts use a 3px left bar of the variant color + a faint
   tint of the same color in the background. The body text stays
   the variant color so the message reads at a glance — green for
   success, amber for warning, red for error. */
.alert {
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-left-width: 3px;
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font-size: var(--fs-sm);
    line-height: 1.55;
    margin: var(--s-3) 0;
    box-shadow: var(--shadow-1);
}
.alert.ok    { border-left-color: var(--ok);     background: var(--ok-tint);     color: var(--ok); }
.alert.warn  { border-left-color: var(--warn);   background: var(--warn-tint);   color: var(--warn); }
.alert.error { border-left-color: var(--accent); background: var(--accent-tint); color: var(--accent); }

/* ─────────────────────────────────────── dialog (modal) ──── */
dialog {
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text);
    padding: var(--s-6);
    max-width: 34rem;
    width: calc(100% - var(--s-6));
    box-shadow: var(--shadow-overlay);
}
dialog::backdrop {
    /* Heavier backdrop blur than before — dialogs feel like proper
       modals when the content behind softens into the background. */
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(10px) saturate(120%);
    -webkit-backdrop-filter: blur(10px) saturate(120%);
}
[data-theme="light"] dialog::backdrop {
    /* Light theme uses a soft-light overlay instead of pitch black
       so the page underneath still has visible contour. */
    background: rgba(60, 60, 64, 0.40);
}
dialog h3 { margin-top: 0; }
dialog h4.eyebrow {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--text-faint);
    font-family: var(--font-mono);
    font-weight: 500;
    margin: var(--s-5) 0 var(--s-2);
}

/* ─────────────────────────────────────── filters bar ──── */
.filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-3);
    align-items: end;
}
.filters > label { flex: 1 1 160px; }
.filters > .actions { display: flex; gap: var(--s-2); }

/* ─────────────────────────────────────── pagination ──── */
.pagination {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--s-3);
    margin: var(--s-5) 0 0;
}
.pagination .disabled { opacity: 0.45; pointer-events: none; }

/* ─────────────────────────────────────── misc UI ──── */
.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-4);
    margin-top: var(--s-10);
    margin-bottom: var(--s-4);
}
.section-head h1, .section-head h2 { margin: 0; }

.empty {
    border: 1px dashed var(--border);
    background: transparent;
    border-radius: var(--radius-md);
    padding: var(--s-12) var(--s-6);
    text-align: center;
    color: var(--text-muted);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s-2);
}
.empty p { margin: 0; }
.empty strong {
    color: var(--text);
    font-size: var(--fs-md);
    font-weight: 600;
}
.empty__icon {
    font-size: 28px;
    color: var(--text-faint);
    margin-bottom: var(--s-1);
    line-height: 1;
}
.empty .btn { margin-top: var(--s-3); }

.action-bar {
    display: flex;
    gap: var(--s-2);
    align-items: center;
    flex-wrap: wrap;
    margin-top: var(--s-4);
}
.action-bar .spacer { flex: 1; }

/* Sticky save bar variant — used on long admin edit forms so the
   Save/Cancel buttons stay reachable while the operator scrolls
   through fields. Sticks to the bottom of the viewport ONLY when the
   form's bottom would otherwise be below the fold; once the user
   scrolls down to the bar's natural position it sits in place. */
.action-bar--sticky {
    position: sticky;
    bottom: 0;
    z-index: 5;
    margin: var(--s-4) calc(var(--s-5) * -1) calc(var(--s-5) * -1);
    padding: var(--s-3) var(--s-5);
    background: color-mix(in srgb, var(--surface) 92%, transparent);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border-top: 1px solid var(--border-strong);
    border-bottom-left-radius: var(--radius-md);
    border-bottom-right-radius: var(--radius-md);
}

.price-cell { display: inline-flex; align-items: end; gap: var(--s-2); margin: var(--s-1) var(--s-2) var(--s-1) 0; }
.price-cell input[type="number"] { width: 7rem; }

.money-input {
    position: relative;
    display: inline-flex;
    align-items: baseline;
    gap: 0.4ch;
}
.money-input::before { content: "$"; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.money-input::after {
    content: "USD";
    color: var(--text-muted);
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.money-input input[type="number"] { width: 6.5rem; }

.recovery-codes {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-2);
}
.recovery-codes code {
    display: block;
    text-align: center;
    padding: var(--s-3);
    font-size: var(--fs-md);
    background: var(--surface-2);
    border: 1px solid var(--border);
    letter-spacing: 0.05em;
}

.copy-btn {
    appearance: none;
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-muted);
    border-radius: var(--radius-sm);
    padding: 3px 9px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.copy-btn:hover { color: var(--text); border-color: var(--border-strong); background: var(--surface-2); }
.copy-btn.copied { color: var(--ok); border-color: rgba(95, 207, 134, 0.4); }

details.card summary {
    cursor: pointer;
    list-style: none;
    color: var(--text-muted);
    font-weight: 500;
    user-select: none;
    display: flex;
    align-items: center;
    gap: var(--s-2);
}
details.card summary::-webkit-details-marker { display: none; }
details.card summary::after {
    content: "+";
    color: var(--text-muted);
    margin-left: auto;
    transition: transform var(--t-fast) var(--ease);
}
details.card[open] summary::after { content: "−"; }
details.card[open] summary { color: var(--text); margin-bottom: var(--s-3); }

hr { border: none; border-top: 1px solid var(--border-faint); margin: var(--s-8) 0; }

/* ────────────────────────────────── admin · duration tiers ──── */
.tier-list { display: grid; gap: var(--s-2); }
.tier-row {
    display: flex;
    align-items: end;
    gap: var(--s-2);
    padding: var(--s-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    flex-wrap: wrap;
}
.tier-row > form { display: contents; margin: 0; gap: 0; }
.tier-row label { flex: 1 1 100px; min-width: 0; margin: 0; }
.tier-row label.tier-label { flex: 1.5 1 140px; }
.tier-row label.tier-price { flex: 1 1 100px; }
.tier-row label.tier-secs  { flex: 1 1 110px; }
.tier-row label.tier-show {
    flex: 0 0 auto;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    color: var(--text);
    padding: 9px 0;
}
.tier-row label.tier-show input { width: auto; padding: 0; }
.tier-row .tier-actions { display: flex; gap: var(--s-2); margin-left: auto; }
.tier-row .tier-actions form { display: inline-flex; margin: 0; }
.tier-row.tier-add { background: var(--inset); border-style: dashed; }
@media (max-width: 700px) {
    .tier-row { gap: var(--s-3); }
    .tier-row label, .tier-row label.tier-label,
    .tier-row label.tier-price, .tier-row label.tier-secs { flex: 1 1 calc(50% - var(--s-2)); }
    .tier-row label.tier-show { flex: 1 1 100%; }
    .tier-row .tier-actions { width: 100%; justify-content: stretch; }
    .tier-row .tier-actions .btn, .tier-row .tier-actions button { flex: 1; }
}

.field-group {
    display: grid;
    gap: var(--s-2);
    margin-bottom: var(--s-4);
}
.field-group .field-help { color: var(--text-muted); font-size: var(--fs-sm); margin: 0; }

.image-uploader {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: var(--s-5);
    align-items: start;
}
.image-uploader .image-current {
    position: relative;
    aspect-ratio: 16/10;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    overflow: hidden;
    background: var(--inset);
}
.image-uploader .image-current img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.image-uploader .image-current.is-empty {
    display: grid;
    place-items: center;
    border-style: dashed;
    color: var(--text-faint);
    font-size: var(--fs-sm);
}
@media (max-width: 700px) {
    .image-uploader { grid-template-columns: 1fr; }
}

.thumb {
    width: 48px; height: 32px;
    border-radius: var(--radius-sm);
    object-fit: cover;
    background: var(--surface-3);
    flex-shrink: 0;
}
.thumb-fallback {
    width: 48px; height: 32px;
    border-radius: var(--radius-sm);
    background: var(--surface-3);
    display: grid;
    place-items: center;
    color: var(--text-faint);
    font-weight: 600;
    font-size: var(--fs-sm);
    flex-shrink: 0;
}

/* ────────────────────────────────────────────────── HERO ──── */
/* Storefront hero — adopts the FOCUS / Sigil reskin: massive
   left-aligned headline, accent-coloured typed phrase, right-side
   meta panel with uptime/activations/discord stats. */
.storefront-hero {
    position: relative;
    padding: var(--s-10) 0 var(--s-9);
    text-align: left;
    max-width: var(--container);
    margin: 0 auto;
}
.storefront-hero .hero-eyebrow {
    /* Eyebrow uses the global .eyebrow primitive (with accent dot
       + glow). Override the dot styling only if pre-existing
       templates carry .hero-eyebrow specifically — they still
       work because we keep the inner .dot element styled. */
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--text-muted);
    margin-bottom: var(--s-5);
}
.storefront-hero .hero-eyebrow .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 10px var(--accent);
}
.storefront-hero h1 {
    font-size: clamp(54px, 8vw, 96px);
    line-height: 0.95;
    letter-spacing: -0.04em;
    font-weight: 600;
    margin: 0 0 var(--s-5);
    color: var(--text);
}
.hero-typed {
    display: inline-block;
    color: var(--accent);
}
.hero-caret {
    display: inline-block;
    width: 4px;
    height: 0.85em;
    margin-left: 6px;
    background: var(--accent);
    vertical-align: -0.05em;
    animation: hero-caret-blink 1s steps(2) infinite;
}
@keyframes hero-caret-blink { 50% { opacity: 0; } }
.storefront-hero p.lead {
    margin: 0 0 var(--s-7);
    color: var(--text-dim);
    font-size: var(--fs-lg);
    max-width: 620px;
}
.hero-cta-row {
    display: inline-flex;
    gap: var(--s-3);
    flex-wrap: wrap;
    align-items: center;
}
/* Right-side stats panel. Lives absolutely positioned on desktop;
   hidden on mobile to keep the hero readable. */
.hero-meta {
    position: absolute;
    top: var(--s-10);
    right: 0;
    display: grid;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--text-muted);
    text-align: right;
}
.hero-meta .k {
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}
.hero-meta .v { color: var(--text-dim); }
@media (max-width: 880px) {
    .hero-meta { display: none; }
    .storefront-hero h1 { font-size: 48px; }
}
.hero-browse {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    text-decoration: none;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    padding: 8px 16px;
    transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.hero-browse:hover {
    color: var(--text);
    border-color: var(--border-strong);
    background: var(--surface);
    text-decoration: none;
}
.hero-browse span { transition: transform var(--t-base) var(--ease); }
.hero-browse:hover span { transform: translateY(2px); }

/* ─────────────────────────────────── live audit strip ──── */
/* Decorative artifact under the hero — the system's audit log, surfaced
 * as a trust signal. Static server-rendered content; entries fade in
 * with staggered nth-child delays. */
.live-strip {
    margin: var(--s-10) auto 0;
    max-width: 920px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--inset);
    overflow: hidden;
    text-align: left;
}
.live-strip .ls-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-faint);
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.14em;
}
.live-strip .ls-head .right {
    display: flex;
    align-items: center;
    gap: 8px;
    text-transform: none;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}
.live-strip .ls-head .right .pulse {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--ok);
    animation: pulse 2s infinite;
}
@keyframes pulse {
    0%   { box-shadow: 0 0 0 0 rgba(95, 207, 134, 0.6); }
    70%  { box-shadow: 0 0 0 10px rgba(95, 207, 134, 0); }
    100% { box-shadow: 0 0 0 0 rgba(95, 207, 134, 0); }
}
.live-strip ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
}
.live-strip li {
    display: grid;
    grid-template-columns: 90px 1fr 1fr 14px;
    gap: 16px;
    padding: 9px 14px;
    border-bottom: 1px solid var(--border-faint);
    align-items: center;
    color: var(--text-muted);
    animation: ls-fade-in var(--t-slow) var(--ease) both;
}
.live-strip li:nth-child(1) { animation-delay: 0ms; }
.live-strip li:nth-child(2) { animation-delay: 80ms; }
.live-strip li:nth-child(3) { animation-delay: 160ms; }
.live-strip li:nth-child(4) { animation-delay: 240ms; }
.live-strip li:nth-child(5) { animation-delay: 320ms; }
.live-strip li:nth-child(6) { animation-delay: 400ms; }
.live-strip li:last-child { border-bottom: 0; }
.live-strip li .ts { color: var(--text-faint); font-size: 11px; }
.live-strip li .ev { color: var(--text); }
.live-strip li .meta { color: var(--text-muted); font-size: 11px; text-align: right; }
.live-strip li .risk { width: 6px; height: 6px; border-radius: 50%; background: var(--text-faint); }
.live-strip li.ok .risk   { background: var(--ok);     box-shadow: 0 0 0 3px var(--ok-tint); }
.live-strip li.warn .risk { background: var(--warn);   box-shadow: 0 0 0 3px var(--warn-tint); }
.live-strip li.bad .risk  { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.live-strip li.bad        { background: rgba(239, 58, 58, 0.03); }
@keyframes ls-fade-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ────────────────────────────────────────── PARTNER STRIP ──── */
/* Sits between the storefront hero and the product grid. A single
   linkable card that reads as an "endorsed-by" signal, NOT a CTA —
   accent border + subtle background so it doesn't compete with the
   Browse-products button above. */
/* ─────────────────────────────────── Discord callout ────────
   Big section above the footer on the storefront landing. Three-
   column grid: art / body / CTA. Discord-blue radial glow on the
   left, accent glow on the right. Stacks on mobile. */
.discord-callout {
    margin-top: var(--s-10);
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: var(--s-7);
    align-items: center;
    padding: var(--s-7) var(--s-8);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    position: relative;
    overflow: hidden;
}
.discord-callout::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse 380px 220px at 8% 50%,
            oklch(0.55 0.18 270 / 0.18), transparent 70%),
        radial-gradient(ellipse 280px 180px at 100% 100%,
            var(--accent-soft), transparent 70%);
    pointer-events: none;
}
.dc-art {
    position: relative;
    width: 100px;
    height: 100px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-lg);
    background: oklch(0.55 0.18 270 / 0.12);
    border: 1px solid oklch(0.55 0.18 270 / 0.3);
    color: oklch(0.78 0.16 270);
}
.dc-body { position: relative; max-width: 580px; }
.dc-body h2 {
    font-size: 28px;
    margin: 8px 0;
    letter-spacing: -0.02em;
}
.dc-body p { color: var(--text-dim); font-size: var(--fs-md); }
.dc-cta {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 10px;
}
.dc-btn {
    background: oklch(0.55 0.18 270);
    color: white;
    border: 1px solid oklch(0.45 0.18 270);
}
.dc-btn:hover {
    background: oklch(0.60 0.18 270);
    border-color: oklch(0.50 0.18 270);
    color: white;
    filter: brightness(1.05);
}
.dc-meta {
    font-size: var(--fs-xs);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.dc-meta::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 8px var(--accent);
}
@media (max-width: 880px) {
    .discord-callout {
        grid-template-columns: 1fr;
        gap: var(--s-4);
        padding: var(--s-6);
    }
    .dc-cta { align-items: flex-start; }
}

.partner-strip {
    max-width: 720px;
    margin: 0 auto var(--s-10);
    padding: 0 var(--s-4);
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s-3);
}
.partner-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--text-muted);
}
.partner-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-tint);
}
.partner-card {
    display: inline-flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-3) var(--s-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text);
    text-decoration: none;
    transition: transform var(--t-base) var(--ease),
                border-color var(--t-base) var(--ease),
                box-shadow var(--t-base) var(--ease);
    min-width: 260px;
    max-width: 100%;
}
.partner-card:hover {
    transform: translateY(var(--lift-2, -2px));
    border-color: var(--border-strong);
    box-shadow: var(--shadow-card-hover, 0 8px 24px -12px rgba(0, 0, 0, 0.6));
    color: var(--text);
    text-decoration: none;
}
.partner-mark {
    color: var(--text-muted);
    display: inline-flex;
    transition: color var(--t-base) var(--ease);
}
.partner-card:hover .partner-mark { color: var(--accent); }
.partner-text {
    display: flex;
    flex-direction: column;
    text-align: left;
    line-height: 1.25;
    min-width: 0;
}
.partner-name {
    font-weight: 600;
    font-size: var(--fs-md);
    letter-spacing: -0.01em;
}
.partner-tag {
    font-family: var(--font-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}
.partner-arrow {
    margin-left: auto;
    color: var(--text-faint);
    font-family: var(--font-mono);
    transition: transform var(--t-base) var(--ease), color var(--t-base) var(--ease);
}
.partner-card:hover .partner-arrow {
    color: var(--accent);
    transform: translateX(3px);
}
@media (max-width: 600px) {
    .partner-card { padding: var(--s-3); gap: var(--s-2); min-width: 0; width: 100%; }
    .partner-tag { display: none; }
}

/* ────────────────────────────────────────── PRODUCT GRID ──── */
.product-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: var(--s-4);
    margin-top: var(--s-6);
    max-width: var(--container);
    margin-left: auto;
    margin-right: auto;
    min-width: 0;
}
.product-grid[data-product-count="1"] {
    grid-template-columns: minmax(0, 460px);
    justify-content: center;
}
.product-grid[data-product-count="1"] .product-name { font-size: var(--fs-lg); }
.product-grid[data-product-count="1"] .price-display { font-size: clamp(var(--fs-xl), 3.5vw, 32px); }

.product-card {
    position: relative;
    background: var(--grad-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition: transform var(--t-base) var(--ease),
                border-color var(--t-base) var(--ease),
                box-shadow var(--t-base) var(--ease);
    /* Storefront cards are now <a href="/product/{slug}"> so the whole
       card area is clickable. Strip the default link styling so the
       inner content keeps the same visual treatment as before. */
    text-decoration: none;
    color: inherit;
    box-shadow: var(--shadow-card);
    /* Subtle accent-glow border line — drawn via an inset shadow
       layered over the regular border. At rest it's almost
       invisible; the hover state ramps it up so the card feels like
       it's emitting a soft accent edge. */
    --product-card-edge: 0 0 0 1px transparent;
    box-shadow: var(--product-card-edge), var(--shadow-card);
}
.product-card::after {
    /* Inner top-light line — narrow, accent-tinted at low opacity.
       Reads as a "lit edge" — premium product-card detail. */
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.06) 0%,
        transparent 12%,
        transparent 100%
    );
    mix-blend-mode: screen;
    opacity: 0.7;
    transition: opacity var(--t-base) var(--ease);
}
.product-card:hover {
    transform: translateY(var(--lift-3, -3px));
    border-color: var(--border-strong);
    --product-card-edge: 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent);
    box-shadow: var(--product-card-edge), var(--shadow-card-hover);
    text-decoration: none;
    color: inherit;
}
.product-card:hover::after { opacity: 1; }
.product-card:focus-visible {
    outline: none;
    box-shadow: var(--ring-focus, 0 0 0 3px var(--accent-tint));
}
.product-image {
    position: relative;
    aspect-ratio: 16/10;
    background:
        radial-gradient(120% 100% at 0% 0%, var(--accent-tint) 0%, transparent 50%),
        repeating-linear-gradient(135deg, rgba(255,255,255,0.015) 0 2px, transparent 2px 6px),
        linear-gradient(135deg, var(--surface-3) 0%, var(--surface-2) 60%, var(--inset) 100%);
    overflow: hidden;
    display: grid;
    place-items: center;
}
.product-image img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 1;
    transition: transform var(--t-base) var(--ease);
}
.product-card:hover .product-image img { transform: scale(1.02); }
.product-image .product-image-fallback {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 56px;
    line-height: 1;
    color: var(--border-strong);
    letter-spacing: -0.04em;
    text-transform: uppercase;
    z-index: 0;
    pointer-events: none;
}
.product-image-chip {
    position: absolute;
    top: var(--s-2); left: var(--s-2);
    z-index: 2;
    padding: 3px 9px;
    border-radius: var(--radius-full);
    background: rgba(10, 10, 12, 0.7);
    backdrop-filter: blur(6px) saturate(140%);
    -webkit-backdrop-filter: blur(6px) saturate(140%);
    border: 1px solid var(--border-strong);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.product-image-corner {
    position: absolute;
    top: var(--s-2); right: var(--s-2);
    z-index: 2;
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--text-muted);
    text-align: right;
    line-height: 1.3;
    letter-spacing: 0.04em;
}

.product-body {
    padding: 14px 16px 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 1;
}
.product-name {
    font-size: var(--fs-sm);
    font-weight: 600;
    margin: 0;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.product-tagline {
    color: var(--text-muted);
    font-size: 12px;
    margin: 0;
    min-height: 1.2em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.product-from {
    margin: 0;
    font-size: var(--fs-xs);
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.product-from strong {
    color: var(--text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    text-transform: none;
    letter-spacing: 0;
}

.duration-toggle {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    background: var(--inset);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 2px;
    gap: 2px;
    margin-top: 4px;
}
.duration-toggle button {
    appearance: none;
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-muted);
    padding: 6px 4px;
    border-radius: var(--radius-sm);
    font-size: 11px;
    font-weight: 500;
    cursor: pointer;
    font-family: var(--font-mono);
    letter-spacing: 0.02em;
    transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
    white-space: nowrap;
}
.duration-toggle button:hover { color: var(--text); background: var(--surface-2); }
.duration-toggle button[aria-pressed="true"] {
    background: var(--accent);
    color: var(--text-on-accent);
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent), 0 4px 12px -4px var(--accent-glow);
}
.duration-toggle button:focus-visible {
    outline: none;
    box-shadow: var(--ring-focus);
}

.price-display {
    font-size: var(--fs-xl);
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    line-height: 1;
    padding-top: 10px;
    border-top: 1px solid var(--border-faint);
}

.product-purchase {
    width: 100%;
    margin-top: auto;
    padding: 9px 12px;
    font-size: var(--fs-xs);
    font-weight: 600;
    gap: 6px;
}
.product-purchase .purchase-arrow {
    display: inline-block;
    transition: transform var(--t-base) var(--ease);
}
.product-purchase:hover .purchase-arrow { transform: translateX(3px); }

/* ────────────────────────────────────────── license rows ──── */
/* New dashboard format: status dot, product+key, HWID+resets, expiry bar, actions.
 * Uses CSS calc on --days for the time-remaining bar so the Go template
 * doesn't need a percent helper — pass DaysToExpiry directly as --days. */
.license-list {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    overflow: hidden;
}
.license-row {
    display: grid;
    grid-template-columns: 14px 1.4fr 1fr 1.1fr auto;
    align-items: center;
    gap: 18px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border-faint);
    transition: background var(--t-fast) var(--ease);
    cursor: pointer;
    position: relative;
}
.license-row:last-child { border-bottom: none; }
.license-row:hover { background: var(--surface-2); }
.license-row:focus-visible {
    outline: none;
    background: var(--surface-2);
    box-shadow: inset 2px 0 0 var(--accent);
}

.license-row .lr-status {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--text-faint);
}
.license-row.is-active .lr-status {
    background: var(--ok);
    box-shadow: 0 0 0 3px var(--ok-tint);
}
.license-row.is-paused .lr-status   { background: var(--warn);   box-shadow: 0 0 0 3px var(--warn-tint); }
.license-row.is-revoked .lr-status,
.license-row.is-expired .lr-status  { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }

.license-row .lr-main {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}
.license-row .lr-product { font-weight: 500; color: var(--text); font-size: var(--fs-sm); }
.license-row .lr-key {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-muted);
    letter-spacing: 0.02em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.license-row .lr-hwid {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.5;
}
.license-row .lr-hwid .hwid-label { color: var(--text-faint); }
.license-row .lr-hwid .hwid-val   { color: var(--text); }
.license-row .lr-hwid .hwid-val.faint { color: var(--text-faint); }
.license-row .lr-hwid .hwid-resets {
    display: block;
    color: var(--text-faint);
    font-size: 10px;
    margin-top: 2px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.license-row .lr-expiry { display: flex; flex-direction: column; gap: 5px; }
.license-row .lr-expiry .date {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text);
}
.license-row .lr-expiry .bar {
    height: 4px;
    border-radius: 2px;
    background: var(--surface-3);
    overflow: hidden;
}
.license-row .lr-expiry .bar > span {
    display: block;
    height: 100%;
    /* --days set inline by template (DaysToExpiry). Width caps at 100% at 30 days. */
    width: calc(min(100%, max(4%, var(--days, 30) * 100% / 30)));
    background: linear-gradient(90deg, var(--ok), #7dd49a);
    border-radius: inherit;
}
.license-row.is-expiring .lr-expiry .bar > span,
.license-row.expiring .lr-expiry .bar > span {
    background: linear-gradient(90deg, var(--warn), #f0c481);
}
.license-row.is-expired .lr-expiry .bar > span {
    width: 100%;
    background: linear-gradient(90deg, var(--accent), var(--accent-hover));
}
.license-row .lr-expiry .remaining {
    font-size: 10px;
    font-family: var(--font-mono);
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.license-row.is-expiring .lr-expiry .remaining { color: var(--warn); }
.license-row.is-expired  .lr-expiry .remaining { color: var(--accent); }

.license-row .lr-actions {
    display: flex;
    gap: 6px;
    align-items: center;
}

/* Redeem-key card on the dashboard. */
.redeem-card {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    padding: var(--s-6);
    margin-bottom: var(--s-6);
    transition: border-color var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.redeem-card:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-ring);
}
.redeem-card .redeem-hint {
    display: flex;
    justify-content: space-between;
    margin-top: 12px;
    font-size: 10px;
    color: var(--text-faint);
    font-family: var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* ────────────────────────────────────────────── docs grid ──── */
.docs-intro {
    max-width: 680px;
    margin-bottom: var(--s-10);
}
.docs-intro h1 {
    font-size: var(--fs-3xl);
    letter-spacing: -0.03em;
    margin: 12px 0 12px;
}
.docs-intro p { color: var(--text-muted); font-size: var(--fs-md); }

.docs-toc {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: var(--s-8);
}
.docs-toc a.chip {
    padding: 6px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    font-size: var(--fs-xs);
    color: var(--text-muted);
    text-decoration: none;
    transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.docs-toc a.chip:hover { color: var(--text); border-color: var(--border-strong); text-decoration: none; }
.docs-toc a.chip.active { color: var(--text); background: var(--surface-2); border-color: var(--border-strong); }

.docs-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--s-4);
}
.doc-card {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    padding: var(--s-6);
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    transition: border-color var(--t-base) var(--ease), background var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.doc-card:hover {
    border-color: var(--border-strong);
    background: var(--surface-2);
    transform: translateY(var(--lift-1));
}
.doc-card .doc-num {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--text-faint);
    letter-spacing: 0.16em;
    text-transform: uppercase;
}
.doc-card h3 {
    font-size: var(--fs-md);
    margin: 0;
}
.doc-card p {
    color: var(--text-muted);
    font-size: var(--fs-sm);
    margin: 0;
}
.doc-card .doc-link {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--accent);
    margin-top: auto;
    padding-top: 8px;
    text-decoration: none;
}
.doc-card .doc-link:hover { text-decoration: underline; }

/* ────────────────────────────────── product detail page ──── */
/* /product/{slug} layout. Desktop: two columns — media + setup steps
   on the left, name + description + features + purchase CTA on the
   right. The grid is intentionally asymmetric (5fr : 6fr) so the
   content column has a bit more room than the media column, keeping
   the image from feeling dominant. The media box itself is also
   capped at 520px wide and aligned to the start of the left column.
   Mobile: single column where the `order` property re-shuffles
   children into the spec'd stack:
     media → setup → header → description → features → purchase. */

.product-breadcrumbs {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    font-size: var(--fs-sm);
    color: var(--text-muted);
    margin: 0 auto var(--s-4);
    max-width: var(--container);
}
.product-breadcrumbs a { color: var(--text-muted); text-decoration: none; }
.product-breadcrumbs a:hover { color: var(--text); }

.product-detail {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--s-8);
    max-width: var(--container);
    margin: var(--s-2) auto var(--s-12);
    align-items: start;
}

.product-detail-left,
.product-detail-right {
    display: flex;
    flex-direction: column;
    gap: var(--s-5);
    min-width: 0;
}

/* Media box — locked aspect, capped max-width so a 4K hero shot can't
   eat the whole left column. object-fit: contain so admin uploads of
   any aspect ratio display without cropping; the gradient panel sits
   behind to fill the box. */
.product-detail-media {
    position: relative;
    width: 100%;
    max-width: 520px;
    aspect-ratio: 16 / 10;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
    background:
        radial-gradient(120% 100% at 0% 0%, var(--accent-tint) 0%, transparent 50%),
        repeating-linear-gradient(135deg, rgba(255,255,255,0.015) 0 2px, transparent 2px 6px),
        linear-gradient(135deg, var(--surface-3) 0%, var(--surface-2) 60%, var(--inset) 100%);
    display: grid;
    place-items: center;
}
.product-detail-media img,
.product-detail-media video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
    z-index: 1;
}
.product-detail-media video {
    /* Native controls only — no autoplay, no muted-by-default
       (controls let the customer initiate sound deliberately). */
    outline: none;
}
.product-detail-media .product-image-fallback {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 88px;
    line-height: 1;
    color: var(--border-strong);
    letter-spacing: -0.04em;
    text-transform: uppercase;
    z-index: 0;
    pointer-events: none;
}
.product-detail-media.no-image img,
.product-detail-media.no-image video { display: none; }

.product-detail-setup,
.product-detail-features {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--s-5);
}
.product-detail-setup h2,
.product-detail-features h2 {
    margin: 0 0 var(--s-3);
    font-size: var(--fs-md);
    font-weight: 600;
    letter-spacing: -0.01em;
}

.setup-steps {
    list-style: none;
    counter-reset: step;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
}
.setup-steps li {
    counter-increment: step;
    position: relative;
    /* Left padding has to clear the badge (12px from edge + 28px wide)
       plus a 12px buffer so the digit doesn't visually crash into the
       step text. The previous calc referenced --s-9 which doesn't exist
       in tokens.css; CSS silently dropped the declaration and the
       badge ended up sitting on top of the text. */
    padding: var(--s-3) var(--s-4) var(--s-3) calc(var(--s-3) + 28px + var(--s-3));
    border: 1px solid var(--border-faint);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text);
    font-size: var(--fs-sm);
    line-height: 1.55;
    min-height: calc(28px + var(--s-4));
    display: flex;
    align-items: center;
}
.setup-steps li::before {
    content: counter(step);
    position: absolute;
    top: 50%;
    left: var(--s-3);
    transform: translateY(-50%);
    width: 28px;
    height: 28px;
    display: grid;
    place-items: center;
    border-radius: var(--radius-full);
    background: var(--accent);
    color: var(--text-on-accent);
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 12px;
    box-shadow: 0 0 0 1px var(--accent), 0 4px 12px -4px var(--accent-glow);
}

.product-detail-header {
    display: flex;
    flex-direction: column;
    gap: var(--s-2);
}
.product-detail-name {
    margin: 0;
    font-size: var(--fs-2xl);
    line-height: 1.15;
    letter-spacing: -0.025em;
}
.product-detail-category {
    align-self: flex-start;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding: 4px 10px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-full);
    background: var(--inset);
}

.product-detail-description {
    color: var(--text);
}
.product-detail-description p {
    margin: 0 0 var(--s-3);
    line-height: 1.65;
    color: var(--text);
}
.product-detail-description p:last-child { margin-bottom: 0; }

/* Scoped to .product-detail-features so the login page's
   .auth-shell .feature-list (which uses a "→" pseudo-element and its
   own grid layout) isn't clobbered. The first cut of these rules used
   a bare `.feature-list` selector and the position:absolute ::before +
   padding-left bleed through into the auth page squeezed its left
   column down to one word per line. */
.product-detail-features .feature-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--s-2);
}
.product-detail-features .feature-list li {
    position: relative;
    padding: var(--s-2) 0 var(--s-2) calc(var(--s-6) + 2px);
    color: var(--text);
    font-size: var(--fs-sm);
    line-height: 1.5;
}
.product-detail-features .feature-list li::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 6px;
    transform: translateY(-50%);
    width: 8px;
    height: 8px;
    border-radius: 2px;
    background: var(--accent);
    box-shadow: 0 0 8px var(--accent-glow);
}

.product-detail-purchase {
    margin-top: auto;
    border: 1px solid var(--border);
    background: var(--surface);
    border-radius: var(--radius-md);
    padding: var(--s-5);
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
}
.product-detail-pricing {
    display: flex;
    align-items: baseline;
    gap: var(--s-2);
}
.product-detail-price {
    font-size: var(--fs-xl);
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.product-detail-cta {
    width: 100%;
    justify-content: center;
    gap: 8px;
}
.product-detail-cta .purchase-arrow {
    display: inline-block;
    transition: transform var(--t-base) var(--ease);
}
.product-detail-cta:hover .purchase-arrow { transform: translateX(3px); }
.product-detail-cta.disabled {
    opacity: 0.55;
    pointer-events: none;
}
.product-detail-help { margin: 0; font-size: var(--fs-xs); }

/* ──────────────────────────────────── compatibility warning ──── */
/* Per-product panel rendered above the purchase block when the
   admin enables it. Amber palette = informational caution; NOT
   the accent red, which is reserved for errors / destructive
   actions elsewhere in the site. */
.product-warning {
    border: 1px solid rgba(232, 164, 74, 0.35);
    background: rgba(232, 164, 74, 0.07);
    border-radius: var(--radius-md);
    padding: var(--s-4) var(--s-5);
    margin: var(--s-3) 0;
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
}
.product-warning__head {
    display: flex;
    align-items: center;
    gap: var(--s-2);
}
.product-warning__icon {
    font-size: var(--fs-lg);
    color: var(--warn);
    line-height: 1;
}
.product-warning__title {
    margin: 0;
    font-size: var(--fs-md);
    font-weight: 600;
    color: var(--text);
}
.product-warning__body {
    margin: 0;
    color: var(--text);
    line-height: 1.55;
    font-size: var(--fs-sm);
}
.product-warning__supported {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    font-size: var(--fs-sm);
}
.product-warning__supported-label {
    font-family: var(--font-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}
.product-warning__chips {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.product-warning__chips li {
    padding: 3px 9px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-full);
    background: var(--surface);
    font-size: var(--fs-xs);
    font-family: var(--font-mono);
    color: var(--text);
}
.product-warning__check {
    margin: 0;
    font-size: var(--fs-sm);
    color: var(--text-muted);
}
.link-btn {
    appearance: none;
    background: none;
    border: 0;
    padding: 0;
    color: var(--accent);
    font: inherit;
    cursor: pointer;
    text-decoration: underline;
    text-decoration-color: var(--border-strong);
}
.link-btn:hover { text-decoration-color: var(--accent); }

/* ──────────────────────────────────── image slider ──── */
/* Used by:
     - product warning gallery (.image-slider--warning)
     - /docs/check-windows-version standalone page
     - shared windows-guide <dialog> (.image-slider--modal)
   CSS scroll-snap is the layout primitive; JS in app.js only
   coordinates dot state + button clicks. */
.image-slider {
    position: relative;
    width: 100%;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    overflow: hidden;
}
.image-slider__track {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
}
.image-slider__track::-webkit-scrollbar { display: none; }
.image-slider__slide {
    flex: 0 0 100%;
    scroll-snap-align: start;
    padding: var(--s-4);
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    min-width: 0;
}
.image-slider__step-num {
    font-family: var(--font-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}
.image-slider__image-frame {
    border: 1px solid var(--border-faint);
    background: var(--inset);
    border-radius: var(--radius-sm);
    overflow: hidden;
    display: grid;
    place-items: center;
    max-height: 320px;
}
.image-slider__image-frame img {
    max-width: 100%;
    max-height: 320px;
    object-fit: contain;
    display: block;
}
.image-slider__text {
    margin: 0;
    color: var(--text);
    line-height: 1.55;
    font-size: var(--fs-sm);
}
.image-slider__controls {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-2) var(--s-3);
    border-top: 1px solid var(--border-faint);
    background: var(--surface-2);
}
.image-slider__prev,
.image-slider__next {
    appearance: none;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    width: 32px;
    height: 32px;
    border-radius: var(--radius-full);
    cursor: pointer;
    font-family: var(--font-mono);
}
.image-slider__prev:disabled,
.image-slider__next:disabled { opacity: 0.4; cursor: not-allowed; }
.image-slider__dots {
    display: flex;
    gap: 6px;
    margin: 0 auto;
}
.image-slider__dot {
    appearance: none;
    background: var(--border);
    border: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    cursor: pointer;
    transition: background var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.image-slider__dot[aria-current="true"] {
    background: var(--accent);
    transform: scale(1.3);
}

/* ──────────────────────────────────── windows guide modal ──── */
.windows-guide-modal {
    border: 1px solid var(--border);
    background: var(--bg);
    color: var(--text);
    border-radius: var(--radius-md);
    padding: 0;
    max-width: 640px;
    width: calc(100% - var(--s-6));
    box-shadow: 0 12px 36px -12px rgba(0, 0, 0, 0.55);
}
.windows-guide-modal::backdrop { background: rgba(0, 0, 0, 0.55); }
.windows-guide-modal__head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--s-4) var(--s-5);
    border-bottom: 1px solid var(--border-faint);
}
.windows-guide-modal__head h2 {
    margin: 0;
    font-size: var(--fs-md);
}
.windows-guide-modal__head form { margin: 0; }
.windows-guide-modal__intro,
.windows-guide-modal__footer {
    padding: var(--s-3) var(--s-5);
    margin: 0;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    line-height: 1.55;
}
.windows-guide-modal__footer { border-top: 1px solid var(--border-faint); }
.windows-guide-modal .image-slider {
    border-left: 0;
    border-right: 0;
    border-radius: 0;
}

/* ──────────────────────────────────── admin: warning thumbs ──── */
.warning-image-thumbs {
    list-style: none;
    padding: 0;
    margin: var(--s-3) 0 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: var(--s-3);
}
.warning-image-thumbs li {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.warning-image-thumbs li img {
    width: 100%;
    aspect-ratio: 16/10;
    object-fit: cover;
    background: var(--inset);
}
.warning-image-thumbs__row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-2);
    padding: 6px 8px;
    border-top: 1px solid var(--border-faint);
    background: var(--surface-2);
}
.warning-image-thumbs__buttons {
    display: inline-flex;
    gap: 4px;
}
.warning-image-thumbs__buttons form { margin: 0; }
.warning-image-thumbs__buttons button { padding: 2px 8px; font-size: 11px; }

.winguide-thumb {
    width: 120px;
    height: 80px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-faint);
    background: var(--inset);
}

.product-notfound {
    max-width: 540px;
    margin: var(--s-12) auto;
    text-align: center;
    padding: 0 var(--s-4);
}

/* Crypto checkout form on the product detail page. Two stacked
   <select>s (duration + coin) plus a submit. Lives inside the same
   .product-detail-purchase box so the visual weight matches the
   surrounding panel. */
.checkout-form {
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
}
.checkout-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.checkout-label {
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}
.checkout-form select {
    width: 100%;
    font-family: var(--font-mono);
}
.checkout-form .product-detail-cta {
    margin-top: var(--s-2);
}

/* Invoice page — single column, payment instructions front-and-centre. */
.invoice-page {
    max-width: 720px;
    margin: 0 auto var(--s-12);
}
.invoice-head h1 {
    margin: 0 0 var(--s-2);
    font-size: var(--fs-xl);
    letter-spacing: -0.02em;
}
.invoice-ref {
    font-family: var(--font-mono);
    color: var(--text-muted);
    font-size: var(--fs-md);
    font-weight: 500;
}
.invoice-status {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 5px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    background: var(--surface);
    margin: var(--s-3) 0 var(--s-5);
    font-family: var(--font-mono);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}
.invoice-status .status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-muted);
}
/* Status-tinted dots: pending/confirming are warm-amber, paid is
   green, terminal-failure is red. Keeps the colour-coded glance
   readable without leaning on emoji. */
.invoice-status[data-invoice-status="pending"] .status-dot,
.invoice-status[data-invoice-status="confirming"] .status-dot {
    background: #f0a500;
    box-shadow: 0 0 0 3px rgba(240, 165, 0, 0.18);
}
.invoice-status[data-invoice-status="confirmed"] .status-dot,
.invoice-status[data-invoice-status="finished"] .status-dot {
    background: var(--ok);
    box-shadow: 0 0 0 3px var(--ok-tint);
}
.invoice-status[data-invoice-status="expired"] .status-dot,
.invoice-status[data-invoice-status="failed"] .status-dot,
.invoice-status[data-invoice-status="refunded"] .status-dot {
    background: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-tint);
}
.invoice-payment-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--s-6);
    display: flex;
    flex-direction: column;
    gap: var(--s-4);
}
.invoice-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s-4);
    flex-wrap: wrap;
}
.invoice-label {
    font-family: var(--font-mono);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}
.invoice-value {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.invoice-address {
    font-family: var(--font-mono);
    font-size: 12px;
    word-break: break-all;
}
.invoice-coin,
.invoice-network {
    font-family: var(--font-mono);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    padding: 2px 8px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-full);
}
.invoice-warning {
    margin: 0;
    padding: var(--s-3);
    border: 1px solid rgba(240, 165, 0, 0.3);
    background: rgba(240, 165, 0, 0.08);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: var(--fs-sm);
    line-height: 1.55;
}
.invoice-payment-card--paid { border-color: var(--ok); }
.invoice-payment-card--expired { border-color: var(--border-strong); }
.invoice-payment-card--problem { border-color: var(--accent); }
.invoice-detail-foot {
    margin-top: var(--s-6);
    font-size: var(--fs-sm);
    color: var(--text-muted);
}
.invoice-meta {
    display: grid;
    grid-template-columns: 180px 1fr;
    row-gap: var(--s-2);
    margin-top: var(--s-3);
}
.invoice-meta dt {
    color: var(--text-muted);
}
.invoice-meta dd {
    margin: 0;
    word-break: break-all;
}

/* /product/{slug} when the product is flagged coming_soon=true.
   Layers on top of .storefront-hero so the eyebrow / h1 / caret / cta
   reuse the existing hero treatment. The typed phrase gets a slight
   accent glow to differentiate from the static "Focus" wordmark on the
   real hero. */
.storefront-hero.coming-soon {
    padding-top: var(--s-20);
    padding-bottom: var(--s-16);
}
.coming-soon-headline {
    font-family: var(--font-mono);
    font-size: var(--fs-3xl);
    letter-spacing: -0.025em;
}
.coming-soon-typed {
    color: var(--accent);
    text-shadow: 0 0 36px var(--accent-glow);
}
.coming-soon-lead {
    max-width: 520px;
}
@media (max-width: 700px) {
    .coming-soon-headline { font-size: var(--fs-2xl); }
}

/* Support dashboard — license rows + per-row action grid. Lives at
   /support, only visible to role='support'. */
.support-search { display: flex; flex-direction: column; gap: var(--s-3); }
.support-search input[type="text"] {
    font-family: var(--font-mono);
    font-size: var(--fs-md);
    max-width: 320px;
}
.support-row {
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    margin-bottom: var(--s-3);
}
.support-row-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s-2);
}
.support-row-meta {
    display: grid;
    grid-template-columns: 120px 1fr;
    row-gap: 6px;
    column-gap: var(--s-3);
    margin: 0;
    font-size: var(--fs-sm);
}
.support-row-meta dt { color: var(--text-muted); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; }
.support-row-meta dd { margin: 0; }
.support-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    align-items: center;
    padding-top: var(--s-3);
    border-top: 1px solid var(--border-faint);
}
.support-extend-form {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
}
.support-extend-form .inline-input {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.support-extend-form .inline-input input {
    width: 70px;
    font-family: var(--font-mono);
    text-align: right;
}

/* Reseller top-up form. Lives on /reseller above the keys section.
   Amount input + preset chips + coin select stack vertically; the
   preset row uses ghost-button styling so it reads as "shortcut"
   instead of "primary action". */
.topup-form { display: flex; flex-direction: column; gap: var(--s-3); }
.topup-form input[type="number"] {
    font-family: var(--font-mono);
    font-size: var(--fs-lg);
    width: 100%;
    max-width: 200px;
}
.topup-form select { font-family: var(--font-mono); }
.topup-presets {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-top: -8px;
}
.topup-presets button { font-family: var(--font-mono); }

/* Inline checkbox + label row used on the admin storefront edit form
   (video preview toggle). Keeps the checkbox snug to its label so it
   doesn't look like a standalone bullet. */
label.inline-check {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    margin: var(--s-2) 0;
    font-weight: 500;
}
label.inline-check input[type="checkbox"] { margin: 0; }
label.inline-check .hint { font-weight: 400; }

/* ─── admin storefront repeatable fields (setup steps, features) ─── */
.repeat-fieldset {
    border: 1px solid var(--border-faint);
    border-radius: var(--radius-sm);
    padding: var(--s-3) var(--s-4) var(--s-4);
    margin: var(--s-3) 0;
}
.repeat-fieldset legend {
    padding: 0 var(--s-2);
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--text);
}
.repeat-fieldset .repeat-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--s-2);
    margin-bottom: var(--s-2);
    align-items: center;
}
.repeat-fieldset .repeat-row input { margin: 0; }
.repeat-fieldset .repeat-actions { margin-top: var(--s-2); }

/* ──────────────────────────────── reduced motion + responsive ──── */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

@media (max-width: 900px) {
    /* Admin sidebar collapses above the main content area. The
       section-label list items disappear so we just get a
       horizontally-scrollable pill row of admin nav. The active
       state stays visible via the left-bar shadow on each link
       (kept by the .active rule, not the section-label which has
       no link inside). */
    main.with-sidebar { grid-template-columns: 1fr; gap: var(--s-4); }
    aside.sidebar {
        position: static;
        border-right: none;
        padding-right: 0;
        padding-bottom: var(--s-2);
        border-bottom: 1px solid var(--border);
    }
    aside.sidebar ul {
        display: flex;
        gap: 4px;
        overflow-x: auto;
        padding-bottom: var(--s-2);
        scroll-snap-type: x proximity;
    }
    aside.sidebar a { white-space: nowrap; scroll-snap-align: start; }
    aside.sidebar .sidebar-section-label { display: none; }

    /* Topnav tightens to a more mobile-appropriate padding + lets
       nav-links scroll horizontally instead of disappearing
       entirely (the previous rule hid navigation on every device
       under 900px which made the site unusable on phones). */
    header.app nav {
        gap: var(--s-3);
        padding: 12px 16px;
        flex-wrap: wrap;
    }
    header.app nav .nav-links {
        order: 99;
        flex-basis: 100%;
        overflow-x: auto;
        padding-bottom: 4px;
        scroll-snap-type: x proximity;
    }
    header.app nav .nav-links a { scroll-snap-align: start; flex-shrink: 0; }
    .live-strip li { grid-template-columns: 80px 1fr 14px; }
    .live-strip li .meta { display: none; }

    /* Admin pages were defaulting to 1280px main padding 32px which
       on phones leaves no room. Tighten across all main shells. */
    main { padding: var(--s-6) 16px var(--s-8); }
    .storefront-hero { padding: var(--s-6) 0 var(--s-7); }
}

@media (max-width: 700px) {
    main { padding: var(--s-5) var(--s-3) var(--s-8); }

    .storefront-hero { padding: var(--s-5) 0 var(--s-6); }
    .storefront-hero h1 { font-size: 44px; }
    .storefront-hero p.lead { font-size: var(--fs-md); }
    .hero-cta-row { flex-direction: column; align-items: stretch; }
    .hero-cta-row .btn { width: 100%; }

    .license-row {
        grid-template-columns: 14px 1fr auto;
        grid-template-rows: auto auto;
        row-gap: 10px;
    }
    .license-row .lr-status { grid-row: 1; }
    .license-row .lr-main { grid-column: 2; grid-row: 1; }
    .license-row .lr-hwid { grid-column: 1 / -1; grid-row: 2; }
    .license-row .lr-expiry { display: none; }
    .license-row .lr-actions { grid-column: 3; grid-row: 1; }

    /* Tables on phones go inside an overflow-x scroller wrapper —
       prevents them from breaking the page width. The table itself
       keeps its column layout intact; users get a touch swipe to
       see hidden columns. */
    .table-scroll, .card > table, main > table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    table, thead, tbody, th, td, tr { font-size: var(--fs-xs); }
    th, td { padding: 8px 10px; }
    td.actions { white-space: normal; }

    .recovery-codes { grid-template-columns: 1fr; }

    .product-grid { grid-template-columns: 1fr; gap: var(--s-4); }
    .price-display { font-size: var(--fs-xl); }

    /* Cards tighten their inner padding on phones — same content,
       less wasted edge space. */
    .card { padding: var(--s-4); }

    /* Footer 4-column grid → 2-column on phones. The brand column
       keeps its full width via grid-column: 1 / -1. */
    footer.app .footer-row {
        grid-template-columns: 1fr 1fr !important;
        gap: var(--s-4);
    }
    footer.app .footer-brand { grid-column: 1 / -1; }
    footer.app .footer-meta {
        flex-direction: column;
        gap: 4px;
        text-align: left;
    }

    /* Action bar wraps cleanly when buttons stack. */
    .action-bar { flex-wrap: wrap; gap: var(--s-2); }
    .action-bar .btn { flex: 1 1 auto; }

    /* Section heads stop trying to fit a long muted-stat span next to
       the H2 on narrow screens — let it wrap underneath. */
    .section-head { flex-wrap: wrap; gap: var(--s-2); }
}

/* Universal touch-target floor + mobile form polish — applies at every
   breakpoint, not just below 700px, so tablets in landscape behave too.
   Input height + button height ≥ 40px for thumb-friendly tapping. */
@media (max-width: 768px) {
    input, select, textarea {
        font-size: 16px;  /* prevents iOS Safari from zooming on focus */
        min-height: 42px;
    }
    button, .btn { min-height: 40px; }
    button.small, .btn.small { min-height: 32px; }
    /* Modal full-width on phones. The default 34rem max-width
       leaves a sliver of backdrop visible on small screens which
       reads as "I'm cut off" — go edge-to-edge instead. */
    dialog {
        max-width: 100%;
        width: calc(100% - var(--s-3));
        padding: var(--s-4);
    }
    /* Discord callout art tile shrinks on phones so the body has
       room to breathe under the icon. */
    .dc-art { width: 72px; height: 72px; }
    .dc-art svg { width: 60px; height: 60px; }
}

/* Product details stack: kicks in at a wider breakpoint than the rest
   of the mobile rules because the page has two heavy columns. Below
   900px the side-by-side layout cramps both content and media — we
   stack instead. Order rules re-shuffle the right-column children so
   the spec'd sequence comes out:
     media → setup → header → description → features → purchase. */
@media (max-width: 900px) {
    .product-detail {
        grid-template-columns: 1fr;
        gap: var(--s-5);
    }
    .product-detail-left,
    .product-detail-right {
        display: contents;
    }
    .product-detail-media       { order: 1; max-width: 100%; }
    [data-stack="setup"]        { order: 2; }
    [data-stack="header"]       { order: 3; }
    [data-stack="description"]  { order: 4; }
    [data-stack="features"]     { order: 5; }
    [data-stack="purchase"]     { order: 6; }

    .product-detail-name { font-size: var(--fs-xl); }
    .product-detail-media .product-image-fallback { font-size: 64px; }
}
