/* ==========================================================================
   SystemCraft core stylesheet
   Single source of truth for design tokens and site chrome (header, nav,
   footer, scrollbars, shared primitives). Page-specific styles live with
   their page; anything that appears on more than one page belongs here.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
    /* Neutral surfaces — near-black, no colour cast */
    --bg: #09090c;
    --bg-subtle: #0e0e13;
    --surface: #131319;
    --surface-2: #1a1a22;
    --surface-3: #22222c;

    /* Borders */
    --border: #23242f;
    --border-strong: #31323f;
    --border-accent: rgba(129, 140, 248, 0.35);

    /* Text — 3 steps is enough; more invites inconsistency */
    --text: #f1f2f5;
    --text-muted: #a2a6b2;
    --text-dim: #6d707c;

    /* Brand */
    --accent: #818cf8;
    --accent-hover: #a5adff;
    --accent-contrast: #ffffff;
    --accent-subtle: rgba(129, 140, 248, 0.12);
    --accent-subtle-hover: rgba(129, 140, 248, 0.18);

    /* Semantic */
    --success: #34d399;
    --warning: #fbbf24;
    --danger: #f87171;
    --info: #60a5fa;

    /* Difficulty (DSA + HLD) */
    --easy: #34d399;
    --medium: #fbbf24;
    --hard: #f87171;

    /* Elevation — restrained; depth comes from borders, not blur */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.45);
    --shadow-accent: 0 6px 20px rgba(129, 140, 248, 0.22);

    /* Radii */
    --r-xs: 5px;
    --r-sm: 7px;
    --r-md: 10px;
    --r-lg: 14px;
    --r-xl: 20px;
    --r-full: 999px;

    /* Type scale — fluid, tuned for long-form reading */
    --fs-xs: 0.75rem;
    --fs-sm: 0.8125rem;
    --fs-base: 0.9375rem;
    --fs-md: 1rem;
    --fs-lg: 1.125rem;
    --fs-xl: clamp(1.15rem, 0.9rem + 1.1vw, 1.4rem);
    --fs-2xl: clamp(1.4rem, 1rem + 1.9vw, 1.9rem);
    --fs-3xl: clamp(1.75rem, 1.1rem + 3.1vw, 2.9rem);
    /* Editorial display size — homepage hero only. Floors at the old --fs-3xl
       minimum so narrow phones are unaffected, and scales harder above that. */
    --fs-4xl: clamp(1.75rem, 1rem + 4.6vw, 4.1rem);

    /* Spacing */
    --sp-1: 0.25rem;
    --sp-2: 0.5rem;
    --sp-3: 0.75rem;
    --sp-4: 1rem;
    --sp-5: 1.5rem;
    --sp-6: 2rem;
    --sp-7: 3rem;
    --sp-8: 4rem;

    /* Layout */
    --measure: 1160px;
    --measure-narrow: 780px;
    --header-h: 56px;

    /* Motion */
    --ease: cubic-bezier(0.4, 0, 0.2, 1);
    --dur-fast: 0.15s;
    --dur: 0.22s;

    /* Fonts */
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    /* ---- Compatibility aliases (older inline CSS still references these) ---- */
    --bg-card: var(--surface);
    --card-bg: var(--surface);
    --bg-header: rgba(9, 9, 12, 0.72);
    /* --header-bg is only consumed by the auth popovers in auth-styles.html.
       They float over page content, so it must be opaque — the translucent
       value the sticky header uses makes text behind them show through. */
    --header-bg: #16161d;
    --code-bg: var(--bg-subtle);
    --accent-light: var(--accent-hover);
    --border-hover: var(--border-accent);
    --glow: var(--accent-subtle);
    --glass: rgba(255, 255, 255, 0.035);
    --glass-border: var(--border);
    --tag-bg: var(--accent-subtle);
    --tag-border: var(--border-accent);
    /* Judge/IDE panes need opaque fills — the app shell has no page background
       showing through, so translucent surfaces would stack visibly. */
    --panel: #101018;
    --panel-2: #171722;

    /* ---- Depth: frosted card surfaces + accent glows ----
       Cards are a translucent wash over the page's gradient mesh rather than a
       flat fill, so the mesh tints them subtly as it shifts across the page. */
    --card-glass: linear-gradient(180deg, rgba(255,255,255,0.075), rgba(255,255,255,0.025));
    --card-glass-hover: linear-gradient(180deg, rgba(255,255,255,0.115), rgba(255,255,255,0.045));
    --card-blur: 12px;
    /* Hairline highlight along a card's top edge — reads as a lit surface. */
    --card-sheen: linear-gradient(90deg, transparent, rgba(255,255,255,0.14), transparent);
    /* Accent glow, kept at 20-30% so it lifts a card without shouting. */
    --glow-accent: 0 8px 30px -6px rgba(129, 140, 248, 0.28);
    --glow-accent-strong: 0 14px 44px -8px rgba(129, 140, 248, 0.38);
    --ring-accent: 0 0 0 1px rgba(129, 140, 248, 0.28);
}

[data-theme="light"] {
    --bg: #ffffff;
    --bg-subtle: #f7f8fa;
    --surface: #ffffff;
    --surface-2: #f4f5f8;
    --surface-3: #eceef2;

    --border: #e3e5ea;
    --border-strong: #cfd2da;
    --border-accent: rgba(79, 70, 229, 0.35);

    --text: #0c0e14;
    --text-muted: #52586a;
    --text-dim: #7b8194;

    --accent: #4f46e5;
    --accent-hover: #4338ca;
    --accent-contrast: #ffffff;
    --accent-subtle: rgba(79, 70, 229, 0.07);
    --accent-subtle-hover: rgba(79, 70, 229, 0.12);

    --success: #059669;
    --warning: #b45309;
    --danger: #dc2626;
    --info: #2563eb;

    --easy: #059669;
    --medium: #b45309;
    --hard: #dc2626;

    --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.05);
    --shadow-md: 0 4px 12px rgba(16, 24, 40, 0.07);
    --shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.1);
    --shadow-accent: 0 6px 20px rgba(79, 70, 229, 0.18);

    --bg-header: rgba(255, 255, 255, 0.78);
    --header-bg: #ffffff;   /* opaque: see the dark-theme note above */
    --glass: rgba(255, 255, 255, 0.7);

    --panel: #ffffff;
    --panel-2: #f4f5f8;

    /* Light theme inverts the depth trick: a white wash is invisible on white,
       so cards sit slightly *above* the page as opaque white with a soft
       shadow, and the sheen darkens instead of lightening. */
    --card-glass: linear-gradient(180deg, #ffffff, #fcfcfe);
    --card-glass-hover: linear-gradient(180deg, #ffffff, #f7f8fc);
    --card-blur: 0px;
    --card-sheen: linear-gradient(90deg, transparent, rgba(79, 70, 229, 0.18), transparent);
    --glow-accent: 0 8px 28px -8px rgba(79, 70, 229, 0.20);
    --glow-accent-strong: 0 14px 40px -10px rgba(79, 70, 229, 0.28);
    --ring-accent: 0 0 0 1px rgba(79, 70, 229, 0.22);
}

/* --------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; padding: 0; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
    font-family: var(--font-sans);
    background: var(--bg);
    color: var(--text);
    font-size: var(--fs-base);
    line-height: 1.65;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-feature-settings: "cv11", "ss01";
    font-variant-numeric: tabular-nums;
}

img, svg, video { max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--r-xs);
}

::selection { background: var(--accent-subtle-hover); color: var(--text); }

/* Respect reduced-motion: kill transitions and entrance animations outright */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* Skip link — keyboard users shouldn't tab the whole nav on every page */
.skip-link {
    position: absolute;
    top: -100px;
    left: var(--sp-4);
    z-index: 1000;
    background: var(--accent);
    color: var(--accent-contrast);
    padding: var(--sp-2) var(--sp-4);
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    font-weight: 600;
    text-decoration: none;
    transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: var(--sp-3); }

/* --------------------------------------------------------------------------
   3. Ambient background
   A single soft wash anchored to the top of the page. Scrolls with content
   (not fixed) so it costs one paint instead of repainting every frame.
   -------------------------------------------------------------------------- */
/* Gradient mesh behind the top of the page. Three offset radial pools instead
   of one centred ellipse — the overlap is what reads as depth rather than as a
   flat wash. Fixed so it stays put while content scrolls over it. */
.bg-gradient {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 900px;
    background:
        radial-gradient(ellipse 55% 45% at 50% -6%, color-mix(in srgb, var(--accent) 38%, transparent), transparent 70%),
        radial-gradient(ellipse 42% 38% at 10% 2%,  color-mix(in srgb, #a78bfa 26%, transparent), transparent 68%),
        radial-gradient(ellipse 42% 40% at 90% 0%,  color-mix(in srgb, #38bdf8 20%, transparent), transparent 68%);
    /* Fade the mesh out at its lower edge so it never ends on a hard line. */
    -webkit-mask-image: linear-gradient(180deg, #000 40%, transparent);
    mask-image: linear-gradient(180deg, #000 40%, transparent);
    pointer-events: none;
    z-index: 0;
}
[data-theme="light"] .bg-gradient {
    background:
        radial-gradient(ellipse 55% 45% at 50% -6%, color-mix(in srgb, var(--accent) 15%, transparent), transparent 70%),
        radial-gradient(ellipse 42% 38% at 10% 2%,  color-mix(in srgb, #7c3aed 11%, transparent), transparent 68%),
        radial-gradient(ellipse 42% 40% at 90% 0%,  color-mix(in srgb, #0ea5e9 10%, transparent), transparent 68%);
}

/* --------------------------------------------------------------------------
   Frosted card surface — shared by every card-like element site-wide, so the
   depth treatment stays consistent instead of being re-tuned per page.
   -------------------------------------------------------------------------- */
.surface-card {
    position: relative;
    background: var(--card-glass);
    backdrop-filter: blur(var(--card-blur));
    -webkit-backdrop-filter: blur(var(--card-blur));
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-md);
    transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
                transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
/* Top-edge sheen. Inset by the radius so it doesn't overhang the rounded corners. */
.surface-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: var(--r-lg);
    right: var(--r-lg);
    height: 1px;
    background: var(--card-sheen);
    opacity: 0.7;
    pointer-events: none;
}
.surface-card:hover {
    background: var(--card-glass-hover);
    border-color: var(--border-accent);
    box-shadow: var(--shadow-lg), var(--glow-accent);
}

/* --------------------------------------------------------------------------
   Staggered card cascade
   Cards inside a revealed grid ripple in rather than appearing all at once.
   This hangs off the existing .reveal → .visible scroll machinery: while a
   section still carries .reveal its grid cards sit offset and transparent, and
   the moment the IntersectionObserver adds .visible they animate in, each one
   a beat behind the last. nth-child is scoped to the grid, so the count always
   restarts per grid rather than running across the whole section.

   Two safeguards come for free. If IntersectionObserver is unavailable the
   page script never adds .reveal, so cards render fully visible at rest — the
   rules below only bite once .reveal is present. And the global
   prefers-reduced-motion block above zeroes the transition-duration, so the
   offset collapses instantly with no motion. Delays are capped at the 6th
   child so a long grid never feels like it's loading in slow motion.

   Grids opted in (kept explicit rather than a blanket "grid > *" so tables,
   filter bars, and other row layouts inside a section are never caught):
   .paths, .popular (home) · .problems-grid (HLD/LLD) ·
   .pattern-grid, .start-grid, .lists-grid (DSA).
   -------------------------------------------------------------------------- */
.reveal .paths > *,
.reveal .popular > *,
.reveal .problems-grid > *,
.reveal .pattern-grid > *,
.reveal .start-grid > *,
.reveal .lists-grid > * {
    /* Hidden until the section flips to .visible. A keyframe animation — not a
       transition — drives the entrance so the cards' own transition property
       (which powers the hover lift) is left untouched and stays snappy. */
    opacity: 0;
}
.reveal.visible .paths > *,
.reveal.visible .popular > *,
.reveal.visible .problems-grid > *,
.reveal.visible .pattern-grid > *,
.reveal.visible .start-grid > *,
.reveal.visible .lists-grid > * {
    animation: card-rise var(--dur) var(--ease) both;
}
@keyframes card-rise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}
.reveal.visible .paths > :nth-child(1),
.reveal.visible .popular > :nth-child(1),
.reveal.visible .problems-grid > :nth-child(1),
.reveal.visible .pattern-grid > :nth-child(1),
.reveal.visible .start-grid > :nth-child(1),
.reveal.visible .lists-grid > :nth-child(1) { animation-delay: 0.04s; }
.reveal.visible .paths > :nth-child(2),
.reveal.visible .popular > :nth-child(2),
.reveal.visible .problems-grid > :nth-child(2),
.reveal.visible .pattern-grid > :nth-child(2),
.reveal.visible .start-grid > :nth-child(2),
.reveal.visible .lists-grid > :nth-child(2) { animation-delay: 0.10s; }
.reveal.visible .paths > :nth-child(3),
.reveal.visible .popular > :nth-child(3),
.reveal.visible .problems-grid > :nth-child(3),
.reveal.visible .pattern-grid > :nth-child(3),
.reveal.visible .start-grid > :nth-child(3),
.reveal.visible .lists-grid > :nth-child(3) { animation-delay: 0.16s; }
.reveal.visible .paths > :nth-child(4),
.reveal.visible .popular > :nth-child(4),
.reveal.visible .problems-grid > :nth-child(4),
.reveal.visible .pattern-grid > :nth-child(4),
.reveal.visible .start-grid > :nth-child(4),
.reveal.visible .lists-grid > :nth-child(4) { animation-delay: 0.22s; }
.reveal.visible .paths > :nth-child(5),
.reveal.visible .popular > :nth-child(5),
.reveal.visible .problems-grid > :nth-child(5),
.reveal.visible .pattern-grid > :nth-child(5),
.reveal.visible .start-grid > :nth-child(5),
.reveal.visible .lists-grid > :nth-child(5) { animation-delay: 0.28s; }
.reveal.visible .paths > :nth-child(n+6),
.reveal.visible .popular > :nth-child(n+6),
.reveal.visible .problems-grid > :nth-child(n+6),
.reveal.visible .pattern-grid > :nth-child(n+6),
.reveal.visible .start-grid > :nth-child(n+6),
.reveal.visible .lists-grid > :nth-child(n+6) { animation-delay: 0.34s; }

/* --------------------------------------------------------------------------
   4. Header & navigation
   -------------------------------------------------------------------------- */
#progress-bar {
    position: fixed;
    top: 0;
    left: 0;
    height: 2px;
    width: 0;
    background: var(--accent);
    z-index: 1001;
    transition: width 0.1s linear;
}

header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: var(--bg-header);
    backdrop-filter: blur(14px) saturate(1.6);
    -webkit-backdrop-filter: blur(14px) saturate(1.6);
    border-bottom: 1px solid var(--border);
}

.header-inner {
    max-width: var(--measure);
    margin: 0 auto;
    padding: 0 var(--sp-5);
    height: var(--header-h);
    display: flex;
    align-items: center;
    gap: var(--sp-4);
}

/* Full-bleed variant — pages whose content is an app shell, not a text column */
.header-inner-wide { max-width: none; padding: 0 var(--sp-4); }

/* Small pill button that can sit beside the logo (e.g. "Shuffle" on the judge) */
.header-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.3rem 0.75rem;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: var(--r-full);
    white-space: nowrap;
    flex-shrink: 0;
    transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
                background var(--dur-fast) var(--ease);
}
.header-chip:hover { color: var(--text); border-color: var(--border-accent); background: var(--surface-2); }
/* Drop to icon-only before the header runs out of room next to the auth button */
@media (max-width: 620px) {
    .header-chip { padding: 0.3rem 0.5rem; }
    .header-chip-label { display: none; }
}

/* Logo */
.logo {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 1.0625rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--text);
    text-decoration: none;
    flex-shrink: 0;
}
.logo-icon { width: 22px; height: 22px; border-radius: var(--r-xs); flex-shrink: 0; }
.logo .logo-text span { color: var(--accent); }

/* Primary nav.
   position: relative is load-bearing — the auth dropdown, the mobile nav
   sheet, and the streak popover are all absolutely positioned against it.
   Without it they anchor to <header>, which is full-bleed, and land at the
   viewport edge instead of under their trigger. */
nav { position: relative; display: flex; align-items: center; gap: var(--sp-1); margin-left: auto; }

.nav-links { display: flex; align-items: center; gap: 2px; }

.nav-links a,
.nav-more-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.4rem 0.7rem;
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--text-muted);
    text-decoration: none;
    border-radius: var(--r-sm);
    white-space: nowrap;
    transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.nav-links a:hover,
.nav-more-btn:hover { color: var(--text); background: var(--surface-2); }
.nav-links a.active { color: var(--accent); background: var(--accent-subtle); font-weight: 600; }

/* "More" dropdown */
.nav-more { position: relative; }
.nav-more-caret { font-size: 0.65em; opacity: 0.7; transition: transform var(--dur) var(--ease); }
.nav-more.open .nav-more-caret { transform: rotate(180deg); }

.nav-more-menu {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 190px;
    padding: var(--sp-1);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-lg);
    z-index: 120;
}
.nav-more.open .nav-more-menu,
.nav-more:hover .nav-more-menu { display: block; }
/* Hover bridge across the gap between the button and the menu.
   The menu is offset below the button (top: calc(100% + Npx)), which leaves a
   band of dead space where neither element is hovered. Because the open state
   is driven by .nav-more:hover, crossing that band exits the container and the
   menu closes before the pointer can reach an item.

   This pseudo-element fills the band. It's a child of the menu, hence inside
   .nav-more, so hovering it keeps :hover true for the whole trip. Height is
   14px to comfortably clear both offsets in play — 6px here and the 9.6px in
   auth-styles.html, which loads later and currently wins. Spans the menu's
   full width so a diagonal cursor path stays covered too. */
.nav-more-menu::before {
    content: '';
    position: absolute;
    bottom: 100%;
    left: 0;
    right: 0;
    height: 14px;
}
.nav-more-menu a {
    display: block;
    padding: 0.5rem 0.7rem;
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--text-muted);
    text-decoration: none;
    border-radius: var(--r-sm);
}
.nav-more-menu a:hover { color: var(--text); background: var(--surface-2); }

/* Icon buttons in the header (theme, search, streak) */
#theme-btn,
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    font-size: 0.95rem;
    line-height: 1;
    color: var(--text-muted);
    border-radius: var(--r-sm);
    flex-shrink: 0;
    transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
#theme-btn:hover,
.theme-toggle:hover { color: var(--text); background: var(--surface-2); }

/* Hamburger — hidden on desktop */
.hamburger {
    display: none;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    font-size: 1.15rem;
    line-height: 1;
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    flex-shrink: 0;
}
.hamburger:hover { background: var(--surface-2); }

/* ---- Mobile nav: slide-down sheet with full-width tap targets ---- */
@media (max-width: 860px) {
    .hamburger { display: inline-flex; }

    .nav-links {
        display: none;
        position: absolute;
        top: calc(100% + 8px);
        right: var(--sp-4);
        left: var(--sp-4);
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
        padding: var(--sp-2);
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--r-lg);
        box-shadow: var(--shadow-lg);
        max-height: calc(100vh - var(--header-h) - 24px);
        overflow-y: auto;
    }
    .nav-links.open { display: flex; animation: navSheetIn var(--dur) var(--ease) both; }

    .nav-links a,
    .nav-more-btn {
        padding: 0.7rem 0.85rem;
        font-size: var(--fs-base);
        border-radius: var(--r-sm);
        min-height: 44px;
    }

    /* Flatten the dropdown into the sheet — nested menus are bad on touch */
    .nav-more { position: static; }
    .nav-more-btn { display: none; }
    /* No trigger and no offset menu here, so there's no gap to bridge. Remove it:
       against a static parent it would position from the wrong box, and as a
       child of the flex column auth-styles.html sets it would add a phantom row. */
    .nav-more-menu::before { content: none; }
    .nav-more-menu {
        display: block;
        position: static;
        min-width: 0;
        padding: var(--sp-2) 0 0;
        margin-top: var(--sp-2);
        background: none;
        border: none;
        border-top: 1px solid var(--border);
        border-radius: 0;
        box-shadow: none;
    }
    .nav-more-menu a {
        padding: 0.7rem 0.85rem;
        font-size: var(--fs-base);
        min-height: 44px;
        display: flex;
        align-items: center;
    }
}

@keyframes navSheetIn {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ---- Narrow-viewport header: stop the row from overflowing ----
   The header packs logo + hamburger + search + theme + streak + auth. Below
   ~520px that clips the right edge (the "Sign in" button falls off). Drop the
   secondary streak widget and collapse "Sign in" to just its Google icon —
   the label is a bare text node, so font-size:0 hides it while the fixed-size
   SVG survives. Both selectors are also defined in shared includes; these
   overrides win on specificity + source order (core.css loads first, but the
   media query raises specificity via the wrapping @media is irrelevant — we
   match the includes' 0-1-0 and rely on load order, so use !important to be
   robust against the include's own @media rules). */
@media (max-width: 520px) {
    .sc-daily-btn { display: none !important; }

    .auth-btn:not(.signed-in) {
        font-size: 0 !important;
        gap: 0 !important;
        padding: 0.3rem 0.4rem !important;
        margin-left: 0.25rem !important;
    }
    .auth-btn:not(.signed-in) .auth-google-icon {
        width: 18px;
        height: 18px;
    }
}

/* --------------------------------------------------------------------------
   5. Shared primitives
   -------------------------------------------------------------------------- */
.container { max-width: var(--measure); margin: 0 auto; padding: 0 var(--sp-5); }

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    padding: 0.6rem 1.1rem;
    font-size: var(--fs-sm);
    font-weight: 600;
    line-height: 1.2;
    min-height: 40px;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
                color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn:hover { border-color: var(--border-strong); background: var(--surface-2); }
.btn:active { transform: translateY(1px); }

.btn-primary {
    color: var(--accent-contrast);
    background: var(--accent);
    border-color: var(--accent);
}
.btn-primary:hover {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
    box-shadow: var(--shadow-accent);
}

.btn-ghost { background: none; border-color: transparent; color: var(--text-muted); }
.btn-ghost:hover { background: var(--surface-2); color: var(--text); }

.btn-lg { padding: 0.8rem 1.6rem; font-size: var(--fs-md); min-height: 48px; }

/* Cards */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: var(--sp-5);
    transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease),
                box-shadow var(--dur) var(--ease);
}
.card-link { text-decoration: none; color: inherit; display: block; }
.card-link:hover {
    border-color: var(--border-accent);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

/* Badges / tags */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.55rem;
    font-size: var(--fs-xs);
    font-weight: 600;
    line-height: 1.5;
    color: var(--accent);
    background: var(--accent-subtle);
    border: 1px solid var(--border-accent);
    border-radius: var(--r-full);
    white-space: nowrap;
}
.badge-easy { color: var(--easy); background: color-mix(in srgb, var(--easy) 12%, transparent); border-color: color-mix(in srgb, var(--easy) 30%, transparent); }
.badge-medium { color: var(--medium); background: color-mix(in srgb, var(--medium) 12%, transparent); border-color: color-mix(in srgb, var(--medium) 30%, transparent); }
.badge-hard { color: var(--hard); background: color-mix(in srgb, var(--hard) 12%, transparent); border-color: color-mix(in srgb, var(--hard) 30%, transparent); }

/* Section heading pattern used across listing pages */
.section-eyebrow {
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: var(--sp-2);
}
.section-title {
    font-size: var(--fs-2xl);
    font-weight: 700;
    letter-spacing: -0.025em;
    line-height: 1.2;
    color: var(--text);
}
.section-sub {
    color: var(--text-muted);
    font-size: var(--fs-md);
    margin-top: var(--sp-2);
    max-width: 60ch;
}

/* --------------------------------------------------------------------------
   6. Footer — grouped sitemap, not a run of dot-separated links
   -------------------------------------------------------------------------- */
/* `body > footer` rather than a bare `footer`: embedded widgets have their own
   footers (Excalidraw's zoom/undo bar is one), and the background, border and
   margin here would otherwise paint over their UI. */
body > footer {
    position: relative;
    z-index: 1;
    border-top: 1px solid var(--border);
    background: var(--bg-subtle);
    margin-top: var(--sp-8);
}

.footer-inner {
    max-width: var(--measure);
    margin: 0 auto;
    padding: var(--sp-7) var(--sp-5) var(--sp-5);
}

.footer-grid {
    display: grid;
    grid-template-columns: 1.4fr repeat(3, 1fr);
    gap: var(--sp-6) var(--sp-5);
}

.footer-brand .logo { margin-bottom: var(--sp-3); }
.footer-tagline {
    color: var(--text-muted);
    font-size: var(--fs-sm);
    line-height: 1.6;
    max-width: 34ch;
}

.footer-col-title {
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: var(--sp-3);
}
.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 0.55rem; }
.footer-col a {
    font-size: var(--fs-sm);
    color: var(--text-muted);
    text-decoration: none;
    transition: color var(--dur-fast) var(--ease);
}
.footer-col a:hover { color: var(--accent); }

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    margin-top: var(--sp-6);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--border);
    font-size: var(--fs-xs);
    color: var(--text-dim);
}
.footer-bottom a { color: var(--text-dim); text-decoration: none; }
.footer-bottom a:hover { color: var(--accent); }

@media (max-width: 860px) {
    .footer-grid { grid-template-columns: 1fr 1fr; }
    .footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 520px) {
    .footer-grid { grid-template-columns: 1fr; gap: var(--sp-5); }
}

/* --------------------------------------------------------------------------
   7. Floating controls
   -------------------------------------------------------------------------- */
#back-to-top {
    position: fixed;
    bottom: var(--sp-5);
    right: var(--sp-5);
    width: 42px;
    height: 42px;
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    color: var(--text-muted);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-md);
    z-index: 50;
    transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
                transform var(--dur-fast) var(--ease);
}
#back-to-top.visible { display: flex; }
#back-to-top:hover { color: var(--accent); border-color: var(--border-accent); transform: translateY(-2px); }

/* --------------------------------------------------------------------------
   8. Scrollbars
   -------------------------------------------------------------------------- */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border-radius: var(--r-full);
    border: 2px solid transparent;
    background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--text-dim); background-clip: content-box; }

/* --------------------------------------------------------------------------
   9. Utilities
   -------------------------------------------------------------------------- */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
