/*
 * redesign.css — HiFi Riff Raff public-facing stylesheet
 * =========================================================
 *
 * AESTHETIC DIRECTION: Editorial Magazine
 * ----------------------------------------
 * Think: a music publication's artist feature page, not a tech product
 * landing. Generous whitespace, confident typography, warm palette.
 * The band takes themselves seriously enough to want bookings and press
 * coverage — the site should reflect that without feeling corporate.
 *
 * ONE clear vision executed consistently across every page:
 *   - Cream/parchment backgrounds (not sterile white, not moody dark)
 *   - Near-black charcoal text (not pure #000, not gray-on-gray)
 *   - Fraunces variable font for all display headings (expressive,
 *     slightly editorial, has WONK axis for personality)
 *   - Inter for body copy (legible, neutral, doesn't fight Fraunces)
 *   - Single warm accent: amber/terracotta — used sparingly
 *   - Lots of breathing room; elements are never cramped
 *
 * SCOPE: Public-facing pages only.
 *   Covers: MainLayout, HamburgerMenu, NewsletterSignup,
 *   Home bento, About, Releases, Playlists, Shows, Press,
 *   Privacy, Terms, Unsubscribe, Contact.
 *   Does NOT cover: /band/*, /admin/*, Identity pages, audio player.
 *   Those continue to use app.css.
 *
 * FILE STRUCTURE:
 *   1. Design tokens (custom properties)
 *   2. Base reset + global typography
 *   3. Layout chrome (header, footer, body container)
 *   4. Hamburger navigation
 *   5. Newsletter signup strip + component
 *   6. Public-page shell (hero, sections, shared utilities)
 *   7. Home page (bento grid)
 *   8. About page
 *   9. Releases page
 *  10. Playlists page
 *  11. Shows page
 *  12. Press / EPK page
 *  13. Contact form
 *  14. Privacy & Terms (prose pages)
 *  15. Unsubscribe page
 *  16. Utility + accessibility
 *  17. Responsive (mobile breakpoint ≤ 720px, mid ≤ 960px)
 */


/* =========================================================
   1. DESIGN TOKENS
   ========================================================= */

:root {
    /* --- Color palette ---
       Warm cream for backgrounds; near-black for text; amber accent.
       Only 5 named colors + their shades — one designer, one weekend. */

    --color-cream-light: #FBF8F2;   /* raised surfaces above the page — cards, inputs, modals */
    --color-cream:       #F5F0E8;   /* page background — warm, not sterile */
    --color-cream-deep:  #EDE7D9;   /* subtle inset / card backgrounds */
    --color-cream-mid:   #E0D9CC;   /* borders, dividers */
    --color-cream-dark:  #C9C0B0;   /* muted borders, placeholder fills */

    --color-charcoal:    #1C1A17;   /* primary text — near-black, warm */
    --color-charcoal-mid: #3D3A34;  /* secondary text, subheads */
    --color-charcoal-muted: #6B6660; /* captions, meta, labels */

    --color-accent:      #C4521A;   /* amber/terracotta — the ONE pop color */
    --color-accent-light: #E8733A;  /* hover states */
    --color-accent-dim:  rgba(196, 82, 26, 0.12); /* tinted backgrounds */

    --color-white:       #FFFFFF;
    --color-surface:     var(--color-cream);

    /* --- Semantic surface + text pairs ---
       Pairs ALWAYS travel together. Whenever you set a background-color
       you MUST set its companion text color, and vice versa. This is the
       single rule that makes contrast bugs structurally impossible:
       there's no such thing as "text on body bg" — every text element
       lives in a labeled surface with a guaranteed contrast partner.

       Surfaces:
         surface-page    = the body canvas (cream)
         surface-raised  = a tile sitting on the page (white)
         surface-deep    = a recessed surface (e.g., input field, cream-deep)
         surface-inverse = a dark tile for emphasis (charcoal)
         surface-accent  = the orange/amber accent (CTAs only)

       Each has -text-strong (primary text) and -text-muted (captions,
       meta, eyebrows). All combinations meet WCAG AA 4.5:1 for normal
       text and 3:1 for ≥18px bold. */

    --surface-page:           var(--color-cream);
    --surface-page-text:      var(--color-charcoal);
    --surface-page-text-muted: var(--color-charcoal-muted);

    --surface-raised:         var(--color-white);
    --surface-raised-text:    var(--color-charcoal);
    --surface-raised-text-muted: var(--color-charcoal-muted);

    --surface-deep:           var(--color-cream-deep);
    --surface-deep-text:      var(--color-charcoal);
    --surface-deep-text-muted: var(--color-charcoal-muted);

    --surface-inverse:        var(--color-charcoal);
    --surface-inverse-text:   var(--color-cream);
    --surface-inverse-text-muted: rgba(245, 240, 232, 0.72);

    --surface-accent:         var(--color-accent);
    --surface-accent-text:    var(--color-white);
    --surface-accent-text-muted: rgba(255, 255, 255, 0.85);

    /* Borders for the surface family — same hue family, low contrast */
    --surface-border:         var(--color-cream-mid);
    --surface-inverse-border: rgba(245, 240, 232, 0.18);

    /* --- Typography ---
       Fraunces: display headings (weights 300–800, WONK axis for flair)
       Inter: body copy, UI labels, small text */

    --font-display: 'Fraunces', Georgia, serif;
    --font-body:    'Inter', system-ui, -apple-system, sans-serif;

    /* Type scale — tightened for density. Anchor: 1rem = 16px */
    /* --- Type scale: derived from --text-base via fixed multipliers ---
       Change ONE token (--text-base) and every step scales proportionally.
       The /admin/general page edits a site setting that overrides
       --text-base at runtime — see App.razor for the inline <style> that
       injects the override.
       Multipliers chosen to reproduce the prior visual scale (14 / 16 / 17
       / 20 / 26 / 34 / 44 px when base is 14px). */
    --text-base:  0.875rem;                         /* default = 14px */
    --text-xs:    calc(var(--text-base) * 0.800);   /* ≈ 11.2px @ base 14 */
    --text-sm:    calc(var(--text-base) * 0.914);   /* ≈ 12.8px @ base 14 */
    --text-md:    calc(var(--text-base) * 1.071);   /* ≈ 15px   @ base 14 */
    --text-lg:    calc(var(--text-base) * 1.214);   /* ≈ 17px   @ base 14 */
    --text-xl:    calc(var(--text-base) * 1.429);   /* ≈ 20px   @ base 14 */
    --text-2xl:   calc(var(--text-base) * 1.857);   /* ≈ 26px   @ base 14 */
    --text-3xl:   calc(var(--text-base) * 2.400);   /* ≈ 34px   @ base 14 */
    --text-4xl:   calc(var(--text-base) * 3.143);   /* ≈ 44px   @ base 14 */

    /* Line-height companions */
    --leading-tight:  1.15;
    --leading-snug:   1.25;
    --leading-normal: 1.5;
    --leading-relaxed: 1.6;

    /* --- Spacing scale — tightened for dense interface feel ---
       Reduced ~25-30% across the board. */
    --space-1:   0.2rem;    /* 3.2px */
    --space-2:   0.375rem;  /* 6px   */
    --space-3:   0.5rem;    /* 8px   */
    --space-4:   0.75rem;   /* 12px  */
    --space-5:   1rem;      /* 16px  */
    --space-6:   1.5rem;    /* 24px  */
    --space-7:   2rem;      /* 32px  */
    --space-8:   2.75rem;   /* 44px  */
    --space-9:   4rem;      /* 64px  */
    --space-10:  5.5rem;    /* 88px  */

    /* --- Layout ---
       Max content width keeps long lines readable.
       Narrow column for prose; wide for grid pages. */
    --max-width:        1140px;
    --max-width-prose:  720px;
    --page-gutter:      clamp(var(--space-5), 5vw, var(--space-8));

    /* --- Borders + Radii ---
       Understated — editorial sites rarely have heavy borders. */
    --radius-sm:   4px;
    --radius-md:   8px;
    --radius-lg:   16px;
    --radius-full: 999px;

    /* Global rounding for CMS bento tiles (.cms-block). One knob rounds every tile —
       background, visualizer, and colored tiles alike. Change here to retune site-wide. */
    --cms-tile-radius: var(--radius-md);

    --border-thin:  1px solid var(--color-cream-mid);
    --border-mid:   2px solid var(--color-cream-dark);
    --border-accent: 2px solid var(--color-accent);

    /* --- Shadows ---
       Subtle warm shadows — no cold gray box shadows. */
    --shadow-sm:  0 1px 3px rgba(28, 26, 23, 0.08);
    --shadow-md:  0 4px 12px rgba(28, 26, 23, 0.10);
    --shadow-lg:  0 8px 32px rgba(28, 26, 23, 0.14);

    /* --- Motion ---
       Short transitions for interactive feedback. */
    --ease-out:    cubic-bezier(0.0, 0.0, 0.2, 1);
    --duration-fast: 120ms;
    --duration-mid:  220ms;

    /* --- Practice game palette ---
       Games use an immersive dark theme distinct from the editorial cream palette.
       Keep these tokens together so a future light-mode game variant can swap them. */
    --game-bg:           #16161f;   /* page/stage background */
    --game-card:         #1e1e2e;   /* card / panel background */
    --game-card-alt:     #2a2050;   /* choice button fill */
    --game-card-hover:   #342a66;   /* choice button hover */
    --game-text:         #eeeeee;   /* primary text on dark bg */
    --game-text-muted:   #aaaaaa;   /* secondary / meta text */
    --game-border:       #444444;   /* default border */
    --game-accent:       #7c6fff;   /* purple accent (links, active states) */
    --game-success:      #80e0a0;   /* correct answer green */
    --game-success-bg:   #1a3a24;   /* success card fill */
    --game-success-border: #2a8040; /* success card border */
    --game-danger:       #f08080;   /* wrong answer red */
    --game-danger-bg:    #3a1a1a;   /* danger card fill */
    --game-danger-border: #803030;  /* danger card border */
    --game-gold:         #e0c840;   /* new-best / gold highlight */

    /* Lyric-game specific — light surface theme used by PracticeDashboard
       and the lyric-game setup / results screens. */
    --game-light-bg:     #f0eefb;   /* pill / metric card background */
    --game-light-border: #e3e1ee;   /* tab / card border */
    --game-light-primary: #6a5acd; /* purple primary — buttons, progress, scores */
    --game-light-success: #2e7d32; /* green — best-score, correct flags */
    --game-light-danger:  #c0392b; /* red — trouble words, miss counts */
    --game-light-success-bg: #e7f5e9;  /* success state fill */
    --game-light-danger-bg:  #fbe4e2;  /* danger state fill */
    --game-light-badge-due:  #e7f0fb;  /* "due" badge fill */
    --game-light-badge-due-text: #2f6fb0;
    --game-light-warn:   #9a6a00;   /* amber warning text */
    --game-light-warn-bg: #fff3cf;  /* amber highlight background */
    --game-light-warn-border: #e6b800; /* amber highlight border */

    /* --- Admin control DENSITY tokens (single source of truth for every admin control) ---
       These drive font-size / control height / padding / gaps across the page builder, the
       inspector, the foundation controls, and the layer editor so the admin UI is ONE cohesive,
       space-conserving density system instead of dozens of hardcoded rem/px values. The values
       here are the DENSE profile (default). Wrapping a subtree in `.admin-shell` and setting
       `data-density="ultra"` switches it to the tighter Ultra-dense profile below — that's the
       runtime density toggle. Absolute px (not rem) on purpose: admin chrome should not ride the
       site's --text-base zoom knob. */
    --admin-text-label:   11px;     /* field labels */
    --admin-text-control: 12px;     /* input / select / button text */
    --admin-text-help:    10.5px;   /* helper + error text */
    --admin-text-section: 11px;     /* group/section headings (uppercase) */
    --admin-control-h:    24px;     /* shared input/select/button height — keeps a row aligned */
    --admin-pad-y:        4px;
    --admin-pad-x:        8px;
    --admin-gap:          6px;      /* gap between a label and its control / between fields */
    --admin-section-gap:  10px;     /* gap between grouped sections */
    --admin-radius:       var(--radius-sm);
}

/* Ultra-dense profile — opt-in via the density toggle. Only the values that get tighter. */
.admin-shell[data-density="ultra"] {
    --admin-text-label:   10.5px;
    --admin-text-control: 11px;
    --admin-text-help:    10px;
    --admin-text-section: 10.5px;
    --admin-control-h:    22px;
    --admin-pad-y:        3px;
    --admin-pad-x:        6px;
    --admin-gap:          4px;
    --admin-section-gap:  8px;
}


/* =========================================================
   1b. BENTO SPEC FOUNDATION (additive — docs/features/bento-system/)
   Spec-compliant tokens + utilities layered ALONGSIDE the tokens above.
   Nothing here is wired to a component yet — components migrate onto these
   per-phase (BentoRollout-Plan-v1.md), so this block is visually inert.
   Do NOT re-point the existing --space-1..10 / --text-* values; migrate
   call sites instead.
   ========================================================= */
:root {
    /* --- Spacing: coherent 8px scale (4px substep), role-named ---
       Distinct from the numeric --space-1..10 above (kept until migrated). */
    --space-3xs: 0.25rem;  /* 4px  */
    --space-2xs: 0.5rem;   /* 8px  */
    --space-xs:  0.75rem;  /* 12px */
    --space-s:   1rem;     /* 16px */
    --space-m:   1.5rem;   /* 24px */
    --space-l:   2rem;     /* 32px */
    --space-xl:  3rem;     /* 48px */
    --space-2xl: 4rem;     /* 64px */
    --space-3xl: 6rem;     /* 96px */

    /* --- Fluid type scale (modular ~1.25); clamp() with rem floor/ceiling ---
       Floor/ceiling in rem => zoom-safe (WCAG 1.4.4 200%); the vw term only
       drives the slope between min/max viewport (20rem..80rem). Page/shell text
       uses these steps; in-tile text uses cqi (.bento-tile-* below). */
    --step--1: clamp(0.8rem,  0.76rem + 0.20vw, 0.9rem);
    --step-0:  clamp(1rem,    0.95rem + 0.25vw, 1.125rem);  /* body */
    --step-1:  clamp(1.25rem, 1.16rem + 0.45vw, 1.5rem);
    --step-2:  clamp(1.56rem, 1.41rem + 0.75vw, 2rem);
    --step-3:  clamp(1.95rem, 1.71rem + 1.20vw, 2.66rem);
    --step-4:  clamp(2.44rem, 2.05rem + 1.95vw, 3.55rem);
    --step-5:  clamp(3.05rem, 2.43rem + 3.10vw, 4.74rem);

    /* --- Measure (readable line length) --- */
    --measure: 65ch;

    /* --- Bento layout primitives --- */
    --bento-gutter: clamp(1rem, 5vw, 2.5rem);    /* fluid page side gutter */
    --bento-gap:    clamp(0.75rem, 2vw, 1.5rem); /* fluid inter-tile gap   */
    --content-max:  75rem;                        /* ~1200px content column */
    --radius-tile:  var(--cms-tile-radius);       /* semantic alias         */
    --tile-focal:   50% 50%;                      /* default image focal     */
}

/* Readable-measure helper — never wider than its container. */
.bento-measure { max-width: min(var(--measure), 100%); }

/* In-tile fluid text — scales to the TILE (needs an inline-size container
   ancestor). cqi = 1% of container inline size; rem floor/ceiling keep it
   zoom-safe. (Named .bento-* to avoid the existing .tile-title rule.) */
.bento-tile-title { font-size: clamp(1.1rem, 6cqi, 2.5rem);  line-height: var(--leading-tight, 1.15); }
.bento-tile-body  { font-size: clamp(0.9rem, 3.5cqi, 1.25rem); line-height: var(--leading-normal, 1.5); }

/* Full-bleed safe-area padding (notched devices). Requires viewport-fit=cover
   on the viewport meta (App.razor); env() resolves to 0 on rectangular screens. */
.bento-safe-pad-inline {
    padding-inline: max(var(--bento-gutter), env(safe-area-inset-left), env(safe-area-inset-right));
}

/* Grid size-class spans of a 12-col authoring grid, clamped so a span never
   exceeds the live column count (--bento-cols, set per breakpoint in Phase 1).
   Inert until the grid contract lands; here so components can adopt them. */
.bento-s    { grid-column: span min(3, var(--bento-cols, 12)); }
.bento-m    { grid-column: span min(4, var(--bento-cols, 12)); }
.bento-l    { grid-column: span min(6, var(--bento-cols, 12)); }
.bento-wide { grid-column: span min(8, var(--bento-cols, 12)); }
.bento-hero { grid-column: 1 / -1; }


/* =========================================================
   2. BASE RESET + GLOBAL TYPOGRAPHY
   ========================================================= */

/*
 * Minimal targeted reset — don't nuke everything because app.css
 * is still in play for admin/band areas. We scope to the public
 * layout container where possible.
 */

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* Body sets the canvas.
   app.css's `.dynamic-background-*` classes paint a blurred gray
   gradient + `filter: blur(80px) contrast(80%)` on <body>. The filter
   blurs ALL child content — which is why the redesign was rendering
   "dark purple over dark grey" for release titles + every page felt
   smeared. We override the entire animated-bg machinery here:
     - background-color: solid cream (kills the gradient)
     - background-image: none (kills the radial-gradient stops)
     - filter: none (THIS is the critical one — without it the entire
                     page is rendered through an 80px Gaussian blur)
     - all !important because app.css's body rules outweigh ours
                     without it. */
body {
    background-color: var(--surface-page) !important;
    background-image: none !important;
    filter: none !important;
    color: var(--surface-page-text);
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    margin: 0;
    padding: 0;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Kill the animated blobs (::before / ::after pseudo-elements) painted
   by .dynamic-background-bright-one + -dark-one in app.css. These were
   incompatible with the editorial direction — blurry gray motion behind
   editorial type doesn't work. */
body[class*="dynamic-background"]::before,
body[class*="dynamic-background"]::after {
    content: none !important;
    display: none !important;
    animation: none !important;
}

/* SCROLLBAR + HORIZONTAL-OVERFLOW ROOT-CAUSE FIX.
   app.css's `.main-layout-body { height: calc(100dvh - 4.5rem);
   overflow-y: auto; width: 100vw }` was creating both bugs:
     1. Inner overflow-y: auto → a second vertical scrollbar inside
        the page, while <html> also scrolls. (User report: "two
        side-by-side vertical scrollbars.")
     2. width: 100vw → viewport width INCLUDES the scrollbar gutter,
        so the body becomes ~15px wider than its parent on browsers
        that reserve scrollbar space. (User report: horizontal
        scrollbar that only scrolls the scrollbar's own width.)
   Both are dispatched by letting <html> own the scrolling, and sizing
   the body to its container (not the viewport). The previous
   overflow-x: clip + scrollbar-gutter: stable hack is removed —
   defending against this overflow was unnecessary once the source
   stopped producing it. */
.main-layout-body {
    height: auto !important;
    overflow: visible !important;
    width: 100% !important;
}

/* Typographic defaults inside the public layout container.
   AI Note: every selector below uses `:where()` so it has specificity 0,0,1
   instead of 0,1,1. This is THE critical fix for the contrast-bug class
   we kept hitting: previously `.main-layout-container h1 { color: charcoal }`
   beat per-tile rules like `.home-hero-tagline-text { color: cream }`
   because (0,1,1) > (0,1,0). With :where() the specificity falls to a single
   element, so any per-component class wins automatically. */
:where(.main-layout-container) {
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
}

:where(.main-layout-container) h1,
:where(.main-layout-container) h2,
:where(.main-layout-container) h3,
:where(.main-layout-container) h4 {
    font-family: var(--font-display);
    font-weight: 600;
    line-height: var(--leading-tight);
    /* No color: surface containers set their own; absent that, headings
       inherit body color (charcoal). This is what lets a charcoal tile
       have cream-colored headings without a specificity fight. */
    margin: 0;
}

:where(.main-layout-container) p {
    margin: 0;
}

:where(.main-layout-container) a {
    color: var(--color-accent);
    text-decoration: none;
    transition: color var(--duration-fast) var(--ease-out);
}

:where(.main-layout-container) a:hover {
    color: var(--color-accent-light);
}

/* Remove list bullets inside the public layout (nav, press lists,
   etc. use their own classes) */
:where(.main-layout-container) ul,
:where(.main-layout-container) ol {
    margin: 0;
    padding: 0;
    list-style: none;
}

img {
    max-width: 100%;
    height: auto;
    display: block;
}

button {
    font-family: inherit;
    cursor: pointer;
}

/* Focus ring — warm accent, not browser blue */
.main-layout-container :focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}


/* =========================================================
   3. LAYOUT CHROME
   Header · Body · Footer
   ========================================================= */

/*
 * Main layout structure:
 *   .main-layout-container (flex column, full height)
 *     .main-layout-header  (sticky top bar — compact, 40px target height)
 *     .main-layout-body    (flex-grow, page content lives here)
 *     .main-layout-newsletter (slim strip above footer)
 *     .main-layout-footer  (copyright row)
 *
 * Header child order (left → right):
 *   [logo] [HamburgerMenu — inline nav + mobile toggle] [booking pill]
 */

/* --- Header --- */

.main-layout-header {
    position: sticky;
    top: 0;
    z-index: 100;
    /* relative so .site-nav-panel (position: absolute) anchors here */
    display: flex;
    align-items: center;
    gap: var(--space-4);
    /* Header height target: ~32px. Both the logo (24px) and the booking
       pill (~22px) are sized below so they fit in this band without
       padding pushing it taller. */
    padding: 2px var(--page-gutter);
    border-bottom: var(--border-thin);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    background-color: rgba(245, 240, 232, 0.93);
    min-height: 0;
}

/* Logo chrome — height/padding/margin are admin-controlled via
   /admin/general, injected into :root by App.razor. Defaults set
   below are the bare-CSS fallback when no override is saved. */
.main-layout-header-logo-wrapper {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    padding: var(--logo-padding, 0);
    margin: var(--logo-margin, 0);
}

.main-layout-header-logo-link {
    display: flex;
    align-items: center;
    /* No color override — SVG carries its own color */
}

.main-layout-header-logo {
    height: var(--logo-height, 24px);
    width: auto;
    display: block;
}

/* Right-side actions group — booking pill + any future header icons */
.main-layout-header-actions {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
}

/* "Booking Inquiry" pill — minimal so it doesn't dominate header height.
   Pill is ~22px tall; with header's 2px vertical padding the total band
   is ~26-28px. */
.main-layout-header-booking {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 1px var(--space-3);
    background-color: var(--surface-accent);
    color: var(--surface-accent-text) !important;
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    border-radius: var(--radius-full);
    text-decoration: none;
    line-height: 1.5;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.main-layout-header-booking:hover {
    background-color: var(--color-accent-light);
    color: var(--surface-accent-text) !important;
    transform: translateY(-1px);
}

/* --- Body --- */

.main-layout-body {
    flex: 1;
    /* No padding here — each page controls its own gutter */
}

.main-layout-body main {
    min-height: 0;
}

/* --- Newsletter strip --- */

.main-layout-newsletter {
    border-top: var(--border-thin);
    background-color: var(--color-cream-deep);
    padding: var(--space-4) var(--page-gutter);
    display: flex;
    justify-content: center;
}

/* --- Footer --- */

.main-layout-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-5);
    padding: var(--space-4) var(--page-gutter);
    border-top: var(--border-thin);
    background-color: var(--color-cream);
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
}

.main-layout-footer a {
    color: var(--color-charcoal-muted);
    transition: color var(--duration-fast) var(--ease-out);
}

.main-layout-footer a:hover {
    color: var(--color-accent);
}

/* Blazor error UI.
   AI Note: this div MUST default to `display: none`. Blazor's JS reveals it by
   setting an inline `style="display: block"` ONLY when a genuine unhandled error
   occurs. A previous redesign pass set `display: flex` with NO hidden default
   ("keep unobtrusive but visible"), which left the "An unhandled error has
   occurred" banner permanently shown on every page using this layout — with no
   actual error. Do NOT remove `display: none`. See docs/Landmines-v1.md. */
#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 9999;
    padding: var(--space-4) var(--page-gutter);
    background: #7B1D1D;
    color: #fff;
    font-size: var(--text-sm);
    align-items: center;
    gap: var(--space-4);
}

/* When Blazor genuinely reveals the banner it sets inline `display: block`.
   Restore the flex row layout (so the dismiss button right-aligns) — !important
   is required to beat the framework-set inline style. */
#blazor-error-ui[style*="block"] {
    display: flex !important;
}

#blazor-error-ui a {
    color: #fff;
    text-decoration: underline;
}

#blazor-error-ui .dismiss {
    margin-left: auto;
    cursor: pointer;
    opacity: 0.8;
}

#blazor-error-ui .dismiss:hover {
    opacity: 1;
}


/* =========================================================
   4. SITE NAVIGATION
   Inline desktop strip + mobile slide-down panel
   ========================================================= */

/*
 * HamburgerMenu.razor renders the nav in two layers:
 *
 *   1. .site-nav-inline  — horizontal row of links, visible on desktop
 *                          (> 880px), hidden on mobile
 *   2. .site-nav-toggle-btn + .site-nav-panel — the hamburger icon +
 *                          full-width slide-down panel, visible on mobile
 *                          and always-available for authenticated users
 *                          who need band/admin links on desktop
 *
 * Markup order in HamburgerMenu.razor (MUST stay fixed):
 *   input.site-nav-toggle-input   ← hidden checkbox toggle
 *   nav.site-nav-inline           ← desktop inline links
 *   label.site-nav-toggle-btn     ← the 3-bar button
 *   nav.site-nav-panel            ← the panel (sibling of checkbox)
 *
 * CSS selector bridge: :checked ~ .site-nav-panel opens the panel.
 * The label is the visual button; the input is the state holder.
 *
 * AI Note: The toggle input must remain a PREVIOUS sibling of BOTH the
 * label and the panel. Reordering breaks the :checked ~ selector without
 * producing a compile error. See HamburgerMenu.razor for the full rationale.
 */

/* --- Shared container --- */

/* The entire SiteNav is a flex row that lives in the header.
   We set flex: 1 so it stretches between logo and actions. */
.site-nav-toggle-input,
.site-nav-inline,
.site-nav-toggle-btn,
.site-nav-panel {
    /* nothing at this level — each sub-element sized below */
}

/* The SiteNav renders directly inside .main-layout-header as siblings:
   [logo-wrapper] [toggle-input (0x0)] [site-nav-inline] [toggle-btn] [actions]
   We need site-nav-inline to grow and fill the center gap. */
.site-nav-inline {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 1;
    padding: 0 var(--space-3);
}

/* --- Desktop inline links --- */

.site-nav-link {
    display: inline-flex;
    align-items: center;
    /* Tight enough to fit in the ~32px header band. */
    padding: 2px var(--space-3);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-charcoal-mid);
    text-decoration: none;
    border-radius: var(--radius-sm);
    letter-spacing: 0.01em;
    line-height: 1.5;
    transition: color var(--duration-fast) var(--ease-out),
                background-color var(--duration-fast) var(--ease-out);
    white-space: nowrap;
}

.site-nav-link:hover {
    color: var(--color-charcoal);
    background-color: var(--color-cream-deep);
}

/* Blazor NavLink adds .active when the route matches */
.site-nav-link.active {
    color: var(--color-accent);
    font-weight: 600;
}

/* --- Hidden toggle checkbox --- */

.site-nav-toggle-input {
    /* Invisible state holder — activated via label */
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    pointer-events: none;
}

/* --- Hamburger toggle button --- */

.site-nav-toggle-btn {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    width: 36px;
    height: 36px;
    padding: var(--space-2);
    flex-shrink: 0;
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: background-color var(--duration-fast) var(--ease-out);
}

.site-nav-toggle-btn:hover {
    background-color: var(--color-cream-deep);
}

.site-nav-bar {
    display: block;
    width: 18px;
    height: 1.5px;
    background-color: var(--color-charcoal);
    border-radius: 1px;
    transition: transform var(--duration-mid) var(--ease-out),
                opacity var(--duration-mid) var(--ease-out);
    transform-origin: center;
}

/* X animation when panel is open */
.site-nav-toggle-input:checked ~ .site-nav-toggle-btn .site-nav-bar:nth-child(1) {
    transform: translateY(6.5px) rotate(45deg);
}

.site-nav-toggle-input:checked ~ .site-nav-toggle-btn .site-nav-bar:nth-child(2) {
    opacity: 0;
    transform: scaleX(0);
}

.site-nav-toggle-input:checked ~ .site-nav-toggle-btn .site-nav-bar:nth-child(3) {
    transform: translateY(-6.5px) rotate(-45deg);
}

/* --- Slide-down panel --- */

/*
 * The panel is position:absolute relative to .main-layout-header (sticky).
 * It is sized to its CONTENT and right-anchored (under the booking pill
 * area). NOT full-viewport-width — that looked ridiculous on desktop.
 *
 * AI Note: max-height + overflow-y ensures the panel never clips when
 * a logged-in Administrator has 15+ items in band+admin sections.
 */
.site-nav-panel {
    display: none;           /* closed by default */
    position: absolute;
    top: 100%;
    right: 0;                /* anchor to header's right edge */
    z-index: 200;
    background-color: var(--surface-raised);
    color: var(--surface-raised-text);
    border: var(--border-thin);
    border-top: none;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    box-shadow: var(--shadow-lg);
    /* Size to content with a sane min/max envelope. Cap is wide enough for all admin sections
       (Account/Band/Site/Admin/Store) to sit side-by-side on desktop instead of wrapping the
       last column to a new line; still clamps to the viewport on narrow screens. */
    width: max-content;
    max-width: min(calc(100vw - 2rem), 1040px);
    min-width: 200px;
    max-height: calc(100dvh - 4rem);
    overflow-y: auto;
    padding: var(--space-4) var(--space-5);
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--space-4) var(--space-6);
}

.site-nav-toggle-input:checked ~ .site-nav-panel {
    display: flex;
}

/* Public links — shown in panel on mobile, hidden on desktop
   since they're visible inline */
.site-nav-panel-public {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 130px;
}

/* Section groups for authenticated links */
.site-nav-panel-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 130px;
}

.site-nav-panel-section-label {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-charcoal-muted);
    padding: var(--space-2) var(--space-3) var(--space-1);
    display: block;
}

.site-nav-panel-link {
    display: block;
    padding: var(--space-2) var(--space-3);
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--color-charcoal);
    text-decoration: none;
    border-radius: var(--radius-sm);
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.site-nav-panel-link:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-accent);
}

.site-nav-panel-link.active {
    color: var(--color-accent);
    font-weight: 600;
}

/* Footer row inside the panel — login/logout */
.site-nav-panel-footer {
    width: 100%;
    border-top: var(--border-thin);
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    display: flex;
    align-items: center;
}

.site-nav-panel-logout {
    padding: var(--space-2) var(--space-3);
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--color-charcoal-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    text-align: left;
    transition: color var(--duration-fast) var(--ease-out),
                background-color var(--duration-fast) var(--ease-out);
}

.site-nav-panel-logout:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

/* On desktop: the panel is still available (for authenticated band/admin
   users), but the public links column inside it is redundant — already
   visible inline. Hide the public-links column at desktop widths.
   The panel itself only opens when the hamburger is clicked. */
@media (min-width: 881px) {
    .site-nav-panel-public {
        display: none;
    }

    /* On desktop, unauthenticated visitors never need the panel at all.
       We don't hide the toggle button because we can't know auth state in
       CSS — but we can hide it if there are no authenticated sections.
       The authenticated sections are wrapped in <AuthorizeView> which
       renders nothing when logged out, so the panel just shows the footer
       login link — acceptable. We can't do better without JS. */
}

/* On mobile: hide inline links, always show the toggle button */
@media (max-width: 880px) {
    .site-nav-inline {
        display: none;
    }

    .site-nav-toggle-btn {
        /* Always visible on mobile */
        display: flex;
    }
}


/* =========================================================
   5. NEWSLETTER SIGNUP COMPONENT
   ========================================================= */

/*
 * The newsletter strip sits in .main-layout-newsletter (footer-adjacent).
 * It can also be dropped on any page. The component itself is the island;
 * only the .newsletter-signup* classes are styled here.
 */

.newsletter-signup {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    max-width: 480px;
    text-align: center;
    transition: opacity var(--duration-mid) var(--ease-out);
}

/* Confirmed state: fade slightly to signal done-ness */
.newsletter-signup-ok {
    opacity: 0.75;
}

.newsletter-signup-label {
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--color-charcoal);
    letter-spacing: -0.01em;
}

.newsletter-signup-form {
    display: flex;
    gap: var(--space-2);
    width: 100%;
}

.newsletter-signup-input {
    flex: 1;
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-base);
    color: var(--color-charcoal);
    transition: border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
}

.newsletter-signup-input::placeholder {
    color: var(--color-charcoal-muted);
}

.newsletter-signup-input:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-dim);
}

.newsletter-signup-input-invalid {
    border-color: #B91C1C;
}

.newsletter-signup-button {
    flex-shrink: 0;
    padding: var(--space-3) var(--space-5);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.newsletter-signup-button:hover:not(:disabled) {
    background-color: var(--color-accent);
    transform: translateY(-1px);
}

.newsletter-signup-button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Feedback messages */
.newsletter-signup-feedback {
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
}

.newsletter-signup-feedback-ok {
    color: #166534;
}

.newsletter-signup-feedback-alreadysubscribed,
.newsletter-signup-feedback-welcome_back {
    color: var(--color-charcoal-muted);
}

.newsletter-signup-feedback-error {
    color: #B91C1C;
}


/* =========================================================
   6. PUBLIC-PAGE SHELL
   Page eyebrow · Section · Content · Empty · Contact card
   ========================================================= */

/*
 * PUBLIC PAGE PHILOSOPHY (post-redesign):
 *
 * Bento pages (About, Releases, Playlists, Shows):
 *   article.public-page
 *     div.page-eyebrow   ← tiny one-line label, no H1 preamble
 *     [grid/list content immediately]
 *
 * Structured pages (Press):
 *   article.public-page
 *     div.page-eyebrow
 *     [section groups with .press-section-label, no big H2 dividers]
 *
 * Prose pages (Privacy, Terms):
 *   article.public-page
 *     header.public-page-hero   ← compact hero kept for legal pages
 *     div.public-page-content
 *       section.public-page-section [repeated]
 *
 * The old pattern (large H1 hero + big H2 section-title with accent bar
 * before every bento grid) added 150-200px of chrome before first content.
 * The new pattern: tiles carry their own labels; the page eyebrow is
 * one short label line.
 */

/* --- View transitions (PP2) ---
 * @view-transition { navigation: auto } enables native page transitions
 * when Blazor Enhanced Navigation fires (uses the Navigation API in
 * Chrome/Edge 111+). Gracefully degrades to instant swap on other browsers.
 * The page-enter animation provides a fallback for non-supporting browsers
 * and acts as the ::view-transition-new animation on supporting ones.
 */
@view-transition {
    navigation: auto;
}

@keyframes page-enter {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* --- Base page container --- */

.public-page {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--space-5) var(--page-gutter) var(--space-8);
    width: 100%;
    animation: page-enter 0.22s var(--ease-out) both;
}

@media (prefers-reduced-motion: reduce) {
    .public-page {
        animation: none;
    }
}

/* --- Page eyebrow --- (replaces the hero on bento pages)
   A single compact line at the top: page title as a small label.
   No border, no bottom margin blowout, no lead paragraph. */

.page-eyebrow {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.page-eyebrow-title {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-charcoal-muted);
}

.page-eyebrow-lead {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    line-height: var(--leading-normal);
}

/* --- Prose hero (Privacy, Terms only) --- */

.public-page-hero {
    max-width: var(--max-width-prose);
    /* Tight bottom space — these are legal pages, the copy is the content */
    margin-bottom: var(--space-5);
    padding-bottom: var(--space-4);
    border-bottom: var(--border-thin);
}

.public-page-hero-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    line-height: var(--leading-tight);
    letter-spacing: -0.02em;
    color: var(--color-charcoal);
    margin-bottom: var(--space-2);
    font-variation-settings: 'WONK' 0;
}

.public-page-hero-lead {
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--color-charcoal-muted);
}

/* --- Section (prose pages — Privacy, Terms) --- */

.public-page-section {
    margin-bottom: var(--space-5);
    padding-bottom: var(--space-5);
    border-bottom: var(--border-thin);
}

.public-page-section:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
}

/* Section heading for prose pages — plain, legible, no accent chrome */
.public-page-section-title {
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: 700;
    color: var(--color-charcoal);
    margin-bottom: var(--space-3);
    line-height: var(--leading-snug);
    letter-spacing: -0.01em;
    /* No accent bar — that was the bento preamble pattern we're removing */
}

/* --- Prose content container (Privacy, Terms) --- */

.public-page-content {
    max-width: var(--max-width-prose);
}

.public-page-content p + p {
    margin-top: var(--space-4);
}

.public-page-content ul,
.public-page-content ol {
    list-style: revert;
    padding-left: var(--space-6);
    margin-top: var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

/* --- Section label used inside bento + press sections ---
   A small uppercase label above a grid or content block.
   Does NOT add a heavy border or large margin. */

.section-label {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--surface-page-text-muted);
    margin-bottom: var(--space-3);
    display: block;
}

/* --- .section-block ---
   A FULL-WIDTH slim tile used to host text that would otherwise sit
   orphaned on the body background. Same chrome family as the other
   tiles — predictable contrast guaranteed because it pulls its color
   from the surface-deep token pair.

   Use this when you need a between-section header, divider label, or
   any standalone text that's not inside a card/grid. Don't use it for
   primary section titles inside a tile (the tile chrome already does
   that job).

       <div class="section-block">
         <span class="section-label">Latest releases</span>
         <p>Optional one-line description.</p>
       </div> */
.section-block {
    background-color: var(--surface-deep);
    color: var(--surface-deep-text);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-5);
    margin: var(--space-5) 0 var(--space-4);
    display: flex;
    align-items: baseline;
    gap: var(--space-4);
    flex-wrap: wrap;
}

.section-block .section-label {
    margin-bottom: 0;       /* tile padding handles spacing */
    color: var(--surface-deep-text-muted);
}

.section-block p {
    font-size: var(--text-sm);
    color: var(--surface-deep-text);
    line-height: var(--leading-normal);
    margin: 0;
}


/* =========================================================
   6.5 COMPOSABLE TILE CONTAINER CLASSES
   ========================================================= */

/*
 * The user-proposed "guarantee" pattern:
 *
 *   "Define CSS classes for the different bento box styles and define
 *    all the text colors along with the background colors, button colors,
 *    etc. So that you can just apply that class to the container and be
 *    guaranteed that everything will look right."
 *
 * Three named tile variants (light / deep / dark / accent) — apply ONE
 * variant class to any container and EVERY descendant element gets a
 * matching color from the same surface token pair. No more "I picked
 * a dark tile bg and forgot to recolor the .meta inside it" bugs.
 *
 * Usage:
 *   <div class="tile tile-light">       ← light cream surface
 *     <h2>Title</h2>                    ← gets surface-raised-text
 *     <p>Body copy.</p>                 ← gets surface-raised-text
 *     <a href="...">A link</a>          ← gets accent
 *     <span class="meta">Caption</span> ← gets muted token
 *   </div>
 *
 *   <div class="tile tile-dark">        ← dark charcoal surface
 *     [all descendants → cream text automatically]
 *   </div>
 *
 * Pick a variant based on emphasis: light = default tile, deep =
 * recessed/secondary, dark = high-emphasis hero block, accent = CTA.
 *
 * AI Note: descendants are matched by tag where possible (h1-h4, p, a,
 * dt, dd) so the system works without forcing every text node to carry
 * an extra class. For semantic-neutral spans + divs, use the .muted
 * helper class to opt into the muted color.
 */

/* --- Base tile chrome — apply this WITH a variant class --- */
.tile {
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-md);
    border: 1px solid transparent;
}

/* ----- LIGHT TILE — cream/parchment, charcoal text (DEFAULT) ----- */
.tile-light {
    background-color: var(--surface-raised);
    color: var(--surface-raised-text);
    border-color: var(--surface-border);
}

.tile-light :where(h1, h2, h3, h4, h5, h6) {
    color: var(--surface-raised-text);
}

.tile-light :where(p, li, dt, dd, span:not(.meta):not(.muted):not([class*="eyebrow"]):not([class*="label"])) {
    color: var(--surface-raised-text);
}

.tile-light :where(a) {
    color: var(--color-accent);
}

.tile-light :where(a:hover) {
    color: var(--color-accent-light);
}

.tile-light :where(.meta, .muted, [class*="eyebrow"], [class*="label"], small, figcaption, time) {
    color: var(--surface-raised-text-muted);
}

/* ----- DEEP TILE — slightly recessed cream-deep, charcoal text ----- */
.tile-deep {
    background-color: var(--surface-deep);
    color: var(--surface-deep-text);
    border-color: var(--surface-border);
}

.tile-deep :where(h1, h2, h3, h4, h5, h6) {
    color: var(--surface-deep-text);
}

.tile-deep :where(p, li, dt, dd, span:not(.meta):not(.muted):not([class*="eyebrow"]):not([class*="label"])) {
    color: var(--surface-deep-text);
}

.tile-deep :where(a) {
    color: var(--color-accent);
}

.tile-deep :where(a:hover) {
    color: var(--color-accent-light);
}

.tile-deep :where(.meta, .muted, [class*="eyebrow"], [class*="label"], small, figcaption, time) {
    color: var(--surface-deep-text-muted);
}

/* ----- DARK TILE — charcoal surface, cream text ----- */
.tile-dark {
    background-color: var(--surface-inverse);
    color: var(--surface-inverse-text);
    border-color: var(--surface-inverse-border);
}

.tile-dark :where(h1, h2, h3, h4, h5, h6) {
    color: var(--surface-inverse-text);
}

.tile-dark :where(p, li, dt, dd, span:not(.meta):not(.muted):not([class*="eyebrow"]):not([class*="label"])) {
    color: var(--surface-inverse-text);
}

.tile-dark :where(a) {
    color: var(--color-accent-light);
}

.tile-dark :where(a:hover) {
    color: var(--color-cream);
}

.tile-dark :where(.meta, .muted, [class*="eyebrow"], [class*="label"], small, figcaption, time) {
    color: var(--surface-inverse-text-muted);
}

/* ----- ACCENT TILE — amber surface, white text (used SPARINGLY) ----- */
.tile-accent {
    background-color: var(--surface-accent);
    color: var(--surface-accent-text);
    border-color: transparent;
}

.tile-accent :where(h1, h2, h3, h4, h5, h6) {
    color: var(--surface-accent-text);
}

.tile-accent :where(p, li, dt, dd, span:not(.meta):not(.muted)) {
    color: var(--surface-accent-text);
}

.tile-accent :where(a) {
    color: var(--surface-accent-text);
    text-decoration: underline;
}

.tile-accent :where(.meta, .muted) {
    color: var(--surface-accent-text-muted);
}

/* ----- Tile-internal labels (eyebrows above titles within tiles) ----- */
/* The .tile-eyebrow class is a small uppercase chip inside any tile.
   Color is inherited from the variant's muted token via the descendant
   match above, so it adapts to light/deep/dark/accent automatically. */
.tile-eyebrow {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    display: block;
    margin-bottom: var(--space-2);
}

/* ----- Tile-internal title (the in-tile heading) ----- */
.tile-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: var(--leading-tight);
    letter-spacing: -0.01em;
    margin: 0 0 var(--space-2);
    display: block;
}

/* --- Empty state --- */

.public-page-empty {
    font-size: var(--text-md);
    color: var(--color-charcoal-muted);
    font-style: italic;
    padding: var(--space-8) 0;
    text-align: center;
}

/* --- Contact card --- */

.public-page-contact-card {
    margin-top: var(--space-4);
    padding: var(--space-4) var(--space-5);
    background-color: var(--surface-deep);
    color: var(--surface-deep-text);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    font-size: var(--text-base);
    max-width: 400px;
}

.public-page-contact-card p {
    color: var(--surface-deep-text);
    line-height: var(--leading-normal);
}

/* --- Contact form container override (Contact.razor) ---
   app.css's .contact-container sets a dark bg + dark-grey label color
   (user report: "dark grey text on a slightly darker grey background").
   Override here so the contact page reads as a light tile with charcoal
   labels — same surface family as everything else on the public site. */
.contact-container {
    background-color: var(--surface-raised) !important;
    color: var(--surface-raised-text) !important;
    border: var(--border-thin);
    border-radius: var(--radius-md);
    padding: var(--space-6) var(--space-6) !important;
    box-shadow: none !important;
    min-height: 0 !important;       /* override `calc(100vh - 4.5rem)` */
}

.contact-container :where(h1, h2, h3) {
    color: var(--surface-raised-text) !important;
}

.contact-container :where(label, .form-group label) {
    color: var(--surface-raised-text) !important;
    opacity: 1 !important;
    font-weight: 600;
    text-transform: none !important;
    letter-spacing: 0 !important;
    font-size: var(--text-sm);
    margin-bottom: var(--space-1);
}

.contact-container :where(input, select, textarea) {
    background-color: var(--color-white) !important;
    color: var(--surface-raised-text) !important;
    border: var(--border-thin) !important;
    border-radius: var(--radius-sm) !important;
    padding: var(--space-2) var(--space-3) !important;
    font-size: var(--text-base) !important;
}

.contact-container :where(input:focus, select:focus, textarea:focus) {
    outline: none !important;
    border-color: var(--color-accent) !important;
    box-shadow: 0 0 0 3px var(--color-accent-dim) !important;
}

.contact-container .btn-submit {
    background-color: var(--surface-accent) !important;
    color: var(--surface-accent-text) !important;
    border: none !important;
    border-radius: var(--radius-full) !important;
    padding: var(--space-3) var(--space-6) !important;
    font-family: var(--font-body);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    width: auto !important;
    align-self: flex-start;
}


/* =========================================================
   7. HOME PAGE — BENTO GRID
   .home > .home-hero > tiles
   ========================================================= */

/*
 * The Home page uses an asymmetric bento grid. Tiles of varying sizes
 * sit in a CSS grid container. Tile types:
 *   - Tagline block (spans ~2 columns, large display text)
 *   - Band photo  (portrait tile, spans a full column)
 *   - Release tile (rich: cover art + body)
 *   - Performance tile (rich: title + video embed)
 *   - Shows strip (when upcoming show exists)
 *   - Booking CTA (always present)
 *
 * WONK axis on Fraunces adds personality to the hero text.
 */

.home {
    /* Remove default public-page padding — home manages its own layout */
    padding: 0;
    max-width: none;
}

/* Bento grid container
   AI Note: grid placement is explicit on ALL tiles to prevent overlap.
   4-column × 3-row layout (2fr 1fr 1fr 1fr):
     Row 1: tagline (col 1-2) | release (col 3) | photo (col 4)
     Row 2: performance (col 1-2) | shows (col 3) | booking (col 4)
     Row 3: newsletter (cols 1-4 full-width slim strip)
   The shows tile is conditional — when absent, booking still sits at
   col 4 row 2 and performance keeps its min-height.

   AI Note: row-gap is defined on the container (gap: var(--space-3)).
   Do NOT add negative margins or top offsets on tiles — use gap exclusively
   for row spacing. Using explicit grid-template-rows: auto auto auto prevents
   implicit row creation which was the source of the "second row hovering
   over the first row" bug (auto-rows produced uneven row heights at certain
   content sizes). */
.home-hero {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    /* Rows are dynamic — tiles set their own grid-row via inline styles
       from the HomeTile DB row (admin-controlled). Auto rows so the grid
       grows to fit however many rows admins use. */
    grid-auto-rows: minmax(180px, auto);
    gap: var(--space-3);
    padding: var(--space-5) var(--page-gutter) var(--space-7);
    max-width: var(--max-width);
    margin: 0 auto;
    width: 100%;
    align-items: stretch;
}

/* =========================================================
   7.5 HOME-TILE COMPONENT (data-driven)
   ========================================================= */
/* Each tile in the home bento is a .tile.tile-{variant} (chrome from
   the composable tile system) plus .home-tile + a type modifier
   (.home-tile-tagline / -photo / -release / -performance / -show /
   -newsletter / -booking / -custom).

   The wrapper carries grid-column / grid-row INLINE styles (set from
   the HomeTile DB row by the admin), so layout is data-driven, not
   per-class.

   Layout inside each tile-type is handled here. Color comes from the
   tile-{variant} composable class. */

.home-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    overflow: hidden;
}

/* Override: tagline tile is centered + has its own large type stack */
.home-tile-tagline {
    justify-content: center;
    gap: var(--space-3);
    padding: var(--space-6) var(--space-5);
}

.home-tile-tagline-text {
    font-family: var(--font-display);
    font-size: var(--text-4xl);
    font-weight: 800;
    line-height: 1.0;
    letter-spacing: -0.04em;
    margin: 0;
    font-variation-settings: 'WONK' 1, 'opsz' 144;
}

.home-tile-tagline-sub {
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    max-width: 40ch;
    margin: 0;
}

.home-tile-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-2);
}

/* Photo tile — unboxed: image bleeds to tile edges */
.home-tile-photo {
    padding: 0;
    overflow: hidden;
}

.home-tile-photo-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}

.home-tile-photo .scene-container {
    /* Cancel any min-height the composite component sets */
    min-height: 0;
    height: 100%;
    width: 100%;
}

/* Release tile — cover-art + body side-by-side */
.home-tile-release {
    padding: var(--space-3);
}

.home-tile-link-cover,
.home-tile-link {
    display: flex;
    gap: var(--space-3);
    text-decoration: none;
    color: inherit;
    height: 100%;
}

.home-tile-cover {
    flex-shrink: 0;
    width: 96px;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background-color: var(--color-charcoal);
}

.home-tile-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.home-tile-cover-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-2);
    font-family: var(--font-display);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-cream);
    text-align: center;
}

.home-tile-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
    flex: 1;
}

.home-tile-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: var(--leading-snug);
    margin: 0;
}

.home-tile-meta {
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
}

.home-tile-empty {
    font-size: var(--text-sm);
    margin: 0;
    opacity: 0.85;
}

/* Performance tile — title on top, embed dominates below */
.home-tile-performance {
    padding: var(--space-3);
}

.home-tile-video {
    margin-top: var(--space-2);
    border-radius: var(--radius-sm);
    overflow: hidden;
    aspect-ratio: 16 / 9;
}

.home-tile-video .youtube-embed {
    height: 100%;
    width: 100%;
}

/* Show tile — date block + venue side-by-side */
.home-tile-show {
    padding: var(--space-3);
}

.home-tile-show-date {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-width: 56px;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    background-color: rgba(0, 0, 0, 0.18);
    line-height: 1;
}

.home-tile-show-month {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.home-tile-show-day {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    margin-top: 2px;
    font-variant-numeric: tabular-nums;
}

.home-tile-show-info {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    justify-content: center;
    min-width: 0;
}

/* Booking tile — single CTA-style row */
.home-tile-booking .home-tile-link {
    flex-direction: column;
    justify-content: center;
}

.home-tile-arrow {
    font-size: var(--text-lg);
    margin-top: var(--space-1);
}

/* Newsletter tile — eyebrow + title + form */
.home-tile-newsletter {
    padding: var(--space-4);
    justify-content: center;
}

.home-tile-newsletter .newsletter-signup {
    max-width: 100%;
    margin-top: var(--space-3);
}

.home-tile-newsletter .newsletter-signup-label {
    display: none;
}

/* Custom tile — markdown body styling */
.home-tile-custom {
    padding: var(--space-4);
    gap: var(--space-3);
}

.home-tile-body-prose {
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
}

.home-tile-body-prose p { margin: 0 0 var(--space-2); }
.home-tile-body-prose p:last-child { margin-bottom: 0; }
.home-tile-body-prose ul, .home-tile-body-prose ol {
    margin: 0 0 var(--space-2);
    padding-left: var(--space-5);
    list-style: revert;
}

.home-tile-media-img {
    width: 100%;
    border-radius: var(--radius-sm);
    display: block;
}

/* Immersive hero tile (PP4) — non-default; admin creates a tile with
   HomeTileType.ImmersiveHero to enable. Typically spans the full grid
   width. MediaUrl supplies the background image. */

.home-tile-immersive {
    padding: 0;
    min-height: 380px;
}

/* The background layer: full-bleed image + subtle Ken Burns drift.
   --hero-bg is set inline by the renderer when MediaUrl is present;
   falls back to a gradient derived from brand colors when absent. */
.home-tile-immersive-bg {
    position: absolute;
    inset: 0;
    background-image: var(--hero-bg,
        linear-gradient(135deg, var(--color-charcoal) 0%, #302d28 100%));
    background-size: cover;
    background-position: center 30%;
    animation: hero-ken-burns 24s ease-in-out infinite alternate;
    z-index: 0;
}

/* Dark vignette over the image so text is legible at any image brightness */
.home-tile-immersive-bg::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to bottom,
        rgba(28, 26, 23, 0.08) 0%,
        rgba(28, 26, 23, 0.62) 65%,
        rgba(28, 26, 23, 0.82) 100%
    );
}

@keyframes hero-ken-burns {
    from { transform: scale(1.0) translate(0, 0); }
    to   { transform: scale(1.07) translate(-1%, -1%); }
}

/* Content stacks in the flex flow at z-index 1 — above the absolute bg */
.home-tile-immersive-content {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    flex: 1;
    padding: var(--space-8) var(--space-6) var(--space-6);
    color: var(--color-cream);
}

.home-tile-immersive-eyebrow {
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-cream);
    opacity: 0.75;
    margin: 0 0 var(--space-2);
    animation: hero-text-fade-up 0.55s var(--ease-out) 0.1s both;
}

.home-tile-immersive-headline {
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 4.5vw, 3.25rem);
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -0.03em;
    color: var(--color-cream);
    margin: 0 0 var(--space-5);
    animation: hero-text-fade-up 0.55s var(--ease-out) 0.22s both;
}

.home-tile-immersive-actions {
    margin-top: 0;
    animation: hero-text-fade-up 0.55s var(--ease-out) 0.38s both;
}

@keyframes hero-text-fade-up {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .home-tile-immersive-bg { animation: none; }
    .home-tile-immersive-eyebrow,
    .home-tile-immersive-headline,
    .home-tile-immersive-actions { animation: none; }
}

/* ---- Visualizer Showcase tile: silent, timeline-driven viz hero ---- */
.home-tile-showcase {
    padding: 0;
    container-type: inline-size;   /* headline scales to the tile's own width via cqi */
    min-height: clamp(18rem, 38vw, 26rem);
    overflow: hidden;
}

/* Fills the tile wrapper; the canvas sits behind a legibility scrim + text. */
.showcase-tile {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    background: linear-gradient(135deg, var(--color-charcoal) 0%, #302d28 100%);
}

.showcase-tile-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    z-index: 0;
}

/* Dark scrim under the text, over the canvas — keeps the overlay legible
   regardless of how bright the visualizer gets. */
.showcase-tile-scrim {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(
        to bottom,
        rgba(28, 26, 23, 0.05) 0%,
        rgba(28, 26, 23, 0.55) 62%,
        rgba(28, 26, 23, 0.82) 100%
    );
}

.showcase-tile-overlay {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    flex: 1;
    padding: var(--space-8) var(--space-6) var(--space-6);
    color: var(--color-cream);
}

.showcase-tile-eyebrow {
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-cream);
    opacity: 0.78;
    margin: 0 0 var(--space-2);
}

.showcase-tile-headline {
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 8cqi, 3.25rem);
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -0.03em;
    color: var(--color-cream);
    margin: 0 0 var(--space-5);
    text-shadow: 0 2px 18px rgba(0, 0, 0, 0.45);
}

.showcase-tile-cta {
    align-self: flex-start;
}

/* Poster fallback (timeline missing / no WebGL / reduced-motion): gradient
   surface, no canvas — the overlay text still reads. */
.showcase-tile-poster {
    background: radial-gradient(120% 100% at 50% 0%, #3a3630 0%, var(--color-charcoal) 70%);
}

/* A tile that opted into the layered compositor renders full-bleed: zero
   padding, positioned so the absolute .tile-layer-host fills the whole tile. */
.home-tile-layered {
    padding: 0;
    position: relative;
    overflow: hidden;
    min-height: 15rem;   /* was 240px — rem scales with zoom */
}

/* ---- Layered tiles: an N-layer composite (canvas runs + DOM text layers) ---- */
/* The host is the positioned stacking context the compositor fills with run
   canvases and absolutely-positioned text layers, each z-indexed by stack order. */
.tile-layer-host {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: var(--color-charcoal);
    /* Query container so tile text (headline) sizes relative to THIS TILE, not the viewport — a
       small mobile tile gets small text instead of staying humongous (see .tile-layer-text--headline). */
    container-type: inline-size;
}

/* Full-bleed canvas runs only. Cell-placed canvases are sized inline by the
   compositor (grid items), so they must NOT inherit absolute positioning. */
.tile-layer-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
}

/* DOM text layers. Base = TYPOGRAPHY only (color/shadow), so a grid-placed text
   layer flows in its cell. Positioning is applied by modifier classes:
   --fullbleed (fills the tile, bottom-aligned overlay) vs grid placement
   (compositor sets grid-area + self-align inline). */
.tile-layer-text {
    margin: 0;
    color: var(--color-cream);
    text-decoration: none;
    text-shadow: 0 2px 18px rgba(0, 0, 0, 0.45);
}

/* ----- Carousel layer (auto-advancing slides; fade or slide) ----- */
.tile-carousel { position: absolute; inset: 0; overflow: hidden; --car-tms: 600ms; }
.tile-carousel-track { width: 100%; height: 100%; }
.tile-carousel-slide {
    display: flex; align-items: flex-end;
    background-size: cover; background-position: center;
    color: var(--color-cream); text-decoration: none;
}
/* Fade: slides stacked, only the active one visible. */
.tile-carousel--fade .tile-carousel-slide {
    position: absolute; inset: 0; opacity: 0;
    transition: opacity var(--car-tms) ease;
}
.tile-carousel--fade .tile-carousel-slide.is-active { opacity: 1; }
/* Slide: a flex track translated by the active index. */
.tile-carousel--slide .tile-carousel-track {
    display: flex; transition: transform var(--car-tms) ease;
}
.tile-carousel--slide .tile-carousel-slide { flex: 0 0 100%; height: 100%; }
.tile-carousel-caption {
    padding: var(--space-3); width: 100%;
    background: linear-gradient(to top, rgba(0,0,0,0.55), transparent);
    text-shadow: 0 2px 18px rgba(0,0,0,0.45);
}
.tile-carousel-heading { margin: 0; font-size: 1.2rem; }
.tile-carousel-body { margin: var(--space-1) 0 0; font-size: 0.9rem; }
.tile-carousel-cta { display: inline-block; margin-top: var(--space-2); font-weight: 700; text-decoration: underline; }
.tile-carousel-arrow {
    position: absolute; top: 50%; transform: translateY(-50%);
    border: 0; background: rgba(0,0,0,0.35); color: var(--color-cream);
    width: 2rem; height: 2rem; border-radius: var(--radius-full);
    font-size: 1.2rem; line-height: 1; cursor: pointer; z-index: 2;
}
.tile-carousel-prev { left: var(--space-2); }
.tile-carousel-next { right: var(--space-2); }
.tile-carousel-dots {
    position: absolute; bottom: var(--space-2); left: 0; right: 0;
    display: flex; gap: 6px; justify-content: center; z-index: 2;
}
.tile-carousel-dot {
    width: 8px; height: 8px; padding: 0; border: 0; border-radius: var(--radius-full);
    background: rgba(255,255,255,0.45); cursor: pointer;
}
.tile-carousel-dot.is-active { background: var(--color-cream); }

.tile-layer-text--eyebrow {
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    opacity: 0.8;
}

.tile-layer-text--headline {
    font-family: var(--font-display);
    /* cqi = 1% of the TILE's inline size (the .tile-layer-host query container), so the headline
       scales with the tile — big on a wide desktop tile, small on a narrow mobile tile — instead of
       riding the viewport width (vw) and staying humongous when the tile shrinks. */
    font-size: clamp(1.1rem, 12cqi, 2.75rem);
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -0.03em;
}

.tile-layer-text--body {
    font-size: clamp(0.85rem, 4.5cqi, var(--text-md));
    line-height: 1.4;
}

/* Custom-size text — the font-size is applied inline by the compositor (Style=custom + Size). */
.tile-layer-text--custom {
    font-weight: 700;
    line-height: 1.15;
}

/* CTA = a button (works as a grid item or a full-bleed-anchored button). */
.tile-layer-text--cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: fit-content;
    padding: var(--space-3) var(--space-5);
    background: var(--color-amber, #d9933a);
    color: #fff;
    font-weight: 700;
    border-radius: var(--radius-pill, 999px);
    text-shadow: none;
    pointer-events: auto;
}

/* Full-bleed single text overlay: fill the tile, bottom-align (the legacy look). */
.tile-layer-text--fullbleed:not(.tile-layer-text--cta) {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: var(--space-6);
    pointer-events: none;
}

/* Full-bleed CTA: anchor the button at the bottom-left rather than fill. */
.tile-layer-text--fullbleed.tile-layer-text--cta {
    position: absolute;
    inset: auto auto var(--space-6) var(--space-6);
}

/* ---- Layer stack editor (preset creator + tile admin) ---- */
.layer-stack-add {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

/* Each reorderable item = a grip handle + the row. Only the grip starts a drag,
   so the row's sliders/selects work normally. */
.layer-row-wrap {
    list-style: none;
    display: flex;
    align-items: stretch;
    gap: var(--space-1);
    margin-bottom: var(--space-2);
}

.reorder-handle {
    display: flex;
    align-items: center;
    padding: 0 var(--space-1);
    cursor: grab;
    opacity: 0.5;
    user-select: none;
    font-size: var(--text-lg);
}
.reorder-handle:active { cursor: grabbing; }

.layer-row {
    flex: 1;
    border: 1px solid var(--color-border, rgba(0, 0, 0, 0.12));
    border-radius: var(--radius-md, 8px);
    background: var(--color-surface, #fff);
}

/* ----- Grid layer: compact summary row + pop-out editor modal ----- */
.layer-grid-summary {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-2); padding: var(--space-2) var(--space-3);
}
.grid-modal-backdrop {
    position: fixed; inset: 0; z-index: 1000;
    background: rgba(0, 0, 0, 0.5);
    display: flex; align-items: center; justify-content: center;
    padding: var(--space-4);
}
.grid-modal {
    background: var(--color-cream, #fff); color: var(--color-charcoal);
    border-radius: var(--radius-lg); width: min(720px, 100%); max-height: 90vh;
    display: flex; flex-direction: column; overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
}
.grid-modal-head, .grid-modal-foot {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
}
.grid-modal-head { justify-content: space-between; border-bottom: var(--border-thin); }
.grid-modal-foot { justify-content: flex-end; border-top: var(--border-thin); }
.grid-modal-title { margin: 0; font-size: var(--text-md); }
.grid-modal-close { border: 0; background: transparent; font-size: var(--text-md); cursor: pointer; color: inherit; }
.grid-modal-body { padding: var(--space-4); overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-4); }
.grid-modal-section { display: flex; flex-direction: column; gap: var(--space-2); }
.grid-modal-section-title {
    margin: 0; font-size: var(--admin-text-section); text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--color-charcoal-muted); border-bottom: var(--border-thin); padding-bottom: var(--space-1);
}
.grid-modal-row { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: flex-end; }
.grid-modal-row .admin-field { margin: 0; }
.grid-modal-presets { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.grid-modal-advanced { margin-top: var(--space-1); }
.grid-modal-advanced summary { cursor: pointer; font-size: var(--admin-text-help); color: var(--color-accent); }

/* ===== Reusable admin control family (AdminControls-Spec-v1) ===== */

/* DimensionInput: number + unit */
.dim-input { display: inline-flex; gap: var(--admin-gap); align-items: center; flex-wrap: wrap; }
/* Wide enough to read a 3–4 digit value and a full unit name ("vmin"); the admin-input-narrowest
   80px cap is removed here so the value is never clipped (was the "can't see the padding values" bug). */
.dim-input-num { width: 4.5rem; max-width: none; flex: 0 0 auto; }
.dim-input-unit { width: 4.75rem; max-width: none; flex: 0 0 auto; }

/* GridPlacementField — compact label|control layout for grid-cell placement (every grid-child layer). */
.grid-place {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: var(--admin-gap);
    padding: var(--admin-pad-y) 0;
}
.grid-place-label {
    font-size: var(--admin-text-label); font-weight: 700; letter-spacing: 0.05em;
    text-transform: uppercase; color: var(--color-charcoal-muted);
}
.grid-place-pair { display: inline-flex; align-items: center; gap: var(--admin-gap); flex-wrap: wrap; }
.grid-place-num { width: 3.25rem; max-width: none; }
.grid-place-x { font-size: var(--admin-text-help); color: var(--color-charcoal-muted); }

/* FocalField — click-to-set focal point + zoom for a tile layer (generalizes the members focal editor). */
.focal-field { display: flex; gap: var(--admin-gap); align-items: flex-start; flex-wrap: wrap; }
.focal-field-frame {
    position: relative; width: 160px; aspect-ratio: 4 / 3; overflow: hidden;
    border-radius: var(--admin-radius); border: var(--border-thin); cursor: crosshair;
    background: rgba(0, 0, 0, 0.06); flex-shrink: 0;
}
.focal-field-image {
    width: 100%; height: 100%; object-fit: cover;
    object-position: var(--focal-x, 50%) var(--focal-y, 50%);
    transform: scale(var(--focal-scale, 1)); transform-origin: var(--focal-x, 50%) var(--focal-y, 50%);
    user-select: none; pointer-events: none; display: block;
}
.focal-field-placeholder {
    display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;
    color: var(--color-charcoal-muted); font-size: var(--admin-text-help);
    text-transform: uppercase; letter-spacing: 0.08em;
}
.focal-field-pin {
    position: absolute; left: var(--focal-x, 50%); top: var(--focal-y, 50%);
    width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%;
    border: 2px solid #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5); pointer-events: none;
}
.focal-field-controls { display: flex; flex-direction: column; gap: var(--admin-gap); }

/* ColorField: picker + opacity + theme swatch pulldown */
.color-field { display: inline-flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.color-field-picker { width: 2.5rem; height: 2rem; padding: 0; border: var(--border-thin); border-radius: var(--radius-sm); background: none; cursor: pointer; }
.color-field-alpha { width: 6rem; }
.color-field-alpha-val { font-size: var(--admin-text-help); color: var(--color-charcoal-muted); min-width: 2.6em; }
.color-field-theme { position: relative; }
.color-field-theme-toggle { cursor: pointer; font-size: var(--admin-text-help); color: var(--color-accent); list-style: none; }
.color-field-theme[open] .color-field-swatches {
    position: absolute; z-index: 50; margin-top: var(--space-1);
    display: grid; grid-template-columns: repeat(6, 1.25rem); gap: var(--space-1);
    padding: var(--space-2); background: var(--color-cream-light);
    border: var(--border-thin); border-radius: var(--radius-md); box-shadow: var(--shadow-md, 0 6px 18px rgba(0,0,0,0.18));
}
.color-field-swatch { width: 1.25rem; height: 1.25rem; padding: 0; border: 1px solid var(--color-cream-mid); border-radius: var(--radius-sm); cursor: pointer; }
.color-field-swatch.is-active { outline: 2px solid var(--color-accent); outline-offset: 1px; }

/* SimpleAdvanced shell */
.simple-advanced { display: flex; flex-direction: column; gap: var(--space-2); }
.simple-advanced-adv { margin-top: var(--space-1); }
.simple-advanced-summary { cursor: pointer; font-size: var(--admin-text-help); color: var(--color-accent); }
.simple-advanced-body { margin-top: var(--space-2); display: flex; flex-direction: column; gap: var(--space-2); }

/* RepeaterField */
.repeater-field { display: flex; flex-direction: column; gap: var(--space-2); }
.repeater-row { display: flex; gap: var(--space-2); align-items: flex-start; }
.repeater-row-body { flex: 1 1 auto; }

/* PageLinkField */
.page-link-field { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.page-link-field > .admin-input:last-child { flex: 1 1 12rem; }

.layer-row-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
}

.layer-row-handle { cursor: grab; opacity: 0.5; user-select: none; }
.layer-row-kind { font-weight: 700; min-width: 4.5em; }
.layer-row-opacity { flex: 1; display: flex; }
.layer-row-opacity input { width: 100%; }

.layer-row-body {
    padding: var(--space-2) var(--space-3) var(--space-3);
    border-top: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.layer-pool {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11em, 1fr));
    gap: var(--space-1) var(--space-3);
    max-height: 12rem;
    overflow-y: auto;
    padding: var(--space-2);
    border: 1px solid var(--color-border, rgba(0, 0, 0, 0.1));
    border-radius: var(--radius-sm, 6px);
}

.layer-pool-item {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-sm);
}

.layer-grid-presets {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

/* A Grid layer's nested children editor — indented + ruled so the tree reads. */
.layer-row-body .layer-stack-editor {
    margin-top: var(--space-2);
    padding-left: var(--space-3);
    border-left: 2px solid var(--color-border, rgba(0, 0, 0, 0.12));
}

/* Live-preview frame for the preset creator — gives the absolutely-positioned
   .tile-layer-host a sized, positioned parent. */
.preset-preview-frame {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-md, 8px);
    overflow: hidden;
    background: var(--color-charcoal);
}

/* Admin edit-pencil overlay — appears only when an admin views the page */
.home-tile-edit-pencil {
    position: absolute;
    top: var(--space-2);
    right: var(--space-2);
    z-index: 10;
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.55);
    color: #fff !important;
    border-radius: 50%;
    font-size: 14px;
    text-decoration: none !important;
    opacity: 0.7;
    transition: opacity var(--duration-fast) var(--ease-out),
                background-color var(--duration-fast) var(--ease-out);
}

.home-tile-edit-pencil:hover {
    opacity: 1;
    background-color: var(--color-accent);
}

/* Mobile collapse — every tile spans full width, in DisplayOrder */
@media (max-width: 720px) {
    .home-hero {
        grid-template-columns: 1fr;
    }
    .home-hero > .home-tile {
        grid-column: 1 / -1 !important;
        grid-row: auto !important;
    }
}

/* --- Tagline tile --- */

.home-hero-tagline {
    grid-column: 1 / 3;
    grid-row: 1 / 2;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--space-3);
    padding: var(--space-6) var(--space-5);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    border-radius: var(--radius-lg);
    /* AI Note: min-height removed — grid-template-rows: auto + align-items: stretch
       on the container handles row sizing without risk of one tile forcing
       its neighbor into the wrong row track. */
}

.home-hero-tagline-text {
    font-family: var(--font-display);
    font-size: var(--text-4xl);
    font-weight: 800;
    line-height: 1.0;
    letter-spacing: -0.04em;
    color: var(--color-cream);
    /* Max personality on the WONK axis — this is the marquee line */
    font-variation-settings: 'WONK' 1, 'opsz' 144;
}

.home-hero-tagline p {
    font-size: var(--text-base);
    color: var(--color-cream-dark);
    line-height: var(--leading-normal);
    max-width: 40ch;
}

/* CTA buttons within the tagline tile */
.home-hero-tagline-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-2);
}

.home-cta {
    display: inline-flex;
    align-items: center;
    padding: var(--space-3) var(--space-5);
    border-radius: var(--radius-full);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.home-cta-primary {
    background-color: var(--color-accent);
    color: var(--color-white);
}

.home-cta-primary:hover {
    background-color: var(--color-accent-light);
    color: var(--color-white);
    transform: translateY(-1px);
}

.home-cta-secondary {
    background-color: transparent;
    color: var(--color-cream);
    border: 1px solid rgba(245, 240, 232, 0.4);
}

.home-cta-secondary:hover {
    background-color: rgba(245, 240, 232, 0.1);
    color: var(--color-cream);
    transform: translateY(-1px);
}

/* CTA size + shape MODIFIERS — compose with .home-cta (and -primary / -secondary) so one button
   system covers small/large and pill/rectangle instead of bespoke per-use classes. Declared after
   .home-cta so they win for the properties they set.
     .home-cta--sm / --lg : tighter / roomier
     .home-cta--rect      : rounded rectangle instead of the full pill (less "bulbous")
     .home-cta--fluid     : size scales with the tile width (cqi) — good inside visualizer tiles */
.home-cta--sm   { padding: var(--space-1) var(--space-3); font-size: var(--text-xs); }
.home-cta--lg   { padding: var(--space-4) var(--space-6); font-size: var(--text-base); }
.home-cta--rect { border-radius: var(--radius-md); }
.home-cta--fluid { padding: clamp(0.4rem, 1.6cqi, 0.8rem) clamp(0.9rem, 3.5cqi, 1.6rem); font-size: clamp(0.78rem, 2.4cqi, 0.95rem); }

/* --- Band photo tile --- */

.home-hero-photo {
    grid-column: 4 / 5;
    grid-row: 1 / 2;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background-color: var(--color-cream-deep);
    /* AI Note: min-height removed — grid stretch handles height uniformity. */
    /* GroupPhotoComposite renders an image that fills this tile */
}

.home-hero-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* --- Generic bento tile base --- */

.home-hero-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: var(--space-2);
    padding: var(--space-4);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    overflow: hidden;
    text-decoration: none;
    color: var(--color-charcoal);
    transition: transform var(--duration-mid) var(--ease-out),
                box-shadow var(--duration-mid) var(--ease-out),
                border-color var(--duration-mid) var(--ease-out);
}

/* Clickable tiles get a hover lift */
a.home-hero-tile:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
    border-color: var(--color-cream-dark);
}

/* Shared tile content */
.home-hero-tile-eyebrow {
    display: block;
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-accent);
}

.home-hero-tile-title {
    display: block;
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--color-charcoal);
    line-height: var(--leading-snug);
    font-variation-settings: 'WONK' 0;
}

.home-hero-tile-meta {
    display: block;
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    margin-top: var(--space-1);
}

.home-hero-tile-arrow {
    display: block;
    font-size: var(--text-lg);
    color: var(--color-accent);
    margin-top: var(--space-1);
    transition: transform var(--duration-fast) var(--ease-out);
}

a.home-hero-tile:hover .home-hero-tile-arrow {
    transform: translateX(4px);
}

/* --- Release tile (rich variant) --- */

.home-hero-tile-release {
    grid-column: 3 / 4;
    grid-row: 1 / 2;
}

/* Rich tiles have a horizontal cover+body split */
.home-hero-tile-rich {
    flex-direction: column;
    justify-content: flex-start;
    gap: 0;
    padding: 0;
}

.home-hero-tile-cover {
    width: 100%;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    background-color: var(--color-cream-dark);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    flex-shrink: 0;
}

.home-hero-tile-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--duration-mid) var(--ease-out);
}

a.home-hero-tile:hover .home-hero-tile-cover img {
    transform: scale(1.03);
}

.home-hero-tile-cover-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-display);
    font-size: var(--text-md);
    font-weight: 600;
    padding: var(--space-4);
    text-align: center;
}

.home-hero-tile-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    flex: 1;
}

/* --- Performance tile (rich variant) --- */

.home-hero-tile-performance {
    grid-column: 1 / 3;
    grid-row: 2 / 3;
    min-height: 200px;
}

.home-hero-tile-performance.home-hero-tile-rich {
    flex-direction: column;
}

.home-hero-tile-video {
    flex: 1;
    min-height: 160px;
    overflow: hidden;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
}

/* YouTubeEmbed fills available space */
.home-hero-tile-video iframe,
.home-hero-tile-video > * {
    width: 100%;
    height: 100%;
    border: none;
}

/* --- Shows strip tile --- */

.home-hero-tile-shows {
    grid-column: 3 / 4;
    grid-row: 2 / 3;
    flex-direction: row;
    align-items: center;
    gap: var(--space-3);
    justify-content: flex-start;
    background-color: var(--color-accent-dim);
    border-color: rgba(196, 82, 26, 0.25);
}

/* Date block — month+day display */
.home-hero-tile-shows-date {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 56px;
    padding: var(--space-2);
    background-color: var(--color-accent);
    color: var(--color-white);
    border-radius: var(--radius-md);
    text-align: center;
    line-height: 1;
}

.home-hero-tile-shows-month {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.home-hero-tile-shows-day {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 800;
    line-height: 1.1;
    font-variation-settings: 'WONK' 0;
}

.home-hero-tile-shows-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    flex: 1;
    min-width: 0;
}

/* --- Booking CTA tile --- */

.home-hero-tile-booking {
    grid-column: 4 / 5;
    grid-row: 2 / 3;
    background-color: var(--color-charcoal);
    border-color: transparent;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: var(--space-3);
    /* When .home-hero-tile-shows is absent the grid auto-places booking
       into col 4 row 2 regardless — explicit assignment keeps it stable. */
}

.home-hero-tile-booking .home-hero-tile-eyebrow {
    color: var(--color-cream-dark);
}

.home-hero-tile-booking .home-hero-tile-title {
    color: var(--color-cream);
    font-size: var(--text-xl);
    font-weight: 700;
    font-variation-settings: 'WONK' 1;
}

.home-hero-tile-booking .home-hero-tile-arrow {
    color: var(--color-accent-light);
}

a.home-hero-tile-booking:hover {
    background-color: #2A2824;
    border-color: transparent;
}

/* --- Newsletter tile (row 3, full-width slim strip) --- */

.home-hero-tile-newsletter {
    grid-column: 1 / -1;
    grid-row: 3 / 4;
    background-color: var(--surface-deep);
    color: var(--surface-deep-text);
    border-color: var(--surface-border);
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-4) var(--space-6);
    padding: var(--space-4) var(--space-5);
}

.home-hero-tile-newsletter .home-hero-tile-eyebrow {
    color: var(--surface-deep-text-muted);
    flex-shrink: 0;
}

.home-hero-tile-newsletter .home-hero-tile-title {
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--surface-deep-text);
    margin-right: auto;          /* push the signup form to the right */
    flex: 0 1 auto;
}

.home-hero-tile-newsletter .newsletter-signup {
    /* Stretch to fill remaining row space, but cap at a reasonable width */
    max-width: 460px;
    flex: 1 1 320px;
    text-align: left;
}

/* The form inside the home tile doesn't need the label — the tile's
   own title provides context. */
.home-hero-tile-newsletter .newsletter-signup-label {
    display: none;
}

/* --- Empty tile state --- */

.home-hero-tile-empty {
    opacity: 0.6;
    pointer-events: none;
}

.home-hero-tile-empty .home-hero-tile-eyebrow {
    color: var(--color-charcoal-muted);
}

.home-hero-tile-empty .home-hero-tile-title {
    color: var(--color-charcoal-muted);
    font-style: italic;
    font-size: var(--text-base);
    font-weight: 400;
}


/* =========================================================
   8. ABOUT PAGE
   ========================================================= */

/*
 * Classes: .about-members, .about-members-grid, .about-member-card,
 *          .about-member-photo, .about-member-info, .about-member-name,
 *          .about-member-role, .about-member-bio,
 *          .about-story, .about-performances, .about-performances-grid,
 *          .about-performance-card, .about-performance-title,
 *          .about-performance-meta, .about-cta, .about-cta-button,
 *          .about-cta-primary, .about-cta-secondary
 */

/* Generic section spacer for about sections — compact gap between
   the section-label and the grid below, and between sections */
.about-section,
.about-members-section {
    margin-bottom: var(--space-6);
}

.about-section:last-child,
.about-members-section:last-child {
    margin-bottom: 0;
}

/* Member grid — responsive cards */
.about-members-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
    gap: var(--space-4);
}

.about-member-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: box-shadow var(--duration-mid) var(--ease-out);
}

.about-member-card:hover {
    box-shadow: var(--shadow-md);
}

/* Photo frame — owns the aspect ratio AND `overflow: hidden` so any
   transform: scale on the inner <img> is clipped to the photo region.
   Without this wrapper, the card's overflow:hidden only clips at the
   card boundary, which sits BELOW the info text — letting a zoomed
   image visually obscure the name/instrument/bio. Mirrors the
   .admin-focal-frame on /admin/members. */
.about-member-photo-frame {
    width: 100%;
    aspect-ratio: 3 / 4;
    overflow: hidden;
    background-color: var(--color-cream-dark);
}

/* Member portrait. Focal point + zoom come from inline CSS custom
   properties (--focal-x, --focal-y, --focal-scale) set per-member in
   About.razor, edited via /admin/members. The wrapper owns the shape;
   the img just fills 100% and applies object-position + transform. */
.about-member-photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--focal-x, 50%) var(--focal-y, 50%);
    transform: scale(var(--focal-scale, 1));
    transform-origin: var(--focal-x, 50%) var(--focal-y, 50%);
    display: block;
}

.about-member-info {
    padding: var(--space-3) var(--space-4) var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.about-member-name {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    font-variation-settings: 'WONK' 0;
}

.about-member-role {
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-accent);
}

.about-member-bio {
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
    color: var(--color-charcoal-mid);
    margin-top: var(--space-2);
}

/* Performances grid — YouTube embed cards */
.about-performances-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: var(--space-5);
}

.about-performance-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: box-shadow var(--duration-mid) var(--ease-out);
}

.about-performance-card:hover {
    box-shadow: var(--shadow-md);
}

/* YouTubeEmbed inside performance card fills the top portion */
.about-performance-card > *:first-child {
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
}

.about-performance-title {
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--color-charcoal);
    padding: 0 var(--space-4);
}

.about-performance-meta {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    padding: 0 var(--space-4) var(--space-4);
}

/* Videos page — YouTube embed grid (moved from About.razor; class names updated) */
.videos-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
    gap: var(--space-6);
}

.videos-card {
    display: flex;
    flex-direction: column;
    background: var(--color-cream-light);
    border-radius: var(--radius-md);
    overflow: hidden;
    border: 1px solid var(--color-border-subtle);
    transition: box-shadow 0.15s ease;
}

.videos-card:hover {
    box-shadow: var(--shadow-md);
}

.videos-card > *:first-child {
    width: 100%;
    aspect-ratio: 16 / 9;
    display: block;
}

.videos-card-title {
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--color-charcoal);
    padding: var(--space-3) var(--space-4) var(--space-1);
}

.videos-card-meta {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    padding: 0 var(--space-4) var(--space-4);
}

/* About CTA section — pair of buttons */
.about-cta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    padding-top: var(--space-2);
    border-bottom: none !important;
    border-top: var(--border-thin);
}

.about-cta-button {
    display: inline-flex;
    align-items: center;
    padding: var(--space-3) var(--space-6);
    border-radius: var(--radius-full);
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: 600;
    text-decoration: none;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.about-cta-primary {
    background-color: var(--color-accent);
    color: var(--color-white);
}

.about-cta-primary:hover {
    background-color: var(--color-accent-light);
    color: var(--color-white);
    transform: translateY(-1px);
}

.about-cta-secondary {
    background-color: transparent;
    color: var(--color-charcoal);
    border: var(--border-mid);
}

.about-cta-secondary:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
    transform: translateY(-1px);
}

/* Story section — body paragraphs */
.about-story p + p {
    margin-top: var(--space-4);
}

.about-story p {
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    color: var(--color-charcoal-mid);
    max-width: 72ch;
}


/* =========================================================
   9. RELEASES PAGE
   ========================================================= */

/*
 * Classes: .releases-grid, .release-card, .release-cover,
 *          .release-cover-placeholder, .release-cover-placeholder-title,
 *          .release-cover-placeholder-tag, .release-info, .release-title,
 *          .release-meta, .release-meta-sep, .release-description,
 *          .release-actions, .release-action-play, .release-external-link
 *
 * TrackList component has its own internal styles — we just provide the
 * card frame it sits inside.
 */

.releases-grid {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
}

/* Each release is a horizontal card: cover art | info.
   The card now carries .tile.tile-light from markup, so background +
   text colors are guaranteed via the tile-light descendant rules.
   No more between-card border — gap on .releases-grid does that work. */
.release-card {
    display: grid;
    grid-template-columns: clamp(7.5rem, 28%, 12.5rem) 1fr;   /* fluid cover (was fixed 200px) */
    gap: var(--space-5);
    align-items: start;
}
.release-card > * { min-width: 0; }   /* grid-child overflow guard for the 1fr info column */

/* Cover art square */
.release-cover {
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background-color: var(--color-cream-dark);
    flex-shrink: 0;
    box-shadow: var(--shadow-md);
}

.release-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Placeholder when no cover art is uploaded */
.release-cover-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    padding: var(--space-5);
    text-align: center;
}

.release-cover-placeholder-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    font-variation-settings: 'WONK' 0;
}

.release-cover-placeholder-tag {
    font-size: var(--text-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-accent-light);
}

/* Release info column */
.release-info {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding-top: var(--space-2);
}

.release-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--color-charcoal);
    line-height: var(--leading-tight);
    letter-spacing: -0.02em;
    font-variation-settings: 'WONK' 0;
}

.release-meta {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
}

.release-meta-sep {
    /* Contrast fix: cream-dark (#C9C0B0) on cream-deep gave 1.46:1 (FAIL).
       charcoal-muted (#6B6660) gives 4.61:1 — passes WCAG AA. */
    color: var(--color-charcoal-muted);
}

.release-description {
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
    color: var(--color-charcoal-mid);
    max-width: 60ch;
    margin-top: var(--space-2);
}

/* "Coming soon" pre-release teaser badge */
.release-badge {
    align-self: flex-start;
    display: inline-block;
    padding: 2px 10px;
    margin-bottom: var(--space-1);
    border-radius: 999px;
    background-color: var(--color-accent);
    color: var(--color-white);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

/* Credits line (publisher / featuring) under a release's meta + description */
.release-credits {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    margin-top: var(--space-2);
}

/* Action buttons row */
.release-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-2);
}

.release-action-play {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.release-action-play:hover {
    background-color: var(--color-accent);
    transform: translateY(-1px);
}

.release-external-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    background-color: transparent;
    color: var(--color-charcoal-mid);
    font-size: var(--text-sm);
    font-weight: 600;
    border: var(--border-thin);
    border-radius: var(--radius-full);
    text-decoration: none;
    transition: border-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.release-external-link:hover {
    border-color: var(--color-accent);
    color: var(--color-accent);
    transform: translateY(-1px);
}

/* Store cross-sell CTA (PP5) — shown only when /store is public and
   release.SuppressStoreCrossSell is false. Styled as a tertiary link
   so it doesn't compete with the play / streaming-service buttons. */
.release-store-cta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-accent);
    border: 1px solid var(--color-accent);
    border-radius: var(--radius-full);
    text-decoration: none;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.release-store-cta:hover {
    background-color: var(--color-accent);
    color: var(--color-white);
    transform: translateY(-1px);
}

/* Card → detail links. The cover + title on the list page link to
   /releases/{slug}; keep them visually identical to the static versions
   (no default underline/blue) so the card still reads as a unit. */
.release-cover-link {
    display: block;
    line-height: 0;
    width: 100%;
    height: 100%;
}

.release-title-link {
    color: inherit;
    text-decoration: none;
    transition: color var(--duration-fast) var(--ease-out);
}

.release-title-link:hover {
    color: var(--color-accent);
}

/* ---- Release detail page (/releases/{slug}) ---- */
.release-detail-back {
    font-size: var(--text-sm);
    margin-bottom: var(--space-4);
}

.release-detail-back a {
    color: var(--color-charcoal-muted);
    text-decoration: none;
}

.release-detail-back a:hover {
    color: var(--color-accent);
}

/* Cover | info, like a release-card but with a larger cover. */
.release-detail-layout {
    display: grid;
    grid-template-columns: clamp(10rem, 35%, 20rem) minmax(0, 1fr);   /* fluid cover (was fixed 320px) + info overflow guard */
    gap: var(--space-7);
    align-items: start;
}

.release-detail-cover {
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background-color: var(--color-cream-dark);
    box-shadow: var(--shadow-lg);
}

.release-detail-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.release-detail-info {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.release-detail-title {
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    font-weight: 700;
    color: var(--color-charcoal);
    line-height: var(--leading-tight);
    letter-spacing: -0.02em;
    font-variation-settings: 'WONK' 0;
}

.release-detail-description {
    margin-top: var(--space-6);
    max-width: 65ch;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
    color: var(--color-charcoal-mid);
}

.release-detail-missing {
    text-align: center;
    padding: var(--space-9) 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
    color: var(--color-charcoal-mid);
}

/* Stack cover above info on narrow viewports. */
@media (max-width: 720px) {
    .release-detail-layout {
        grid-template-columns: 1fr;
        gap: var(--space-5);
    }

    .release-detail-cover {
        max-width: 320px;
    }
}


/* =========================================================
   10. PLAYLISTS PAGE
   ========================================================= */

/*
 * Classes: .playlists-grid, .playlist-card, .playlist-card-header,
 *          .playlist-card-titles, .playlist-title, .playlist-meta,
 *          .playlist-meta-sep, .playlist-card-actions, .playlist-action,
 *          .playlist-action-play, .playlist-action-queue,
 *          .playlist-notes, .playlist-tracklist, .playlist-tracklist-row,
 *          .playlist-tracklist-row-unplayable, .playlist-tracklist-num,
 *          .playlist-tracklist-titles, .playlist-tracklist-name,
 *          .playlist-tracklist-artist, .playlist-tracklist-play
 */

.playlists-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 360px), 1fr));
    gap: var(--space-6);
}

.playlist-card {
    display: flex;
    flex-direction: column;
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: box-shadow var(--duration-mid) var(--ease-out);
}

.playlist-card:hover {
    box-shadow: var(--shadow-md);
}

/* Card header: titles on left, actions on right */
.playlist-card-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-4) var(--space-2);
}

.playlist-card-titles {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.playlist-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    line-height: var(--leading-snug);
    font-variation-settings: 'WONK' 0;
}

.playlist-meta {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

.playlist-meta-sep {
    /* Contrast fix: same as release-meta-sep — cream-dark on cream-deep
       gave 1.46:1. charcoal-muted gives 4.61:1. */
    color: var(--color-charcoal-muted);
}

/* Play / Queue action buttons */
.playlist-card-actions {
    display: flex;
    gap: var(--space-2);
    flex-shrink: 0;
}

.playlist-action {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3);
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.playlist-action-play {
    background-color: var(--color-charcoal);
    color: var(--color-cream);
}

.playlist-action-play:hover {
    background-color: var(--color-accent);
    transform: translateY(-1px);
}

.playlist-action-queue {
    background-color: transparent;
    color: var(--color-charcoal-mid);
    border: var(--border-thin);
}

.playlist-action-queue:hover {
    border-color: var(--color-charcoal);
    color: var(--color-charcoal);
    transform: translateY(-1px);
}

/* Optional notes paragraph */
.playlist-notes {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    line-height: var(--leading-relaxed);
    padding: 0 var(--space-5) var(--space-3);
    font-style: italic;
}

/* Tracklist — ordered list of songs */
.playlist-tracklist {
    display: flex;
    flex-direction: column;
    border-top: var(--border-thin);
    margin-top: var(--space-2);
    list-style: none;
    padding: 0;
}

.playlist-tracklist-row {
    display: grid;
    grid-template-columns: 28px 1fr 28px;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    border-bottom: 1px solid rgba(0, 0, 0, 0.04);
    transition: background-color var(--duration-fast) var(--ease-out);
}

.playlist-tracklist-row:last-child {
    border-bottom: none;
}

.playlist-tracklist-row:hover {
    background-color: var(--color-cream);
}

.playlist-tracklist-row-unplayable {
    opacity: 0.5;
}

.playlist-tracklist-num {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.playlist-tracklist-titles {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.playlist-tracklist-name {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-charcoal);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.playlist-tracklist-artist {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Per-row play button */
.playlist-tracklist-play {
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: transparent;
    border: none;
    border-radius: 50%;
    color: var(--color-charcoal-muted);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.playlist-tracklist-play:hover {
    background-color: var(--color-accent);
    color: var(--color-white);
}


/* =========================================================
   11. SHOWS PAGE
   ========================================================= */

/*
 * Classes: .shows-list, .show-card, .show-card-date,
 *          .show-card-date-month, .show-card-date-day, .show-card-date-year,
 *          .show-card-info, .show-card-title, .show-card-venue,
 *          .show-card-city, .show-card-time, .show-card-notes,
 *          .show-card-ticket
 *
 * Design intent: a calendar-list hybrid. Big date badge on the left,
 * venue info in the center, ticket CTA on the right.
 */

.shows-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.show-card {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) auto;   /* minmax(0,..) lets the info column shrink (overflow guard) */
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-5);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    transition: box-shadow var(--duration-mid) var(--ease-out),
                border-color var(--duration-mid) var(--ease-out);
}

.show-card:hover {
    box-shadow: var(--shadow-sm);
    border-color: var(--color-cream-dark);
}

/* Date badge — tight calendar block */
.show-card-date {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    background-color: var(--color-accent);
    color: var(--color-white);
    border-radius: var(--radius-md);
    text-align: center;
    flex-shrink: 0;
    line-height: 1;
    gap: 2px;
}

.show-card-date-month {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.show-card-date-day {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 800;
    line-height: 1;
    font-variation-settings: 'WONK' 0;
}

.show-card-date-year {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    /* Contrast fix: opacity 0.8 reduced white-on-accent to ~3.50:1 (FAIL for
       11px text). Full white gives 4.60:1 — just passes WCAG AA. */
    color: var(--color-white);
}

/* Venue info column */
.show-card-info {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.show-card-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    line-height: var(--leading-snug);
    font-variation-settings: 'WONK' 0;
}

.show-card-venue {
    font-size: var(--text-base);
    color: var(--color-charcoal-mid);
}

.show-card-city {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
}

.show-card-time {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    font-style: italic;
}

.show-card-notes {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    margin-top: var(--space-1);
}

/* Ticket CTA */
.show-card-ticket {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    padding: var(--space-2) var(--space-4);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.02em;
    border-radius: var(--radius-full);
    text-decoration: none;
    white-space: nowrap;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.show-card-ticket:hover {
    background-color: var(--color-accent);
    color: var(--color-white);
    transform: translateY(-1px);
}

/* Actions column: ticket + add-to-calendar + directions, stacked on the right
   of the card. Secondary actions are outline pills so the ticket CTA stays
   dominant. */
.show-card-actions {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    align-items: stretch;
}

.show-card-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-charcoal-mid);
    border: var(--border-thin);
    border-radius: var(--radius-full);
    text-decoration: none;
    white-space: nowrap;
    transition: border-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.show-card-action:hover {
    border-color: var(--color-accent);
    color: var(--color-accent);
}

/* Past-shows archive — a lightweight disclosure below the upcoming list. */
.shows-archive {
    margin-top: var(--space-7);
}

.shows-archive-toggle {
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-charcoal-muted);
    padding: var(--space-2) 0;
}

.shows-archive-toggle:hover {
    color: var(--color-accent);
}

.shows-archive-list {
    list-style: none;
    margin: var(--space-3) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.shows-archive-row {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-2) 0;
    border-top: var(--border-thin);
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
}

.shows-archive-date {
    flex-shrink: 0;
    width: 8.5rem;
    color: var(--color-charcoal-muted);
    font-variant-numeric: tabular-nums;
}

.shows-archive-where {
    font-weight: 600;
    color: var(--color-charcoal);
}

/* Show countdown badge (shows within 7 days) */
.show-card-countdown {
    display: inline-block;
    margin-top: var(--space-2);
    padding: 2px 6px;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    background-color: var(--color-amber, #d97706);
    color: var(--color-white);
    border-radius: var(--radius-sm);
}

.show-card-countdown--tonight {
    background-color: var(--color-accent);
    animation: countdown-pulse 1.5s ease-in-out infinite;
}

@keyframes countdown-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.7; }
}

@media (prefers-reduced-motion: reduce) {
    .show-card-countdown--tonight {
        animation: none;
    }
}


/* =========================================================
   12. PRESS / EPK PAGE
   ========================================================= */

/*
 * Classes: .press-page (modifier on .public-page), .press-section,
 *          .press-facts, .press-facts-list, .press-facts-row,
 *          .press-bio-short, .press-bio-long, .press-section-lead,
 *          .press-photos-grid, .press-photo, .press-photo-link,
 *          .press-releases-list, .press-releases-row, .press-releases-cover,
 *          .press-releases-info, .press-releases-title, .press-releases-meta,
 *          .press-shows-list, .press-tech, .press-quotes, .press-empty
 *
 * An EPK is a reference document; layout prioritizes scannability.
 */

/* press-section: each section is its own .tile.tile-light now, so no
   between-section horizontal-rule borders here — gap between tiles
   does the work. Just space them out vertically. */
.press-section {
    margin-bottom: var(--space-4);
}

.press-section:last-child {
    margin-bottom: 0;
}

/* .press-section-title is retired in favor of .tile-eyebrow. The class
   is left styled minimally in case any stale markup references it. */
.press-section-title {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin-bottom: var(--space-3);
    display: block;
    /* Color inherited from parent tile via the tile-* descendant rules */
}

.press-section-lead {
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
    margin-bottom: var(--space-4);
    /* Color inherited from parent tile's muted token */
}

.press-section-lead a {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* At-a-glance fact box — definition list */
.press-facts-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: var(--border-thin);
    border-radius: var(--radius-md);
    overflow: hidden;
    max-width: 480px;
}

.press-facts-row {
    display: grid;
    grid-template-columns: 120px 1fr;
    align-items: baseline;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-5);
    border-bottom: var(--border-thin);
    background-color: var(--color-cream-deep);
}

.press-facts-row:last-child {
    border-bottom: none;
}

.press-facts-row dt {
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-charcoal-muted);
}

.press-facts-row dd {
    font-size: var(--text-base);
    color: var(--color-charcoal);
}

/* Bio text */
.press-bio-short {
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    color: var(--color-charcoal-mid);
    max-width: 72ch;
    font-style: italic;
    border-left: 3px solid var(--color-accent);
    padding-left: var(--space-4);
    margin-left: 0;
}

.press-bio-long {
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
    color: var(--color-charcoal-mid);
    max-width: 72ch;
}

/* Markdown output within press-bio-long / press-tech / press-quotes */
.press-bio-long p,
.press-tech p,
.press-quotes p {
    margin-bottom: var(--space-4);
}

.press-bio-long blockquote,
.press-tech blockquote,
.press-quotes blockquote {
    border-left: 3px solid var(--color-accent);
    padding-left: var(--space-5);
    margin: var(--space-5) 0;
    color: var(--color-charcoal-mid);
    font-style: italic;
}

.press-bio-long ul,
.press-tech ul,
.press-quotes ul {
    list-style: disc;
    padding-left: var(--space-6);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-top: var(--space-3);
}

/* Press photos grid */
.press-photos-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
    gap: var(--space-4);
}

.press-photo {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.press-photo-link {
    display: block;
    /* No fixed aspect-ratio — images render at their natural proportions.
       overflow: hidden kept to clip the hover-scale animation so the image
       doesn't bleed into adjacent grid cells. */
    overflow: hidden;
    border-radius: var(--radius-md);
    border: var(--border-thin);
    transition: box-shadow var(--duration-mid) var(--ease-out);
}

.press-photo-link:hover {
    box-shadow: var(--shadow-md);
}

.press-photo-link img {
    width: 100%;
    height: auto;   /* natural aspect ratio */
    display: block; /* removes inline baseline gap */
    transition: transform var(--duration-mid) var(--ease-out);
}

.press-photo-link:hover img {
    transform: scale(1.03);
}

.press-photo figcaption {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    text-align: center;
}

/* Downloadable press-kit assets (logo pack, one-sheet, photo bundle) */
.press-downloads {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    max-width: 560px;
}

.press-download {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    text-decoration: none;
    color: var(--color-charcoal);
    transition: border-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.press-download:hover {
    border-color: var(--color-accent);
    transform: translateY(-1px);
}

.press-download-label {
    font-weight: 600;
    flex: 1 1 auto;
    min-width: 0;   /* let long file names shrink/wrap instead of overflowing the row */
}

.press-download-meta {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    font-variant-numeric: tabular-nums;
}

.press-download-arrow {
    color: var(--color-accent);
    font-weight: 700;
}

/* Releases list (compact — links to /releases for full detail) */
.press-releases-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    max-width: 560px;
}

.press-releases-row {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
}

.press-releases-cover {
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    flex-shrink: 0;
}

.press-releases-info {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.press-releases-title {
    font-weight: 600;
    font-size: var(--text-base);
    color: var(--color-charcoal);
    text-decoration: none;
}

.press-releases-title:hover {
    color: var(--color-accent);
}

.press-releases-meta {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

/* Upcoming shows (condensed list) */
.press-shows-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    font-size: var(--text-base);
    color: var(--color-charcoal-mid);
    max-width: 560px;
}

.press-shows-list li {
    padding: var(--space-2) 0;
    border-bottom: var(--border-thin);
}

.press-shows-list li:last-child {
    border-bottom: none;
}

/* Tech specs + quotes — markdown output regions */
.press-tech,
.press-quotes {
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
    color: var(--color-charcoal-mid);
    max-width: 72ch;
}

/* Empty states */
.press-empty {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    font-style: italic;
    padding: var(--space-5) 0;
}


/* =========================================================
   13. CONTACT FORM
   ========================================================= */

/*
 * Classes (ContactForm.razor): .contact-container (on .public-page),
 *   .compact-row, .form-group, .message-group, .message-box,
 *   .captcha-group, .captcha-row, .captcha-img, .captcha-input,
 *   .btn-submit, .validation-message
 *
 * The contact page wraps ContactForm in .contact-container. The form
 * itself is a server-side Blazor EditForm.
 */

.contact-container {
    /* Narrow the page for a form — 720px feels intimate */
    max-width: 720px;
}

/* Blazor EditForm renders a <form> — target it within the container */
.contact-container form {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    margin-top: var(--space-6);
}

/* Two-column row for paired fields (Name+Email, Phone+Reason) */
.compact-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-5);
}

/* Individual form group */
.form-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.form-group label {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.03em;
    color: var(--color-charcoal-mid);
    text-transform: uppercase;
}

/* All form inputs — text, email, select, number */
.form-group input,
.form-group select,
.contact-container input[type="text"],
.contact-container input[type="email"],
.contact-container select {
    width: 100%;
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-base);
    color: var(--color-charcoal);
    appearance: none;
    -webkit-appearance: none;
    transition: border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
}

.form-group input:focus,
.form-group select:focus,
.contact-container input[type="text"]:focus,
.contact-container input[type="email"]:focus,
.contact-container select:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-dim);
}

/* Message textarea */
.message-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.message-group label {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.03em;
    color: var(--color-charcoal-mid);
    text-transform: uppercase;
}

.message-box {
    width: 100%;
    min-height: 160px;
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-base);
    color: var(--color-charcoal);
    line-height: var(--leading-relaxed);
    resize: vertical;
    transition: border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
}

.message-box:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-dim);
}

/* Captcha section */
.captcha-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.captcha-row {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
}

.captcha-img {
    border-radius: var(--radius-sm);
    border: var(--border-thin);
    background-color: var(--color-white);
    display: block;
}

.captcha-input {
    width: 100px;
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-base);
    color: var(--color-charcoal);
    text-align: center;
    transition: border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
}

.captcha-input:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-dim);
}

/* Validation messages (Blazor DataAnnotationsValidator) */
.validation-message {
    font-size: var(--text-sm);
    color: #B91C1C;
}

.contact-container .validation-message {
    font-size: var(--text-xs);
    margin-top: var(--space-1);
}

/* Submit button */
.btn-submit {
    align-self: flex-start;
    padding: var(--space-3) var(--space-7);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: 600;
    letter-spacing: 0.04em;
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.btn-submit:hover:not(:disabled) {
    background-color: var(--color-accent);
    transform: translateY(-1px);
}

.btn-submit:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}


/* =========================================================
   14. PRIVACY & TERMS (PROSE PAGES)
   ========================================================= */

/*
 * Both Privacy and Terms use: .public-page > .public-page-hero
 *   then .public-page-content > .public-page-section (repeated)
 *   and .public-page-contact-card at the end.
 *
 * The shared rules in sections 6 + 13 cover most of it.
 * Additional typographic polish for prose paragraphs:
 */

.public-page-content .public-page-section p {
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
    color: var(--color-charcoal-mid);
}

.public-page-content .public-page-section p + p {
    margin-top: var(--space-4);
}

.public-page-content .public-page-section strong {
    font-weight: 700;
    color: var(--color-charcoal);
}

.public-page-content .public-page-section a {
    color: var(--color-accent);
    text-decoration: underline;
    text-decoration-color: rgba(196, 82, 26, 0.35);
    text-underline-offset: 3px;
}

.public-page-content .public-page-section a:hover {
    text-decoration-color: var(--color-accent);
}


/* =========================================================
   15. UNSUBSCRIBE PAGE
   ========================================================= */

/*
 * Classes: .unsubscribe-working, .unsubscribe-working-dot
 * Rest is .public-page-content + .newsletter-signup-feedback-error
 */

/* Loading affordance */
.unsubscribe-working {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--text-md);
    color: var(--color-charcoal-muted);
    font-style: italic;
    padding: var(--space-6) 0;
}

/* Animated dot — CSS pulse, falls back to invisible under
   prefers-reduced-motion (the text is self-explanatory alone) */
.unsubscribe-working-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    background-color: var(--color-accent);
    border-radius: 50%;
    flex-shrink: 0;
    animation: dot-pulse 1.2s ease-in-out infinite;
}

@keyframes dot-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%       { opacity: 0.4; transform: scale(0.75); }
}

@media (prefers-reduced-motion: reduce) {
    .unsubscribe-working-dot {
        animation: none;
        opacity: 0.5;
    }
}

/* Confirmation paragraphs in the unsubscribe done state */
.public-page-content p {
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
    color: var(--color-charcoal-mid);
    margin-bottom: var(--space-4);
}

.public-page-content p:last-child {
    margin-bottom: 0;
}


/* =========================================================
   16. UTILITY + ACCESSIBILITY
   ========================================================= */

/* Visually hidden — accessible but not painted */
.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;
}


/* =========================================================
   17. RESPONSIVE — MOBILE (≤ 720px) + MID (≤ 960px)
   ========================================================= */

/*
 * Mobile-first refinements. The base styles above assume a desktop
 * viewport; these overrides adapt for smaller screens.
 */

/* =========================================================
   17. RESPONSIVE — MID (≤ 960px) + MOBILE (≤ 880px) + SMALL (≤ 480px)
   ========================================================= */

/* --- Mid breakpoint (960px) --- */
@media (max-width: 960px) {

    /* Home bento: collapse to 2 columns
       Row 1: tagline (full width)
       Row 2: photo | release
       Row 3: performance (full width)
       Row 4: shows | booking
       Row 5: newsletter (full width) */
    .home-hero {
        grid-template-columns: 1fr 1fr;
        grid-template-rows: auto auto auto auto auto;
        gap: var(--space-3);
    }

    .home-hero-tagline {
        grid-column: 1 / 3;
        grid-row: 1 / 2;
    }

    .home-hero-photo {
        grid-column: 1 / 2;
        grid-row: 2 / 3;
    }

    .home-hero-tile-release {
        grid-column: 2 / 3;
        grid-row: 2 / 3;
    }

    .home-hero-tile-performance {
        grid-column: 1 / 3;
        grid-row: 3 / 4;
    }

    .home-hero-tile-shows {
        grid-column: 1 / 2;
        grid-row: 4 / 5;
        flex-direction: column;
        align-items: flex-start;
    }

    .home-hero-tile-booking {
        grid-column: 2 / 3;
        grid-row: 4 / 5;
    }

    .home-hero-tile-newsletter {
        grid-column: 1 / 3;
        grid-row: 5 / 6;
    }

    /* Release cards: same 2-column on mid */
    .release-card {
        grid-template-columns: 180px 1fr;
        gap: var(--space-5);
    }

    /* Show cards: drop the actions to their own row */
    .show-card {
        grid-template-columns: 72px 1fr;
        grid-template-rows: auto auto;
    }

    .show-card-actions {
        grid-column: 2;
        grid-row: 2;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-self: start;
        margin-top: var(--space-2);
    }
}

/* --- Mobile breakpoint (880px) — inline nav collapses, hamburger appears --- */
@media (max-width: 880px) {

    /* Reduce gutter */
    :root {
        --page-gutter: var(--space-5);
    }

    /* Keep the booking pill READABLE on narrow screens — it has no icon, so the old font-size:0
       left a blank orange rectangle. Just tighten padding; the (short) label stays visible. */
    .main-layout-header-booking {
        padding: var(--space-1) var(--space-3);
    }
}

/* --- Small mobile (≤ 640px) --- */
@media (max-width: 640px) {

    :root {
        --page-gutter: var(--space-4);
    }

    /* Home bento: single column — all tiles auto-flow, grid-row: auto on each */
    .home-hero {
        grid-template-columns: 1fr;
        grid-template-rows: none; /* let single-column flow naturally */
        gap: var(--space-3);
        padding: var(--space-4) var(--space-4) var(--space-6);
    }

    .home-hero-tagline {
        grid-column: 1;
        grid-row: auto;
        min-height: 200px;
    }

    .home-hero-tagline-text {
        font-size: var(--text-3xl);
    }

    .home-hero-photo {
        grid-column: 1;
        grid-row: auto;
        min-height: 240px;
    }

    .home-hero-tile-release,
    .home-hero-tile-performance,
    .home-hero-tile-shows,
    .home-hero-tile-booking,
    .home-hero-tile-newsletter {
        grid-column: 1;
        grid-row: auto;
    }

    /* Newsletter on small screens: stack title + form vertically */
    .home-hero-tile-newsletter {
        flex-direction: column;
        align-items: flex-start;
    }

    .public-page {
        padding: var(--space-4) var(--page-gutter) var(--space-6);
    }

    /* Release card: stack vertically */
    .release-card {
        grid-template-columns: 1fr;
    }

    .release-cover {
        max-width: 220px;
        margin: 0 auto;
    }

    /* Contact form: single column */
    .compact-row {
        grid-template-columns: 1fr;
        gap: var(--space-4);
    }

    /* Shows card: tighter */
    .show-card {
        grid-template-columns: 60px 1fr;
        gap: var(--space-3);
        padding: var(--space-4);
    }

    .show-card-date {
        width: 52px;
        height: 52px;
    }

    .show-card-date-day {
        font-size: var(--text-xl);
    }

    .show-card-actions {
        grid-column: 1 / 3;
        grid-row: 2;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-self: start;
        margin-top: var(--space-2);
    }

    /* Playlist grid: single column */
    .playlists-grid {
        grid-template-columns: 1fr;
    }

    /* About member grid: two columns on mobile */
    .about-members-grid {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-3);
    }

    /* About performances / Videos page: single column */
    .about-performances-grid,
    .videos-grid {
        grid-template-columns: 1fr;
    }

    /* Press photos: 2 columns */
    .press-photos-grid {
        grid-template-columns: 1fr 1fr;
    }

    /* Booking pill: hide entirely on small mobile — it's in the nav panel */
    .main-layout-header-actions {
        display: none;
    }

    /* Footer: stack vertically */
    .main-layout-footer {
        flex-direction: column;
        gap: var(--space-3);
        text-align: center;
    }

    /* Newsletter form: stack */
    .newsletter-signup-form {
        flex-direction: column;
    }

    .newsletter-signup-button {
        width: 100%;
        justify-content: center;
    }
}

/* Very small screens (≤ 400px) */
@media (max-width: 400px) {
    .about-members-grid {
        grid-template-columns: 1fr;
    }

    .press-photos-grid {
        grid-template-columns: 1fr;
    }

    .home-hero-tile-shows {
        flex-direction: column;
        align-items: flex-start;
    }
}


/* =========================================================
   18. FONT FACE DECLARATIONS
   (Must be in the stylesheet; @font-face isn't inherited
    from app.css because app.css.old is no longer loaded)
   ========================================================= */

/*
 * Fraunces — variable font with weight 100-900, opsz (optical size) axis,
 * and the WONK axis for personality. Used exclusively for display headings.
 * WONK 1 = maximum quirk on key headline text; WONK 0 = clean editorial.
 */
@font-face {
    font-family: 'Fraunces';
    src: url('/fonts/Fraunces.ttf') format('truetype-variations'),
         url('/fonts/Fraunces.ttf') format('truetype');
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

/*
 * Inter — body copy, UI labels, navigation. Weight 400-700 from the variable
 * source. Neutral companion to Fraunces.
 */
@font-face {
    font-family: 'Inter';
    src: url('/fonts/Inter.ttf') format('truetype');
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}


/* =========================================================
   19. LOADING SPLASH
   ========================================================= */

/*
 * Full-viewport overlay visible during WASM download.
 * JS in App.razor adds .splash-overlay-hiding on `blazor:webstarted`
 * to fade out. Background matches the cream page bg so there's no
 * color flash when the overlay lifts.
 *
 * AI Note: do NOT use a CSS timer/keyframe for hide — it fires regardless
 * of WASM readiness and exposes the un-interactive page on slow connections.
 */
.splash-overlay {
    position: fixed;
    top: 0;
    left: 0;
    /* 100% not 100vw — avoids the scrollbar-width horizontal overflow */
    width: 100%;
    height: 100dvh;
    background-color: var(--color-cream);
    z-index: 20000;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition: opacity 0.35s ease-out, visibility 0s linear 0.35s;
}

.splash-overlay-hiding {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

.splash-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-7);
}

.splash-logo {
    width: min(50vw, 300px);
    height: auto;
    animation: splash-pulse 2s ease-in-out infinite;
}

.splash-spinner {
    width: 36px;
    height: 36px;
    border: 3px solid var(--color-cream-mid);
    border-top-color: var(--color-accent);
    border-radius: 50%;
    animation: splash-spin 0.9s linear infinite;
}

@keyframes splash-spin {
    to { transform: rotate(360deg); }
}

@keyframes splash-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%       { opacity: 0.8; transform: scale(0.97); }
}

@media (prefers-reduced-motion: reduce) {
    .splash-logo      { animation: none; }
    .splash-spinner   { animation: none; border-top-color: var(--color-accent); }
}


/* =========================================================
   20. GLOBAL AUDIO PLAYER
   Fixed bottom bar — z-index 500 (Sticky App UI tier)
   ========================================================= */

/*
 * Classes: .player-bar, .player-scrubber, .player-scrubber-input,
 *          .player-scrubber-progress, .player-hud, .player-info-wrap,
 *          .player-info, .player-artwork, .player-artwork-placeholder,
 *          .player-track-name, .player-track-meta, .player-time,
 *          .player-on-deck, .player-controls, .player-right,
 *          .player-queue-count, .player-button, .player-button-primary,
 *          .player-button-active, .player-button-disabled,
 *          .player-hidden-audio
 *          Queue popup: .player-queue-popup, .player-queue-popup-expanded,
 *            .player-queue-header, .player-queue-header-title,
 *            .player-queue-header-count, .player-queue-header-spacer,
 *            .player-queue-clear, .player-queue-list,
 *            .player-queue-item, .player-queue-item-dragover,
 *            .player-queue-track-number, .player-queue-track-title,
 *            .player-queue-track-version, .player-queue-empty,
 *            .player-queue-jump, .player-queue-artwork,
 *            .player-queue-artwork-placeholder, .player-queue-remove
 *          Volume popup: .player-volume-popup, .player-volume-container,
 *            .player-volume-track, .player-volume-fill,
 *            .player-volume-handle, .player-volume-label
 *
 * AI Note: The player inherits the dark surface from the inverse token
 * family so it contrasts against the cream page background without any
 * !important overrides. It is NOT wrapped in .main-layout-container,
 * so it needs its own explicit color declarations.
 */

/* --- Main bar --- */

/* Player chrome is UI, not copy — don't let pointer drags select the track
   name / time / queue labels. */
.player-bar,
.player-queue-popup,
.player-volume-popup {
    user-select: none;
    -webkit-user-select: none;
}

.player-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 500;
    background-color: var(--player-artwork-color, var(--color-charcoal));
    transition: background-color 0.6s ease;
    color: var(--color-cream);
    border-top: 1px solid rgba(245, 240, 232, 0.12);
    box-shadow: 0 -4px 24px rgba(28, 26, 23, 0.40);
    display: flex;
    flex-direction: column;
}

/* Scrubber sits above the HUD — a thin progress stripe */
.player-scrubber {
    position: relative;
    width: 100%;
    height: 4px;
    background-color: rgba(245, 240, 232, 0.12);
    cursor: pointer;
}

/* Buffered ("loaded") stripe — a dim band showing how far the browser has
   downloaded ahead of the playhead. Rendered via --buffered-pct (inline style)
   and sits BELOW the bright fill (::before paints before ::after). */
.player-scrubber::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: var(--buffered-pct, 0%);
    background-color: rgba(245, 240, 232, 0.28);
    pointer-events: none;
    transition: width 300ms linear;
}

/* Fill rendered via CSS custom property --scrubber-pct (inline style).
   When artwork color extraction produces a light variant, use it so the
   scrubber matches the tinted bar. Falls back to the standard accent color. */
.player-scrubber::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: var(--scrubber-pct, 0%);
    background-color: var(--player-artwork-color-light, var(--color-accent));
    pointer-events: none;
    transition: width 200ms linear;
}

/* The actual <input type=range> is layered on top for mouse interaction */
.player-scrubber-input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    margin: 0;
    padding: 0;
    /* Enlarge hit area without changing visual footprint */
    touch-action: none;
}

.player-scrubber-progress {
    /* Handled by ::after pseudo-element — this div is intentionally empty */
    display: none;
}

/* HUD: left info | center controls | right extras */
.player-hud {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-5);
    min-height: 56px;
}

/* --- Track info (left) --- */

.player-info-wrap {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
}

.player-artwork {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-sm);
    object-fit: cover;
    flex-shrink: 0;
    background-color: rgba(245, 240, 232, 0.08);
}

.player-artwork-placeholder {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-sm);
    flex-shrink: 0;
    background-color: rgba(245, 240, 232, 0.08);
    /* Music-note placeholder via CSS */
    display: flex;
    align-items: center;
    justify-content: center;
}

.player-artwork-placeholder::after {
    content: '♪';
    font-size: var(--text-lg);
    color: rgba(245, 240, 232, 0.35);
}

.player-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.player-track-name {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-cream);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.player-track-meta {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-xs);
    color: rgba(245, 240, 232, 0.60);
}

.player-time {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.player-on-deck {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 20ch;
}

/* --- Playback controls (center) --- */

.player-controls {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

/* --- Right controls --- */

.player-right {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    justify-content: flex-end;
}

.player-queue-count {
    font-size: var(--text-xs);
    color: rgba(245, 240, 232, 0.50);
    white-space: nowrap;
}

/* --- Player buttons ---
   One icon-button system. Base = .player-button (36px); size modifiers
   .player-button-primary (42px play/pause) and .player-button-sm (32px, e.g.
   queue remove); state modifiers -active / -disabled. Every clickable icon in
   the player rides this, so hover / focus / disabled behave identically. */
.player-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    background: none;
    border: none;
    border-radius: var(--radius-md);
    color: rgba(245, 240, 232, 0.72);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
    flex-shrink: 0;
}

.player-button:hover {
    background-color: rgba(245, 240, 232, 0.10);
    color: var(--color-cream);
}

/* Keyboard focus — the player previously had NO focus affordance. */
.player-button:focus-visible {
    outline: 2px solid var(--color-accent-light);
    outline-offset: 2px;
    color: var(--color-cream);
}

/* Compact variant (queue remove). */
.player-button-sm {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-sm);
}

/* Primary play/pause button — larger, filled, accent on hover. */
.player-button-primary {
    width: 42px;
    height: 42px;
    background-color: rgba(245, 240, 232, 0.10);
    color: var(--color-cream);
}

.player-button-primary:hover {
    background-color: var(--color-accent);
    color: var(--color-white);
    transform: scale(1.04);
}

.player-button-primary:active {
    transform: scale(0.97);
}

/* Active state (loop on, queue open, volume open) */
.player-button-active {
    color: var(--color-accent-light);
    background-color: rgba(196, 82, 26, 0.15);
}

.player-button-active:hover {
    background-color: rgba(196, 82, 26, 0.25);
    color: var(--color-accent-light);
}

/* Disabled state */
.player-button-disabled {
    opacity: 0.3;
    cursor: not-allowed;
    pointer-events: none;
}

/* Respect reduced-motion: drop the play-button scale. */
@media (prefers-reduced-motion: reduce) {
    .player-button-primary:hover,
    .player-button-primary:active {
        transform: none;
    }
}

/* Hidden audio element — never rendered, just used for JS interop */
.player-hidden-audio {
    display: none;
}

/* --- Queue popup --- */

.player-queue-popup {
    position: fixed;
    bottom: calc(56px + 4px + var(--space-3));  /* above the player bar */
    right: var(--space-5);
    z-index: 550;
    width: 360px;
    max-height: 420px;
    overflow-y: auto;
    background-color: var(--color-charcoal);
    border: 1px solid rgba(245, 240, 232, 0.15);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-2) 0;
}

/* Wider/taller variant toggled by the expand chevron in the header (MP-P7). */
.player-queue-popup-expanded {
    width: 460px;
    max-height: min(72vh, 680px);
}

/* Queue header: "Up next" + count, then a spacer pushing Clear + expand right. */
.player-queue-header {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3) var(--space-2) var(--space-4);
    border-bottom: 1px solid rgba(245, 240, 232, 0.10);
    position: sticky;
    top: 0;
    background-color: var(--color-charcoal);
    z-index: 1;
}

.player-queue-header-title {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(245, 240, 232, 0.70);
}

.player-queue-header-count {
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    color: rgba(245, 240, 232, 0.45);
}

.player-queue-header-spacer {
    flex: 1;
}

/* Text button (not an icon) — give it horizontal padding and small type. */
.player-queue-clear {
    width: auto;
    padding: 0 var(--space-2);
    font-size: var(--text-xs);
    font-weight: 600;
    color: rgba(245, 240, 232, 0.55);
}

.player-queue-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.player-queue-item {
    display: flex;
    align-items: center;
    gap: 0;
    padding: 0;
    border-bottom: 1px solid rgba(245, 240, 232, 0.06);
    transition: background-color var(--duration-fast) var(--ease-out);
    cursor: grab;
}

.player-queue-item:last-child {
    border-bottom: none;
}

.player-queue-item:hover {
    background-color: rgba(245, 240, 232, 0.06);
}

.player-queue-item-dragover {
    background-color: rgba(196, 82, 26, 0.15);
    border-color: rgba(196, 82, 26, 0.35);
}

/* The clickable portion of the queue row */
.player-queue-jump {
    flex: 1;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: none;
    border: none;
    color: var(--color-cream);
    text-align: left;
    cursor: pointer;
    min-width: 0;
    font-family: var(--font-body);
}

/* Keyboard focus for the row-select button (sits inside the row). */
.player-queue-jump:focus-visible {
    outline: 2px solid var(--color-accent-light);
    outline-offset: -2px;
    border-radius: var(--radius-sm);
}

.player-queue-track-number {
    font-size: var(--text-xs);
    color: rgba(245, 240, 232, 0.40);
    min-width: 20px;
    text-align: right;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

.player-queue-artwork {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-sm);
    object-fit: cover;
    flex-shrink: 0;
}

.player-queue-artwork-placeholder {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-sm);
    flex-shrink: 0;
    background-color: rgba(245, 240, 232, 0.08);
}

.player-queue-track-title {
    flex: 1;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-cream);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.player-queue-track-version {
    font-size: var(--text-xs);
    color: rgba(245, 240, 232, 0.40);
    white-space: nowrap;
    flex-shrink: 0;
    margin-left: var(--space-2);
}

/* Remove button — now rides on .player-button .player-button-sm (consistent
   hover/focus/sizing with every other icon button). This rule only nudges it to
   the row's right edge and keeps it a touch dimmer at rest (per-row destructive
   action); hover/focus from .player-button brings it up. */
.player-queue-remove {
    margin-right: var(--space-2);
    color: rgba(245, 240, 232, 0.45);
}

.player-queue-empty {
    padding: var(--space-5) var(--space-5);
    font-size: var(--text-sm);
    color: rgba(245, 240, 232, 0.45);
    text-align: center;
    font-style: italic;
}

/* --- Volume popup --- */

.player-volume-popup {
    position: fixed;
    bottom: calc(56px + 4px + var(--space-3));
    right: calc(var(--space-5) + 80px);
    z-index: 550;
    background-color: var(--color-charcoal);
    border: 1px solid rgba(245, 240, 232, 0.15);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-5);
}

.player-volume-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
}

/* Vertical track — click/drag to set volume */
.player-volume-track {
    width: 6px;
    height: 120px;
    background-color: rgba(245, 240, 232, 0.15);
    border-radius: var(--radius-full);
    position: relative;
    cursor: pointer;
}

.player-volume-fill {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    /* Height driven by --volume-fill-pct inline style on the track */
    height: var(--volume-fill-pct, 100%);
    background-color: var(--color-accent);
    border-radius: var(--radius-full);
    pointer-events: none;
}

.player-volume-handle {
    position: absolute;
    left: 50%;
    /* Positioned at current volume level */
    bottom: calc(var(--volume-fill-pct, 100%) - 8px);
    transform: translateX(-50%);
    width: 14px;
    height: 14px;
    background-color: var(--color-cream);
    border-radius: 50%;
    pointer-events: none;
    box-shadow: 0 1px 4px rgba(0,0,0,0.4);
}

.player-volume-label {
    font-size: var(--text-xs);
    color: rgba(245, 240, 232, 0.60);
    font-variant-numeric: tabular-nums;
    text-align: center;
}

/* Speed toggle + A-B loop (hidden; available for future prototyping)
   Remove style="display: none" from the buttons in GlobalPlayer.razor to enable. */
.player-speed-toggle,
.player-ab-toggle {
    min-width: 40px;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    font-size: var(--text-xs);
    font-weight: 600;
}

.player-speed-label,
.player-ab-label {
    font-size: var(--text-xs);
    font-weight: 700;
}

/* Audio visualizer canvas (P3)
   Positioned absolutely inside .player-bar, behind all HUD content.
   Frequency bars rise from the bottom, reacting to the playing audio.
   JS writes pixel data; Blazor does no rendering of this element. */
.player-waveform-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 1;          /* above bar background, below HUD content */
}

/* HUD and scrubber sit above the visualizer canvas */
.player-hud {
    position: relative;
    z-index: 2;
}

.player-scrubber {
    z-index: 2;
}

/* Responsive: hide queue/volume popups on very narrow screens */
@media (max-width: 480px) {
    .player-hud {
        grid-template-columns: 1fr auto;
        padding: var(--space-2) var(--space-4);
    }

    .player-right {
        display: none;
    }

    .player-queue-popup,
    .player-volume-popup {
        right: var(--space-3);
        left: var(--space-3);
        width: auto;
    }

    .player-track-meta .player-on-deck {
        display: none;
    }
}


/* =========================================================
   20b. FULLSCREEN AUDIO VISUALIZER OVERLAY (P1a)
   Fixed full-viewport — z-index 600 (above player bar at 500)
   ========================================================= */

/*
 * Classes: .player-viz-overlay, .player-viz-canvas, .player-viz-bg-art,
 *          .player-viz-info, .player-viz-artwork, .player-viz-track,
 *          .player-viz-title, .player-viz-artist,
 *          .player-viz-controls, .player-viz-play-btn,
 *          .player-viz-close-btn
 *
 * JS drives the canvas (frequency bars + oscilloscope via Web Audio AnalyserNode).
 * Album art shown as a very subtle blurred atmosphere behind the bars.
 * Click the dark background to dismiss; Escape key also closes.
 */

.player-viz-overlay {
    position: fixed;
    inset: 0;
    z-index: 600;
    /* Very dark warm near-black — lets the colorful bars read clearly */
    background-color: rgb(8, 7, 6);
    animation: viz-overlay-in 0.22s ease;
    /* Pointer on background area hints that clicking dismisses the overlay */
    cursor: pointer;
}

@keyframes viz-overlay-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .player-viz-overlay { animation: none; }
}

/* Full-viewport canvas — JS draws bars and oscilloscope */
.player-viz-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    display: block;
}

/* Album art blurred atmospheric background */
.player-viz-bg-art {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.07;
    pointer-events: none;
    filter: blur(28px);
    transform: scale(1.12); /* overshoot to hide blur-edge artifacts */
    z-index: 0;
}

/* Track info strip — bottom-left, above canvas */
.player-viz-info {
    position: absolute;
    bottom: 76px;
    left: var(--page-gutter, 2rem);
    display: flex;
    align-items: center;
    gap: 0.875rem;
    z-index: 1;
    cursor: default;
}

.player-viz-artwork {
    width: 60px;
    height: 60px;
    object-fit: cover;
    border-radius: 4px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.70);
    flex-shrink: 0;
}

.player-viz-track {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.player-viz-title {
    font-size: var(--text-base, 1rem);
    font-weight: 600;
    color: var(--color-cream);
    text-shadow: 0 1px 10px rgba(0, 0, 0, 0.85);
    max-width: 280px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.player-viz-artist {
    font-size: var(--text-sm, 0.875rem);
    color: rgba(245, 240, 232, 0.60);
}

/* Playback controls — bottom-center */
.player-viz-controls {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: var(--space-4, 1rem);
    z-index: 1;
    cursor: default;
}

/* Primary play/pause in the viz is slightly larger than the bar version */
.player-viz-play-btn {
    width: 52px !important;
    height: 52px !important;
    border-radius: 50% !important;
}

/* Close button — top-right corner */
.player-viz-close-btn {
    position: absolute;
    top: var(--space-4, 1rem);
    right: var(--space-4, 1rem);
    z-index: 1;
    border-radius: 50% !important;
    cursor: pointer;
    background-color: rgba(245, 240, 232, 0.10) !important;
}

.player-viz-close-btn:hover {
    background-color: rgba(245, 240, 232, 0.20) !important;
}

/* Scene name label — fades in when the scene changes, top-center */
.player-viz-scene-label {
    position: absolute;
    top: var(--space-8, 2rem);
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    font-size: var(--text-sm, 0.875rem);
    color: rgba(245, 240, 232, 0.65);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    font-weight: 500;
    pointer-events: none;
    white-space: nowrap;
    opacity: 0;
}

.player-viz-scene-label.viz-label-visible {
    animation: viz-label-show 3.2s ease forwards;
}

@keyframes viz-label-show {
    0%   { opacity: 0;    }
    12%  { opacity: 0.65; }
    72%  { opacity: 0.65; }
    100% { opacity: 0;    }
}

/* Next scene button — bottom-right, mirrors the close-btn position on the left */
.player-viz-next-scene-btn {
    position: absolute;
    bottom: var(--space-4, 1rem);
    right: var(--space-4, 1rem);
    z-index: 1;
    border-radius: 50% !important;
    cursor: pointer;
    background-color: rgba(245, 240, 232, 0.10) !important;
}

.player-viz-next-scene-btn:hover {
    background-color: rgba(245, 240, 232, 0.22) !important;
}

@media (max-width: 480px) {
    .player-viz-info {
        bottom: 84px;
        left: var(--space-4, 1rem);
    }
    .player-viz-title {
        max-width: 180px;
    }
}


/* =========================================================
   21. NOTIFICATION BAR
   Fixed top — z-index 2100 (System Overlays tier)
   ========================================================= */

/*
 * Classes: .notification-bar, .notification-content, .notification-icon,
 *          .notification-message, .bar-success, .bar-error, .bar-info,
 *          .animate-slide-down
 */

.notification-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2100;
    display: flex;
    align-items: stretch;
    justify-content: center;
    padding: 0 var(--page-gutter);
    /* Bar is slim by design — it's an alert, not a dialog */
    min-height: 44px;
}

.notification-content {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-5);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    max-width: 600px;
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    box-shadow: var(--shadow-md);
}

.notification-icon {
    flex-shrink: 0;
    display: flex;
    align-items: center;
}

.notification-message {
    /* Allow message to wrap on very long strings */
    line-height: var(--leading-normal);
}

/* Status color variants */
.bar-success .notification-content {
    background-color: #15803D;
    color: #fff;
}

.bar-error .notification-content {
    background-color: #B91C1C;
    color: #fff;
}

.bar-info .notification-content {
    background-color: var(--color-charcoal);
    color: var(--color-cream);
}

/* Slide-down entry animation */
@keyframes slide-down {
    from {
        opacity: 0;
        transform: translateY(-100%);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.animate-slide-down {
    animation: slide-down 220ms var(--ease-out) forwards;
}

@media (prefers-reduced-motion: reduce) {
    .animate-slide-down {
        animation: none;
    }
}


/* =========================================================
   22. APP MODALS
   Backdrop + dialog — z-index 1000-1010 (App Modals tier)
   ========================================================= */

/*
 * Two modal systems used in the codebase:
 *   A. .app-modal-backdrop + .app-modal-dialog  (SongPortal, PlaylistPortal)
 *   B. .am-backdrop + .am-dialog  (Dashboard conversation modal)
 *
 * Both use the same visual language — semi-transparent dark backdrop,
 * raised white dialog with charcoal text.
 */

/* --- System A: app-modal --- */

.app-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background-color: rgba(28, 26, 23, 0.65);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.app-modal-dialog {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1010;
    background-color: var(--color-cream);
    color: var(--color-charcoal);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: min(90vw, 800px);
    max-height: 90dvh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

/* --- System B: am-* (dashboard activity / conversation modal) --- */

.am-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background-color: rgba(28, 26, 23, 0.65);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.am-dialog {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1010;
    background-color: var(--color-cream);
    color: var(--color-charcoal);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: min(90vw, 640px);
    max-height: 85dvh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.am-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-4) var(--space-5);
    border-bottom: var(--border-thin);
    flex-shrink: 0;
}

.am-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    margin: 0;
}

.am-btn-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--color-charcoal-muted);
    font-size: var(--text-xl);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.am-btn-close:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

.am-body {
    flex: 1;
    overflow-y: auto;
    padding: var(--space-5);
}

.am-body.conversation-mode {
    padding: var(--space-4);
}

/* GlobalModalContainer — same z-index tier */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background-color: rgba(28, 26, 23, 0.65);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    display: flex;
    align-items: center;
    justify-content: center;
}

.modal-box {
    background-color: var(--color-cream);
    color: var(--color-charcoal);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: min(90vw, 560px);
    max-height: 85dvh;
    overflow-y: auto;
    padding: var(--space-6);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}


/* =========================================================
   23. BAND PORTAL — SHARED CONTAINER + COMMON CONTROLS
   /band/* pages — authenticated BandMember routes
   ========================================================= */

/*
 * The band portal uses the legacy .admin-container pattern (predates the
 * new admin vocabulary). It inherits the cream page background via body.
 * The container just frames the content with max-width + padding.
 *
 * Classes: .admin-container, .dashboard-mode, .animate-entry,
 *          .filter-bar, .search-input, .btn-primary, .btn-tab,
 *          .btn-icon-action, .btn-header-action, .btn-header-chat,
 *          .tabs-row, .edit-section, .card-header, .card-header-actions,
 *          .user-card
 */

/* --- Page frame --- */

.admin-container {
    max-width: 1100px;
    margin: 0 auto;
    padding: var(--space-6) var(--page-gutter);
    width: 100%;
}

.admin-container.dashboard-mode {
    max-width: 1300px;
}

/* Fade-in on page entry — plays once */
.animate-entry {
    animation: animate-entry-fade 0.5s var(--ease-out) forwards;
}

@keyframes animate-entry-fade {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* --- Section header row (h2 + optional actions) --- */

.admin-container h2 {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--color-charcoal);
    margin-bottom: var(--space-5);
    font-variation-settings: 'WONK' 0;
}

/* --- Filter/search bar --- */

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-bottom: var(--space-5);
    align-items: center;
}

.search-input {
    flex: 1;
    min-width: 180px;
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-base);
    color: var(--color-charcoal);
    transition: border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
}

.search-input:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-dim);
}

/* Primary action button (was dark themed) */
.btn-primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.02em;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    text-decoration: none;
    width: auto;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.btn-primary:hover:not(.disabled) {
    background-color: var(--color-accent);
    transform: translateY(-1px);
}

.btn-primary.disabled,
.btn-primary:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
    transform: none;
    background-color: var(--color-charcoal-muted);
}

/* Small play/queue buttons inline in the attribute table */
.btn-playlist-play {
    padding: var(--space-2) var(--space-3);
    min-width: 36px;
}

/* Songs-list row actions: Original play/queue + Stem-mix play/queue.
   .song-actions gives the small gap between Play and Queue; .song-actions-stems
   sets the stem pair apart; .btn-stem prefixes a small "S" tag. */
.song-actions {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.song-actions-stems {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: var(--space-4);
}

.btn-stem {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.btn-stem-tag {
    font-weight: 700;
    font-size: 0.78em;
    line-height: 1;
}

/* --- Song/Playlist modal card chrome --- */

.user-card {
    background-color: var(--color-cream);
    color: var(--color-charcoal);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    width: 100%;
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding-bottom: var(--space-4);
    border-bottom: var(--border-thin);
}

.card-header h3 {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    margin: 0;
    font-variation-settings: 'WONK' 0;
}

.card-header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
}

.btn-icon-action {
    width: 36px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    border-radius: var(--radius-md);
    color: var(--color-charcoal-muted);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
    padding: 0;
    width: auto;
}

.btn-icon-action:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

.btn-header-action {
    color: var(--color-charcoal-muted);
}

.btn-header-chat {
    color: var(--color-charcoal-muted);
}

.btn-header-chat.active {
    color: var(--color-accent);
    background-color: var(--color-accent-dim);
}

/* --- Tabs row --- */

.tabs-row {
    display: flex;
    gap: 0;
    border-bottom: var(--border-thin);
    margin-bottom: var(--space-4);
}

.btn-tab {
    padding: var(--space-3) var(--space-5);
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;   /* overlap the parent border-bottom */
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-charcoal-muted);
    cursor: pointer;
    transition: color var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out);
    width: auto;
}

.btn-tab:hover {
    color: var(--color-charcoal);
}

.btn-tab.active {
    color: var(--color-accent);
    border-bottom-color: var(--color-accent);
    font-weight: 600;
}

.btn-tab.disabled {
    opacity: 0.4;
    cursor: not-allowed;
    pointer-events: none;
}

/* --- Edit section container --- */

.edit-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}


/* =========================================================
   24. DASHBOARD GRID
   ========================================================= */

/*
 * Classes: .dashboard-grid, .dashboard-card, .dashboard-header-row,
 *          .dashboard-title, .dashboard-controls, .dashboard-select,
 *          .activity-feed-container, .activity-row, .activity-icon,
 *          .activity-header, .actor-name, .activity-details-inline,
 *          .activity-date, .activity-empty
 */

.dashboard-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
    gap: var(--space-5);
    align-items: start;
}

/* Admin-positioned bento variant: a fixed 4-column grid so each DashboardTile's
   grid-column / grid-row start+end are meaningful. Collapses to a single
   stacked column on narrow screens (positions ignored there). */
.dashboard-grid-positioned {
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: minmax(min-content, auto);
}

.dashboard-tile-slot {
    min-width: 0;          /* allow grid children to shrink instead of overflow */
    display: flex;
}

.dashboard-tile-slot > * {
    flex: 1 1 auto;
    min-width: 0;
}

/* Fixed full-width tabbed section (Playlists / Songs) below the grid. */
.dashboard-tabs-section {
    margin-top: var(--space-5);
}

.dashboard-tabs-row {
    display: flex;
    gap: var(--space-2);
    border-bottom: var(--border-thin);
    margin-bottom: var(--space-4);
}

.dashboard-tab {
    appearance: none;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    padding: var(--space-3) var(--space-4);
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: 700;
    color: var(--color-charcoal);
    opacity: 0.7;
    cursor: pointer;
    transition: color var(--duration-fast) var(--ease-out),
                opacity var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out);
}

.dashboard-tab:hover {
    opacity: 1;
    color: var(--color-accent);
}

.dashboard-tab.active {
    opacity: 1;
    color: var(--color-accent);
    border-bottom-color: var(--color-accent);
}

.dashboard-tab:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm, 4px);
}

@media (max-width: 900px) {
    .dashboard-grid-positioned {
        grid-template-columns: 1fr;
    }
    /* Ignore admin grid coords on narrow screens — stack in DisplayOrder. */
    .dashboard-grid-positioned .dashboard-tile-slot {
        grid-column: 1 / -1 !important;
        grid-row: auto !important;
    }
}

.dashboard-card {
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    padding: var(--space-4) var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    box-shadow: var(--shadow-sm);
}

.dashboard-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}

.dashboard-title {
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: 700;
    color: var(--color-charcoal);
    letter-spacing: -0.01em;
    font-variation-settings: 'WONK' 0;
}

.dashboard-controls {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.dashboard-select {
    padding: var(--space-1) var(--space-3);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-xs);
    color: var(--color-charcoal-mid);
    cursor: pointer;
    transition: border-color var(--duration-fast) var(--ease-out);
    width: auto;
}

.dashboard-select:focus {
    outline: none;
    border-color: var(--color-accent);
}

/* Activity feed */
.activity-feed-container {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.activity-row {
    display: grid;
    grid-template-columns: 32px 1fr;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-cream-mid);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.activity-row:last-child {
    border-bottom: none;
}

.activity-row:hover {
    background-color: var(--color-cream-deep);
    border-radius: var(--radius-sm);
    margin: 0 calc(-1 * var(--space-2));
    padding: var(--space-3) var(--space-2);
}

.activity-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal-muted);
    flex-shrink: 0;
    font-size: var(--text-sm);
}

.activity-header {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.actor-name {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-charcoal);
}

.activity-details-inline {
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
    line-height: var(--leading-snug);
}

.activity-date {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    white-space: nowrap;
    margin-left: auto;
    flex-shrink: 0;
}

.activity-empty {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    font-style: italic;
    padding: var(--space-4) 0;
    text-align: center;
}

/* ---- Recent Activity rows (D5): compact two-line layout, shared by the inline
   tile and the "Show N" modal via the ActivityRow component. ---- */
.af-row {
    display: grid;
    grid-template-columns: 24px 1fr;
    gap: var(--space-2) var(--space-3);
    align-items: start;
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--color-cream-mid);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.af-row:last-child {
    border-bottom: none;
}

.af-row:hover {
    background-color: var(--color-cream-deep);
    border-radius: var(--radius-sm);
    margin: 0 calc(-1 * var(--space-2));
    padding-left: var(--space-2);
    padding-right: var(--space-2);
}

.af-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal-mid);
    flex-shrink: 0;
    margin-top: 1px;
}

.af-main {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.af-line {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-3);
}

.af-summary {
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    color: var(--color-charcoal-mid);
}

.af-actor {
    font-weight: 600;
    color: var(--color-charcoal);
}

.af-date {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    white-space: nowrap;
    flex-shrink: 0;
}

.af-preview {
    font-size: var(--text-xs);
    color: var(--color-charcoal-mid);
    line-height: var(--leading-snug);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* "Show N" activity modal: scroll the list within the viewport; the pager below
   stays visible. */
.am-body.activity-mode {
    max-height: 60vh;
    overflow-y: auto;
}

.dashboard-activity-modal-footer {
    padding-top: var(--space-2);
    border-top: 1px solid var(--color-cream-mid);
}

/* /admin/dashboard-tiles — layout preview (placeholder boxes at tile coords). */
.dashboard-tiles-preview {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-2);
    grid-auto-rows: 44px;
    margin-top: var(--space-2);
}

.dashboard-tiles-preview-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: var(--space-1);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-charcoal);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-sm, 4px);
}

.dashboard-tiles-preview-cell.is-selected {
    background-color: var(--color-accent-light);
    border-color: var(--color-accent);
}

/* To-Do tile: its lists collapse and expand one at a time, so a per-section
   pager is awkward UX. Cap the content height and scroll instead, so the tile
   never overflows the bento cell. (Replies / Songs / Playlists use PagedTileBody
   pagers; Recent Activity has its own pager + modal.) */
.todo-list-panel-content {
    max-height: 420px;
    overflow-y: auto;
}


/* =========================================================
   25. ADMIN PAGES (NEW VOCABULARY)
   /admin/* — admin-page + admin-* class family
   ========================================================= */

/*
 * Classes: .admin-page, .admin-header, .admin-title, .admin-lead,
 *          .admin-layout, .admin-list, .admin-list-new, .admin-list-item,
 *          .admin-list-item-selected, .admin-list-filter, .admin-empty,
 *          .admin-detail, .admin-detail-title, .admin-field,
 *          .admin-field-label, .admin-input, .admin-input-invalid,
 *          .admin-input-narrow, .admin-field-error, .admin-textarea,
 *          .admin-fieldset, .admin-required, .admin-checkbox,
 *          .admin-file-input, .admin-upload-status, .admin-preview,
 *          .admin-preview-cover, .admin-child-row, .admin-child-detail,
 *          .admin-message, .admin-message-ok, .admin-message-error,
 *          .admin-actions, .admin-button, .admin-button-primary,
 *          .admin-button-danger, .admin-button-confirm, .admin-button-small
 *
 * Master-detail layout: .admin-layout splits into .admin-list (narrow
 * scrollable list) and .admin-detail (wide edit panel).
 */

/* --- Page frame --- */

.admin-page {
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--space-5) var(--page-gutter) var(--space-8);
    width: 100%;
}

.admin-header {
    margin-bottom: var(--space-5);
    padding-bottom: var(--space-4);
    border-bottom: var(--border-thin);
}

.admin-title {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 700;
    color: var(--color-charcoal);
    line-height: var(--leading-tight);
    letter-spacing: -0.02em;
    font-variation-settings: 'WONK' 0;
}

.admin-lead {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    margin-top: var(--space-2);
    line-height: var(--leading-normal);
}

/* --- Master-detail split --- */

.admin-layout {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: var(--space-5);
    align-items: start;
}

/* --- List panel (left) --- */

.admin-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.admin-list-filter {
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-thin);
    background-color: var(--color-cream-deep);
}

.admin-list-filter input {
    width: 100%;
    padding: var(--space-2) var(--space-3);
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: var(--color-charcoal);
}

.admin-list-filter input:focus {
    outline: none;
    border-color: var(--color-accent);
}

/* "New" button row at the top of the list */
.admin-list-new {
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-thin);
}

.admin-list-new button,
.admin-list-new .admin-button {
    width: 100%;
    justify-content: center;
}

/* Stack of "+ New <type>" buttons (e.g. shared-components admin). */
.admin-list-new-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-thin);
}
.admin-list-new-group .admin-list-new {
    padding: var(--space-2) var(--space-3);
    border-bottom: none;
}

.admin-list-item {
    padding: var(--space-3) var(--space-4);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-charcoal-mid);
    border-bottom: 1px solid var(--color-cream-mid);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

.admin-list-item:last-child {
    border-bottom: none;
}

.admin-list-item:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

.admin-list-item-selected {
    background-color: var(--color-accent-dim);
    color: var(--color-accent);
    font-weight: 600;
    border-left: 3px solid var(--color-accent);
}

.admin-list-item-selected:hover {
    background-color: var(--color-accent-dim);
    color: var(--color-accent);
}

/* Reorderable list row: the selectable item grows, move up/down buttons sit at
   the right edge (Phase 8 WS-3 dashboard-tiles editor). */
.admin-list-row {
    display: flex;
    align-items: center;
}

.admin-list-row .admin-list-item {
    flex: 1;
    min-width: 0;
}

.admin-list-reorder {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 0 var(--space-2);
    flex-shrink: 0;
    border-bottom: 1px solid var(--color-cream-mid);
    align-self: stretch;
    justify-content: center;
}

.admin-list-row:last-child .admin-list-reorder {
    border-bottom: none;
}

.admin-button-icon {
    width: 30px;
    height: 22px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.admin-empty {
    padding: var(--space-6);
    text-align: center;
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    font-style: italic;
}

/* --- Detail panel (right) --- */

.admin-detail {
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.admin-detail-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    padding-bottom: var(--space-4);
    border-bottom: var(--border-thin);
    font-variation-settings: 'WONK' 0;
}

/* --- Form fields --- */

.admin-field {
    display: flex;
    flex-direction: column;
    gap: var(--admin-gap);
}

.admin-field-label {
    font-family: var(--font-body);
    font-size: var(--admin-text-label);
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--color-charcoal-muted);
}

.admin-required {
    color: var(--color-accent);
    margin-left: 2px;
}

.admin-input {
    width: 100%;
    min-height: var(--admin-control-h);
    padding: var(--admin-pad-y) var(--admin-pad-x);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--admin-radius);
    font-family: var(--font-body);
    font-size: var(--admin-text-control);
    line-height: 1.2;
    color: var(--color-charcoal);
    transition: border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
}

.admin-input:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-dim);
    background-color: var(--color-white);
}

.admin-input-invalid {
    border-color: #B91C1C;
}

.admin-input-narrow {
    max-width: 200px;
}

.admin-field-error {
    font-size: var(--admin-text-help);
    color: #B91C1C;
}

.admin-textarea {
    width: 100%;
    min-height: 96px;
    padding: var(--admin-pad-y) var(--admin-pad-x);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--admin-radius);
    font-family: var(--font-body);
    font-size: var(--admin-text-control);
    color: var(--color-charcoal);
    line-height: var(--leading-normal);
    resize: vertical;
    transition: border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
}

.admin-textarea:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-dim);
    background-color: var(--color-white);
}

.admin-fieldset {
    border: var(--border-thin);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* Checkbox row */
.admin-checkbox {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    cursor: pointer;
}

.admin-checkbox input[type="checkbox"] {
    width: 16px;
    height: 16px;
    border-radius: var(--radius-sm);
    border: var(--border-thin);
    accent-color: var(--color-accent);
    cursor: pointer;
    padding: 0;
    flex-shrink: 0;
    /* Restore sensible defaults that get overridden by the broad input rule */
    background: initial;
    appearance: auto;
    -webkit-appearance: auto;
}

.admin-checkbox label {
    font-size: var(--admin-text-control);
    font-weight: 500;
    color: var(--color-charcoal-mid);
    cursor: pointer;
    text-transform: none;
    letter-spacing: 0;
    opacity: 1;
}

/* Small inline chip for status callouts inside admin help text
   (e.g. "hidden from public" next to a toggle). */
.admin-pill {
    display: inline-block;
    padding: 1px var(--admin-pad-x);
    margin-left: var(--space-2);
    border-radius: 999px;
    font-size: var(--admin-text-help);
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    vertical-align: middle;
    line-height: 1.6;
}

.admin-pill-warn {
    background-color: var(--color-amber, #d4a657);
    color: white;
}

.admin-pill-ok {
    background-color: #2F6B33;
    color: white;
}

/* ====================================================================
   PublicPageGate — hidden-page UI + admin preview banner.
   Used by toggleable public pages when admin has set them hidden in
   /admin/general. Non-admins see the .public-page-gate-hidden surface
   (functions as a 404). Admins see a banner above the real content so
   they can preview before flipping the toggle on.
   ==================================================================== */
.public-page-gate-hidden {
    max-width: 640px;
    margin: var(--space-7) auto;
    padding: var(--space-6) var(--space-5);
    text-align: center;
}

.public-page-gate-hidden-title {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 700;
    color: var(--color-charcoal);
    margin: 0 0 var(--space-3);
}

.public-page-gate-hidden-lead {
    font-size: var(--text-base);
    color: var(--color-charcoal-muted);
    margin: 0 0 var(--space-5);
}

.public-page-gate-hidden-link {
    margin: 0;
    font-size: var(--text-base);
}

.public-page-gate-hidden-link a {
    color: var(--color-accent);
    text-decoration: underline;
}

.public-page-gate-admin-banner {
    margin: 0 0 var(--space-4);
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-amber, #d4a657);
    color: white;
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    font-weight: 500;
}

.public-page-gate-admin-banner strong {
    margin-right: var(--space-2);
}

.public-page-gate-admin-banner a {
    color: white;
    text-decoration: underline;
    margin-left: var(--space-2);
}

/* Admin press-photo CRUD list — used in the "Press photos" section
   of /admin/general. Each row: thumbnail + caption/order fields stack
   + delete button. */
.press-photos-admin-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.press-photos-admin-row {
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
    padding: var(--space-3);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
}

.press-photos-admin-thumb {
    width: 96px;
    height: 96px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    background-color: var(--color-cream-dark);
    flex-shrink: 0;
}

.press-photos-admin-fields {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
}

.press-photos-admin-fields .admin-field {
    margin: 0;
}

/* Press-kit asset rows reuse .press-photos-admin-row but show a filename +
   size instead of an image thumbnail. */
.press-asset-admin-fileinfo {
    width: 200px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    word-break: break-word;
}

/* Per-section "hidden from public" badge on the Press page (and any
   other page that gates content at the section level). Rendered only
   for admins; sits in the section's top-right corner. Subtler than the
   page-level admin banner — section gating is a maintenance affordance,
   not a frequent state worth shouting about. */
.press-section-hidden-badge {
    display: inline-block;
    float: right;
    padding: 1px 8px;
    border-radius: 999px;
    background-color: var(--color-amber, #d4a657);
    color: white;
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    line-height: 1.6;
    margin-left: var(--space-2);
}

/* File inputs */
.admin-file-input {
    font-family: var(--font-body);
    font-size: var(--admin-text-help);
    color: var(--color-charcoal-mid);
    cursor: pointer;
    width: auto;
    padding: 0;
    background: none;
    border: none;
}

.admin-upload-status {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    font-style: italic;
}

/* Preview images */
.admin-preview {
    margin-top: var(--space-2);
}

.admin-preview-cover {
    width: 120px;
    height: 120px;
    border-radius: var(--radius-md);
    object-fit: cover;
    border: var(--border-thin);
}

/* ====================================================================
   Focal-point + zoom editor (used on /admin/members member photos).
   Click anywhere in the frame to set the focal point; the slider scales
   the image around that point. The frame mirrors the public site's
   3:4 portrait aspect so admins see ≈ what visitors will see.

   AI Note: the frame dimensions (240 × 320) are duplicated in the
   page's @code FocalFrameWidth / FocalFrameHeight constants — when
   editing here, update those too, or click→percent math drifts.
   ==================================================================== */
.admin-focal-block {
    display: flex;
    gap: var(--space-4);
    align-items: flex-start;
    margin-top: var(--space-2);
    flex-wrap: wrap;
}

.admin-focal-frame {
    position: relative;
    width: 240px;
    aspect-ratio: 3 / 4;     /* 240 × 320, matches FocalFrameHeight constant */
    overflow: hidden;
    border-radius: var(--radius-md);
    border: var(--border-thin);
    cursor: crosshair;
    background-color: rgba(0, 0, 0, 0.05);
    user-select: none;
    flex-shrink: 0;
}

.admin-focal-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--focal-x) var(--focal-y);
    transform: scale(var(--focal-scale));
    transform-origin: var(--focal-x) var(--focal-y);
    transition: transform 0.12s ease-out;
    pointer-events: none;   /* clicks pass through to .admin-focal-frame */
    user-select: none;
}

.admin-focal-pin {
    position: absolute;
    left: var(--focal-x);
    top:  var(--focal-y);
    width: 14px;
    height: 14px;
    margin-left: -7px;
    margin-top:  -7px;
    border: 2px solid white;
    border-radius: 50%;
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.55), 0 0 6px rgba(0, 0, 0, 0.4);
    pointer-events: none;
}

.admin-focal-controls {
    flex: 1 1 220px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.admin-focal-readout {
    font-size: var(--text-sm);
    color: var(--surface-raised-text-muted);
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.admin-focal-readout code {
    background-color: rgba(0, 0, 0, 0.05);
    padding: 1px 6px;
    border-radius: 3px;
    font-size: 0.92em;
}

/* Range slider styling — relies on browser default thumb but adds enough
   chrome that the track is visible against the form background. */
.admin-range {
    -webkit-appearance: auto;   /* defeat the admin-input padding/border */
    appearance: auto;
    padding: 0;
    border: none;
    background: transparent;
    width: 100%;
}

/* Child row / nested detail within detail panel */
.admin-child-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: var(--border-thin);
}

.admin-child-row:last-child {
    border-bottom: none;
}

.admin-child-detail {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
    flex: 1;
}

/* Status messages */
.admin-message {
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    font-weight: 500;
    border: var(--border-thin);
}

.admin-message-ok {
    background-color: #D1FAE5;
    color: #065F46;
    border-color: #6EE7B7;
}

.admin-message-error {
    background-color: #FEE2E2;
    color: #991B1B;
    border-color: #FCA5A5;
}

/* --- Action buttons --- */

.admin-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    padding-top: var(--space-4);
    border-top: var(--border-thin);
    align-items: center;
}

.admin-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--admin-control-h);
    padding: var(--admin-pad-y) var(--admin-pad-x);
    font-family: var(--font-body);
    font-size: var(--admin-text-control);
    font-weight: 600;
    line-height: 1.2;
    border: var(--border-thin);
    border-radius: var(--admin-radius);
    cursor: pointer;
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal-mid);
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out);
    width: auto;
}

.admin-button:hover {
    background-color: var(--color-cream-mid);
    color: var(--color-charcoal);
}

.admin-button-primary {
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    border-color: transparent;
}

.admin-button-primary:hover {
    background-color: var(--color-accent);
    color: var(--color-white);
    border-color: transparent;
}

.admin-button-danger {
    background-color: transparent;
    color: #B91C1C;
    border-color: #FCA5A5;
}

.admin-button-danger:hover {
    background-color: #FEE2E2;
    border-color: #B91C1C;
}

.admin-button-confirm {
    background-color: #B91C1C;
    color: #fff;
    border-color: transparent;
}

.admin-button-confirm:hover {
    background-color: #991B1B;
    border-color: transparent;
}

.admin-button-small {
    min-height: 0;
    padding: 2px var(--admin-pad-x);
    font-size: var(--admin-text-label);
}

/* Responsive: collapse admin layout to single column */
@media (max-width: 880px) {
    .admin-layout {
        grid-template-columns: 1fr;
    }

    .admin-list {
        max-height: 280px;
        overflow-y: auto;
    }
}


/* =========================================================
   26. IDENTITY PAGES (Login, Register, Manage, etc.)
   ========================================================= */

/*
 * The Identity pages are mostly ASP.NET Identity-scaffolded Razor pages.
 * They use: .identity-page-container, .manage-container, .manage-sidebar,
 *   .manage-nav-link, .manage-content-area, .manage-sectioned-container,
 *   .manage-header, .login-links-row, .login-text-row, .form-check,
 *   .passkey-list, .passkey-item, .passkey-name, .recovery-code-grid,
 *   .recovery-code, .alert-box, .alert-danger, .alert-success, .alert-info,
 *   .text-danger, .text-error, .text-info, .step-header, .step-instruction,
 *   .qr-box, .two-factor-auth-button-group, .register-confirmation-message-container
 *
 * Visual tone: inherit the cream/charcoal system; these pages are rare
 * and functional — they don't need the editorial display treatment. Forms
 * just need clarity.
 */

/* --- Page containers --- */

.identity-page-container {
    display: flex;
    min-height: calc(100dvh - 40px);
    background-color: transparent;
    justify-content: center;
    padding: var(--space-6) var(--page-gutter);
    margin: 0 auto;
    gap: var(--space-7);
    width: 100%;
    max-width: 1000px;
    flex-wrap: wrap;
    align-items: flex-start;
}

/* Manage account layout — sidebar nav + content */
.manage-container {
    min-height: calc(100dvh - 40px);
    padding: var(--space-5) var(--page-gutter);
    margin: 0 auto;
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: var(--space-7);
    width: 100%;
    max-width: 1000px;
    align-items: start;
}

.manage-sidebar {
    padding-right: var(--space-4);
}

.manage-header {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    margin-bottom: var(--space-4);
    font-variation-settings: 'WONK' 0;
}

.manage-nav-link {
    display: block;
    padding: var(--space-3) var(--space-4);
    text-decoration: none;
    color: var(--color-charcoal-mid);
    border-left: 3px solid transparent;
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 500;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out);
}

.manage-nav-link:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

.manage-nav-link.active {
    border-left-color: var(--color-accent);
    color: var(--color-accent);
    font-weight: 600;
    background-color: var(--color-accent-dim);
}

.manage-sectioned-container {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}

.manage-content-area {
    padding: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.manage-content-area > .form-group,
.manage-content-area > div {
    width: 100%;
}

/* --- Form check (checkbox row for identity forms) --- */

.form-check {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: var(--space-3) 0;
}

.form-check input[type="checkbox"],
.form-check input[type="radio"] {
    width: auto;
    padding: 0;
    border: initial;
    background: initial;
    appearance: auto;
    -webkit-appearance: auto;
    accent-color: var(--color-accent);
    cursor: pointer;
}

.form-check label {
    margin-bottom: 0;
    cursor: pointer;
    font-size: var(--text-sm);
    text-transform: none;
    letter-spacing: 0;
    opacity: 1;
    color: var(--color-charcoal-mid);
}

/* --- Login links row --- */

.login-links-row {
    display: flex;
    gap: var(--space-5);
    align-items: center;
    justify-content: center;
    margin-top: var(--space-5);
    font-size: var(--text-sm);
}

.login-text-row {
    text-align: center;
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
    white-space: nowrap;
}

.login-links-row a,
.login-text-row a {
    color: var(--color-accent);
    text-decoration: none;
    font-weight: 600;
    transition: color var(--duration-fast) var(--ease-out);
}

.login-text-row a {
    margin-left: var(--space-2);
}

.login-links-row a:hover,
.login-text-row a:hover {
    color: var(--color-accent-light);
    text-decoration: underline;
}

/* --- Alert boxes --- */

.alert-box {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4);
    border: 1px solid transparent;
    border-left: 4px solid;
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    max-width: 480px;
    width: 100%;
}

.alert-box-heading {
    font-weight: 700;
    margin-bottom: var(--space-1);
}

.alert-danger {
    background-color: #FEF2F2;
    color: #991B1B;
    border-color: #FCA5A5;
    border-left-color: #B91C1C;
}

.alert-success {
    background-color: #F0FDF4;
    color: #166534;
    border-color: #86EFAC;
    border-left-color: #16A34A;
}

.alert-info {
    background-color: #EFF6FF;
    color: #1E40AF;
    border-color: #BFDBFE;
    border-left-color: #3B82F6;
}

.text-danger,
.text-error {
    color: #B91C1C;
    font-size: var(--text-sm);
}

.text-info {
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
}

/* --- Passkey list --- */

.passkey-list {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.passkey-item {
    width: 100%;
    display: grid;
    grid-template-columns: 1fr auto;
    border: var(--border-thin);
    border-radius: var(--radius-md);
    background: var(--color-cream-deep);
    gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
    align-items: center;
}

.passkey-item button {
    padding: var(--space-2) var(--space-3);
    width: auto;
}

.passkey-name {
    font-weight: 600;
    font-size: var(--text-sm);
    color: var(--color-charcoal);
}

/* --- Recovery codes grid --- */

.recovery-code-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    justify-items: center;
    background: var(--color-cream-deep);
    border: 1px dashed var(--color-cream-dark);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    gap: var(--space-4);
    padding: var(--space-4);
    max-width: 420px;
}

.recovery-code {
    font-size: var(--text-base);
    color: var(--color-charcoal);
    font-weight: 600;
}

/* --- Email confirmed --- */

.email-confirmed-group {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

/* --- Registration confirmation --- */

.register-confirmation-message-container {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-3);
}

/* --- 2FA / TOTP steps --- */

.step-header {
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: 700;
    color: var(--color-charcoal);
    border-bottom: var(--border-thin);
    padding-bottom: var(--space-3);
    margin-bottom: var(--space-3);
    font-variation-settings: 'WONK' 0;
}

.step-instruction {
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
    line-height: var(--leading-relaxed);
    margin-bottom: var(--space-4);
}

.qr-box {
    background-color: #fff;
    padding: 16px;
    width: 176px;
    height: 176px;
    border-radius: var(--radius-sm);
    display: flex;
    justify-content: center;
    align-items: center;
    border: var(--border-thin);
}

.two-factor-auth-button-group {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
}

/* --- Section separator --- */

.section-separator {
    border: none;
    border-top: var(--border-thin);
    margin: var(--space-6) 0;
    width: 100%;
}

/* --- kbd element --- */

kbd {
    background-color: var(--color-cream-deep);
    padding: 2px var(--space-2);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    color: var(--color-charcoal-mid);
    border: var(--border-thin);
    font-size: var(--text-xs);
}

/* Responsive: identity pages stack on mobile */
@media (max-width: 640px) {
    .manage-container {
        grid-template-columns: 1fr;
        padding: var(--space-4) var(--space-4);
    }

    .manage-sidebar {
        padding-right: 0;
        padding-bottom: var(--space-4);
        border-bottom: var(--border-thin);
    }
}


/* =========================================================
   27. INLINE EDIT DIALOG (Admin only)
   Native <dialog> element — z-index 2000 (System Overlays tier)
   ========================================================= */

/*
 * Classes: .inline-edit-dialog, .inline-edit-form, .inline-edit-title,
 *          .inline-edit-toolbar, .inline-edit-toolbar-btn,
 *          .inline-edit-toolbar-btn-italic, .inline-edit-toolbar-btn-code,
 *          .inline-edit-toolbar-spacer, .inline-edit-toolbar-hint,
 *          .inline-edit-textarea, .inline-edit-hint, .inline-edit-error,
 *          .inline-edit-actions, .inline-edit-btn, .inline-edit-btn-cancel,
 *          .inline-edit-btn-save
 *
 * Invoked by clicking an editable-content field (admin role).
 * Uses native <dialog> so Esc-to-close and focus-trap come for free.
 */

/* Native <dialog> element reset — browser adds a border by default */
.inline-edit-dialog[open] {
    display: flex;
    flex-direction: column;
}

.inline-edit-dialog {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 2000;
    background-color: var(--color-white);
    color: var(--color-charcoal);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: min(90vw, 600px);
    max-height: 85dvh;
    overflow: hidden;
    padding: 0;
    margin: 0;
}

/* ::backdrop is the native dialog backdrop */
.inline-edit-dialog::backdrop {
    background-color: rgba(28, 26, 23, 0.55);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.inline-edit-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-5);
    overflow-y: auto;
    flex: 1;
}

.inline-edit-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    margin: 0 0 var(--space-2);
    font-variation-settings: 'WONK' 0;
}

/* Markdown toolbar — shown only for Markdown content types */
.inline-edit-toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex-wrap: wrap;
    padding: var(--space-2) 0;
    border-bottom: var(--border-thin);
}

.inline-edit-toolbar[hidden] {
    display: none;
}

.inline-edit-toolbar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-1) var(--space-3);
    background: none;
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
    width: auto;
}

.inline-edit-toolbar-btn:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

.inline-edit-toolbar-btn-italic {
    font-style: italic;
}

.inline-edit-toolbar-btn-code {
    font-size: var(--text-xs);
}

.inline-edit-toolbar-spacer {
    flex: 1;
}

.inline-edit-toolbar-hint {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

/* Textarea */
.inline-edit-textarea {
    width: 100%;
    min-height: 140px;
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-base);
    color: var(--color-charcoal);
    line-height: var(--leading-relaxed);
    resize: vertical;
    transition: border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
}

.inline-edit-textarea:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-dim);
    background-color: var(--color-white);
}

.inline-edit-hint {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    margin-top: calc(-1 * var(--space-2));
}

.inline-edit-error {
    font-size: var(--text-sm);
    color: #B91C1C;
    padding: var(--space-3) var(--space-4);
    background-color: #FEE2E2;
    border-radius: var(--radius-sm);
    border: 1px solid #FCA5A5;
}

.inline-edit-error[hidden] {
    display: none;
}

/* Action buttons row */
.inline-edit-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
    padding-top: var(--space-3);
    border-top: var(--border-thin);
}

.inline-edit-btn {
    display: inline-flex;
    align-items: center;
    padding: var(--space-3) var(--space-5);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out);
    width: auto;
}

.inline-edit-btn-cancel {
    background-color: transparent;
    color: var(--color-charcoal-muted);
    border: var(--border-thin);
}

.inline-edit-btn-cancel:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

.inline-edit-btn-save {
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    border: none;
}

.inline-edit-btn-save:hover {
    background-color: var(--color-accent);
    color: var(--color-white);
}


/* =========================================================
   28. LEGACY / COMPATIBILITY UTILITIES
   Classes from app.css.old that are still in use
   ========================================================= */

/*
 * These classes are still referenced in active components.
 * They get the editorial skin treatment (cream/charcoal) rather
 * than the old dark theme, but the class names are preserved
 * for compatibility.
 */

/* .disabled utility — used in several band portal components */
.disabled {
    opacity: 0.45 !important;
    pointer-events: none !important;
    cursor: not-allowed !important;
}

/* .hidden utility */
.hidden {
    display: none !important;
}

/* Utility classes */
.u-flex          { display: flex; }
.u-flex-col      { display: flex; flex-direction: column; }
.u-flex-row      { display: flex; flex-direction: row; }
.u-flex-wrap     { flex-wrap: wrap; }
.u-justify-center  { justify-content: center; }
.u-justify-between { justify-content: space-between; }
.u-justify-end     { justify-content: flex-end; }
.u-align-center    { align-items: center; }
.u-align-start     { align-items: flex-start; }
.u-align-end       { align-items: flex-end; }
.u-text-center     { text-align: center; }
.u-text-right      { text-align: right; }
.u-text-muted      { opacity: 0.65; }

.u-mb-sm  { margin-bottom: 0.25rem; }
.u-mb-md  { margin-bottom: 0.5rem; }
.u-mb-lg  { margin-bottom: 1rem; }
.u-mb-xl  { margin-bottom: 1.5rem; }
.u-mt-sm  { margin-top: 0.25rem; }
.u-mt-md  { margin-top: 0.5rem; }
.u-mt-lg  { margin-top: 1rem; }
.u-mt-xl  { margin-top: 1.5rem; }
.u-ml-sm  { margin-left: 0.25rem; }
.u-ml-md  { margin-left: 0.5rem; }
.u-ml-lg  { margin-left: 1rem; }
.u-mr-sm  { margin-right: 0.25rem; }
.u-mr-md  { margin-right: 0.5rem; }
.u-mr-lg  { margin-right: 1rem; }
.u-gap-sm { gap: 0.25rem; }
.u-gap-md { gap: 0.5rem; }
.u-gap-lg { gap: 1rem; }
.u-w-full { width: 100%; }
.u-h-full { height: 100%; }
.u-hidden        { display: none !important; }
.u-inline-block  { display: inline-block; }
.u-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.u-row {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: flex-start;
}

/* Legacy button shape for band portal — reuses btn-primary above */
.btn-delete {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    background-color: #B45309;
    color: #fff;
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    width: auto;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.btn-delete:hover {
    background-color: #92400E;
}

.btn-delete-confirm {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    background-color: #B91C1C;
    color: #fff;
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    width: auto;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.btn-delete-confirm:hover {
    background-color: #991B1B;
}

/* Empty layout bar (popout pages: LyricView, SongHistoryView, etc.) */
.empty-layout-bar {
    padding: var(--space-3) var(--page-gutter);
    background-color: var(--color-cream);
    border-bottom: var(--border-thin);
    display: flex;
    align-items: center;
}

.empty-layout-home {
    display: inline-flex;
    align-items: center;
    line-height: 0;
}

.empty-layout-home img {
    height: 24px;
    width: auto;
}

/* Spacer utilities */
.spacer-y {
    margin-top: var(--space-5);
}

/* Print: hide chrome, show content */
@media print {
    .main-layout-header,
    .main-layout-footer,
    .main-layout-newsletter,
    .player-bar,
    .notification-bar,
    .site-nav-toggle-btn,
    .main-layout-header-booking,
    .splash-overlay {
        display: none !important;
    }

    .main-layout-body {
        overflow: visible !important;
    }

    body {
        background-color: #fff !important;
        color: #000 !important;
    }
}

/* Reduced motion: disable all animations */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==========================================================================
   SECTION 29 — CONVERSATION + COMMENT CONTROLS
   Controls: Conversation.razor, CommentControl.razor
   Used inside the band portal song/playlist detail modals (.am-body.conversation-mode).
   ========================================================================== */

/* Outer container — fills the .am-body area */
.conversation-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

/* Scrollable message list */
.conversation-list {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: var(--space-3) var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

/* Sticky footer: reply banner + textarea + send */
.conversation-footer {
    flex: 0 0 auto;
    border-top: var(--border-thin);
    padding: var(--space-3) var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    background-color: var(--surface-card);
}

/* "Replying to X" banner */
.replying-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    background-color: var(--color-cream);
    border-left: 3px solid var(--color-amber);
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

/* Textarea for composing a message */
.conversation-input {
    width: 100%;
    min-height: 72px;
    padding: var(--space-2);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font: var(--text-sm)/1.5 var(--font-body);
    color: var(--text-primary);
    background-color: var(--surface-page);
    resize: vertical;
}

.conversation-input:focus {
    outline: none;
    border-color: var(--color-amber);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-amber) 20%, transparent);
}

/* Send button row */
.conversation-actions {
    display: flex;
    justify-content: flex-end;
}

/* Individual comment bubble */
.comment-bubble {
    background-color: var(--surface-card);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* "Replying to …" context bar inside a bubble */
.reply-context-bar {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    background-color: var(--color-cream);
    border-left: 3px solid var(--color-charcoal);
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    color: var(--text-secondary);
    cursor: pointer;
    margin-bottom: var(--space-1);
}

.reply-line-indicator {
    width: 2px;
    align-self: stretch;
    background-color: var(--text-muted);
    border-radius: 1px;
    flex-shrink: 0;
}

.reply-content {
    flex: 1;
}

.reply-author {
    font-weight: 600;
    color: var(--text-primary);
}

.reply-icon {
    margin-right: var(--space-1);
}

.reply-preview {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.reply-full-text {
    white-space: pre-wrap;
}

/* Comment meta row */
.comment-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

.comment-info {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
}

.comment-author {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text-primary);
}

.comment-date {
    font-size: var(--text-xs);
    color: var(--text-muted);
}

/* Comment body text */
.comment-text {
    font-size: var(--text-sm);
    color: var(--text-primary);
    white-space: pre-wrap;
    line-height: 1.5;
}

/* Tiny icon button (reply arrow, dismiss) */
.btn-icon-small {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border: none;
    background: transparent;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: 13px;
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}

.btn-icon-small:hover {
    background-color: var(--color-cream);
    color: var(--text-primary);
}

/* ==========================================================================
   SECTION 30 — USER MANAGEMENT ADMIN PAGE
   Admin/UserManagement.razor — legacy vocabulary that predates .admin-page
   ========================================================================== */

/* Responsive data table */
.user-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}

.user-table th {
    text-align: left;
    padding: var(--space-2) var(--space-3);
    border-bottom: 2px solid var(--border-color);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    white-space: nowrap;
}

.user-table td {
    padding: var(--space-2) var(--space-3);
    border-bottom: var(--border-thin);
    color: var(--text-primary);
    vertical-align: middle;
}

.user-table tr:hover td {
    background-color: var(--color-cream);
}

/* Clickable ID pill that opens the user edit card */
.id-link {
    color: var(--color-amber);
    cursor: pointer;
    font-weight: 500;
    text-decoration: underline;
    text-decoration-color: transparent;
    transition: text-decoration-color var(--transition-fast);
}

.id-link:hover {
    text-decoration-color: var(--color-amber);
}

/* Modal backdrop — used in UserManagement for the edit card overlay */
/* AI Note: .app-modal-backdrop (SongPortal/PlaylistPortal) is in Section 22.
   .modal-backdrop here is UserManagement.razor's own pattern; same behavior. */
.modal-backdrop {
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.45);
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
}

/* 2-column grid for paired form fields */
.grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
    align-items: start;
}

/* Contact grid: input + checkbox toggle inline */
.grid-contact {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--space-3);
    align-items: end;
    margin-bottom: var(--space-2);
}

/* Inline checkbox + label toggle */
.toggle-box {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-primary);
    cursor: pointer;
    user-select: none;
    padding: var(--space-2) var(--space-2);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    background-color: var(--surface-card);
    white-space: nowrap;
}

.toggle-box:hover {
    background-color: var(--color-cream);
}

.toggle-box input[type="checkbox"] {
    accent-color: var(--color-amber);
    width: 15px;
    height: 15px;
    cursor: pointer;
}

/* Role checkboxes grid */
.roles-grid-compact {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-1);
}

.role-item {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-sm);
    cursor: pointer;
    user-select: none;
}

.role-item input[type="checkbox"] {
    accent-color: var(--color-amber);
}

/* Section title inside edit-section */
.edit-section-title {
    display: block;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    font-weight: 600;
    margin-bottom: var(--space-2);
}

/* Save/Cancel button row at the bottom of an edit card */
.action-buttons {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
    margin-top: var(--space-4);
    padding-top: var(--space-3);
    border-top: var(--border-thin);
}

/* Secondary button — cancel/close actions */
.btn-secondary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    background-color: transparent;
    color: var(--text-secondary);
    font-size: var(--text-sm);
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
    transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.btn-secondary:hover {
    background-color: var(--color-cream);
    border-color: var(--color-charcoal);
    color: var(--text-primary);
}

/* Small button variant (compact height) */
.btn-small {
    padding: var(--space-1) var(--space-2);
    font-size: var(--text-xs);
    line-height: 1.4;
}

/* ==========================================================================
   SECTION 31 — ACTIVITY DETAIL MODAL EXTENSIONS
   DashboardComponents/ActivityDetailModal.razor
   Extends the base .am-* vocabulary (backdrop/dialog/header/body) in Section 22
   with the content-specific sub-components.
   ========================================================================== */

/* Title + subtitle group in the modal header */
.am-title-group {
    flex: 1;
    min-width: 0;
}

.am-subtitle {
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin-top: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Content box — wraps either a comment view, diff view, or kv view */
.am-content-box {
    padding: var(--space-3) var(--space-4);
    background-color: var(--surface-page);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-3);
}

/* --- Comment view --- */
.am-comment-display {
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
}

.am-comment-icon {
    flex-shrink: 0;
    color: var(--text-muted);
    margin-top: 2px;
}

.am-comment-text {
    font-style: italic;
    color: var(--text-primary);
    margin-top: var(--space-1);
    line-height: 1.5;
}

/* --- Diff view --- */
.am-diff-grid {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.am-diff-row {
    display: grid;
    grid-template-columns: 120px 1fr auto 1fr;
    gap: var(--space-2);
    align-items: baseline;
    font-size: var(--text-sm);
}

.am-diff-label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    font-weight: 600;
}

.am-diff-old {
    color: #B91C1C;
    text-decoration: line-through;
    overflow-wrap: anywhere;
}

.am-diff-new {
    color: #15803D;
    overflow-wrap: anywhere;
}

.am-diff-arrow {
    color: var(--text-muted);
    flex-shrink: 0;
}

/* --- Key-value list view --- */
.am-kv-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.am-kv-item {
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: var(--space-2);
    font-size: var(--text-sm);
}

.am-kv-item label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    font-weight: 600;
}

/* Long-field notes block */
.am-notes-block {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: var(--border-thin);
}

.am-notes-label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    font-weight: 600;
    display: block;
    margin-bottom: var(--space-1);
}

.am-notes-text {
    font-size: var(--text-sm);
    color: var(--text-primary);
    white-space: pre-wrap;
    line-height: 1.5;
}

/* Quick reply section */
.am-reply-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.am-reply-section > label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    font-weight: 600;
}

/* Textarea inside the modal */
.am-input {
    width: 100%;
    padding: var(--space-2);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font: var(--text-sm)/1.5 var(--font-body);
    color: var(--text-primary);
    background-color: var(--surface-page);
    resize: vertical;
}

.am-input:focus {
    outline: none;
    border-color: var(--color-amber);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-amber) 20%, transparent);
}

/* Action row: Open Full Page + Post Comment */
.am-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
    margin-top: var(--space-1);
}

.am-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    font-weight: 500;
    cursor: pointer;
    border: var(--border-thin);
    transition: background-color var(--transition-fast), color var(--transition-fast);
    text-decoration: none;
}

.am-btn-primary {
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    border-color: var(--color-charcoal);
}

.am-btn-primary:hover:not(:disabled) {
    background-color: var(--color-amber);
    border-color: var(--color-amber);
    color: var(--color-charcoal);
}

.am-btn-secondary {
    background-color: transparent;
    color: var(--text-secondary);
    border-color: var(--border-color);
}

.am-btn-secondary:hover {
    background-color: var(--color-cream);
    color: var(--text-primary);
}

.am-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ==========================================================================
   SECTION 32 — DASHBOARD SUMMARY CARD INTERNALS
   DashboardSongSummary.razor, DashboardPlaylistSummary.razor,
   DashboardToDoSummary.razor, DashboardActivityFeed.razor,
   DashboardReplyList.razor
   ========================================================================== */

/* Scrollable content area inside a dashboard card */
.dashboard-content {
    overflow-y: auto;
    flex: 1 1 auto;
}

/* Sticky header row for sortable column headers */
.dashboard-grid-header {
    display: grid;
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    font-weight: 600;
    border-bottom: var(--border-thin);
    position: sticky;
    top: 0;
    background-color: var(--surface-card);
    z-index: 1;
}

.header-sortable {
    cursor: pointer;
    user-select: none;
    transition: color var(--transition-fast);
}

.header-sortable:hover {
    color: var(--text-primary);
}

/* Grid column templates */
/* Song grid: Name | Artist | Status | Actions */
.grid-cols-song {
    grid-template-columns: 2fr 1fr 80px 100px;
    gap: var(--space-2);
}

/* Playlist grid: Name | Songs | Status | Actions */
.grid-cols-playlist {
    grid-template-columns: 2fr 60px 80px 100px;
    gap: var(--space-2);
}

/* A data row in the summary grid */
.dashboard-row {
    display: grid;
    padding: var(--space-2) var(--space-3);
    align-items: center;
    border-bottom: var(--border-thin);
    font-size: var(--text-sm);
    transition: background-color var(--transition-fast);
}

.dashboard-row:last-child {
    border-bottom: none;
}

.dashboard-row:hover {
    background-color: var(--color-cream);
}

/* Clickable row variant — shows pointer cursor */
.clickable-row {
    cursor: pointer;
}

/* Actions cell — icon buttons aligned right */
.action-cell {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-1);
}

/* Expansion panel below a row */
.dashboard-expand-panel {
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-cream);
    border-bottom: var(--border-thin);
    animation: animate-entry-fade 0.15s ease-out;
}

/* Compact details line inside expand panel */
.expand-details-compact {
    display: flex;
    gap: var(--space-3);
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin-bottom: var(--space-2);
}

.expand-details-separator {
    padding-left: var(--space-3);
    border-left: var(--border-thin);
}

/* Track list inside an expand panel */
.expand-track-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.expand-track-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    background-color: var(--surface-card);
}

.expand-track-info {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 1;
    min-width: 0;
}

.expand-track-actions {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex-shrink: 0;
}

/* Track metadata inside expand row */
.track-meta {
    font-size: var(--text-xs);
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.track-title {
    font-weight: 500;
    color: var(--text-primary);
}

.track-artist {
    font-size: var(--text-xs);
    color: var(--text-muted);
}

.track-seq-num {
    font-size: var(--text-xs);
    color: var(--text-muted);
    width: 20px;
    text-align: right;
    flex-shrink: 0;
}

/* Status badge — shows song or playlist status */
.status-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 600;
    background-color: var(--color-cream);
    color: var(--text-secondary);
    border: var(--border-thin);
    white-space: nowrap;
}

/* Type badge — shows audio track type (Original, Cover, Vocals, etc.) */
.type-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 7px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
    background-color: color-mix(in srgb, var(--color-amber) 12%, transparent);
    color: var(--color-charcoal);
    border: 1px solid color-mix(in srgb, var(--color-amber) 30%, transparent);
    white-space: nowrap;
    flex-shrink: 0;
}

/* Small "view-only" content area (items tab) */
.content-viewer {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

/* Dashboard card header CTA buttons */
.dashboard-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    font-size: var(--text-xs);
    font-weight: 600;
    border-radius: var(--radius-sm);
    border: none;
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.dashboard-btn-new {
    background-color: var(--color-charcoal);
    color: var(--color-cream);
}

.dashboard-btn-new:hover {
    background-color: var(--color-amber);
    color: var(--color-charcoal);
}

/* ==========================================================================
   SECTION 33 — TODO LIST COMPONENTS
   DashboardToDoSummary.razor, ToDoListDetailModal.razor
   ========================================================================== */

/* Panel content area (todo variant of dashboard-content) */
.todo-list-panel-content {
    display: flex;
    flex-direction: column;
    gap: 0;
    overflow-y: auto;
}

/* Section header: "My Private Lists" / "Band Public Lists" */
.todo-section-header {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
    color: var(--text-muted);
    padding: var(--space-2) var(--space-3);
    background-color: var(--color-cream);
    border-top: var(--border-thin);
    border-bottom: var(--border-thin);
    margin-top: var(--space-1);
}

.todo-section-header:first-child {
    margin-top: 0;
    border-top: none;
}

/* Wrapper around a single list row + its expansion panel */
.todo-list-wrapper {
    border-bottom: var(--border-thin);
}

.todo-list-wrapper:last-child {
    border-bottom: none;
}

/* List title row (inherits .dashboard-row.clickable-row) */
.todo-list-title-row {
    grid-template-columns: 1fr auto auto;
    gap: var(--space-2);
    align-items: center;
}

/* Chevron area */
.todo-list-title-row-chevrons {
    display: flex;
    align-items: center;
    color: var(--text-muted);
}

/* Truncated list name */
.todo-list-name {
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--text-primary);
}

/* Expansion header: edit button + show-completed toggle */
.todo-expansion-header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-2);
}

.todo-expansion-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-xs);
    color: var(--text-secondary);
    cursor: pointer;
    user-select: none;
}

.todo-checkbox {
    accent-color: var(--color-amber);
    cursor: pointer;
}

.todo-list-edit-button {
    /* inherits .btn-icon-action — no extra styles needed */
}

/* Empty states */
.todo-empty-state {
    padding: var(--space-4) var(--space-3);
    text-align: center;
    font-size: var(--text-sm);
    color: var(--text-muted);
}

/* Scroll area for the items tab */
.todo-list-scroll-area {
    max-height: 320px;
    overflow-y: auto;
}

/* Toolbar row above the item list */
.todo-toolbar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    padding-bottom: var(--space-2);
}

/* Description textarea in the detail modal */
.todo-list-new-item-description {
    width: 100%;
    resize: vertical;
    min-height: 60px;
}

/* Muted helper text */
.todo-text-muted {
    font-size: var(--text-sm);
    color: var(--text-muted);
    padding: var(--space-2) var(--space-3);
}

/* Single-line truncation helper */
.todo-text-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ==========================================================================
   SECTION 34 — INLINE EDIT TARGET (EditableContent.razor admin mode)
   The span wrapping editable text in admin mode — shows a pencil cursor
   and a subtle underline to signal editability.
   ========================================================================== */

.inline-edit-target {
    cursor: pointer;
    text-decoration-line: underline;
    text-decoration-style: dotted;
    text-decoration-color: color-mix(in srgb, var(--color-amber) 50%, transparent);
    text-underline-offset: 3px;
    transition: text-decoration-color var(--transition-fast);
}

.inline-edit-target:hover {
    text-decoration-color: var(--color-amber);
}

/* Empty slot placeholder — shows "click to edit" hint */
.inline-edit-target:empty::before {
    content: attr(data-label);
    color: var(--text-muted);
    font-style: italic;
    font-size: var(--text-xs);
    text-decoration: none;
    display: inline-block;
}

/* ==========================================================================
   SECTION 35 — ACTIVITY FEED (DashboardActivityFeed.razor)
   ========================================================================== */

/* Activity feed container */
.activity-feed-container {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    flex: 1;
}

/* Individual activity row */
.activity-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border-bottom: var(--border-thin);
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.activity-item:last-child {
    border-bottom: none;
}

.activity-item:hover {
    background-color: var(--color-cream);
}

/* Icon badge */
.activity-icon {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background-color: color-mix(in srgb, var(--color-amber) 15%, transparent);
    color: var(--color-charcoal);
    font-size: 14px;
    margin-top: 1px;
}

/* Text content area */
.activity-header {
    display: flex;
    align-items: baseline;
    gap: var(--space-1);
    flex-wrap: wrap;
}

.actor-name {
    font-weight: 600;
    font-size: var(--text-sm);
    color: var(--text-primary);
}

.af-target-entity {
    font-size: var(--text-xs);
    color: var(--color-amber);
    font-weight: 500;
}

.activity-details-inline {
    font-size: var(--text-sm);
    color: var(--text-primary);
}

.activity-date {
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin-top: 2px;
}

.activity-row {
    flex: 1;
    min-width: 0;
}

.activity-empty {
    padding: var(--space-4) var(--space-3);
    text-align: center;
    font-size: var(--text-sm);
    color: var(--text-muted);
}

/* Responsive: stack grid-2 on narrow screens */
@media (max-width: 640px) {
    .grid-2 {
        grid-template-columns: 1fr;
    }

    .grid-contact {
        grid-template-columns: 1fr;
    }

    .am-diff-row {
        grid-template-columns: 80px 1fr;
    }

    .am-diff-arrow,
    .am-diff-new {
        grid-column: 2;
    }

    .grid-cols-song,
    .grid-cols-playlist {
        grid-template-columns: 1fr auto;
    }

    .dashboard-grid-header .header-sortable:nth-child(n+3),
    .dashboard-row > div:nth-child(n+3):not(.action-cell) {
        display: none;
    }
}


/* ==========================================================================
   SECTION 36 — COVERAGE AUDIT GAP FILL
   All classes that were used in markup but had no rule in this file.
   Organized by the tier inventory from the audit.
   ========================================================================== */


/* --------------------------------------------------------------------------
   36-A. PUBLIC SURFACE GAPS
   -------------------------------------------------------------------------- */

/* Home hero tagline subtitle (p below the big display text) */
.home-hero-tagline-sub {
    font-size: var(--text-md);
    color: rgba(245, 240, 232, 0.80);
    line-height: var(--leading-relaxed);
    max-width: 44ch;
    /* No separate margin — the gap on .home-hero-tagline flex parent handles it */
}

/* Play-release button overlaid on the Home release tile.
   Floated inside .home-hero-tile-body so it doesn't push copy around. */
.home-hero-tile-play {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    background-color: var(--color-accent);
    color: var(--color-white);
    border: none;
    border-radius: 50%;
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
    /* Sits in the tile-body flex column — margin-top: auto pushes it to the bottom */
    margin-top: auto;
    align-self: flex-start;
}

.home-hero-tile-play:hover {
    background-color: var(--color-accent-light);
    transform: scale(1.08);
}

/* Press page root — modifier on .public-page */
.press-page {
    /* No extra override needed beyond .public-page; preserves space for
       any future press-specific padding tweaks without breaking the base. */
}

/* Press facts container — wraps the at-a-glance definition list */
.press-facts {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* GroupPhotoComposite — .person-image, .person-name-caption */
.person-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top center;
    display: block;
}

.person-name-caption {
    position: absolute;
    bottom: var(--space-3);
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    /* Semi-transparent backdrop so the logo reads on any photo */
    background-color: rgba(28, 26, 23, 0.45);
    border-radius: var(--radius-sm);
    padding: var(--space-1) var(--space-3);
    pointer-events: none;
}

.person-name-caption img {
    height: 20px;
    width: auto;
    filter: brightness(0) invert(1);
    opacity: 0.90;
}

/* YouTubeEmbed component classes */

/* Outer wrapper — reserves 16:9 space even before the iframe loads */
.youtube-embed {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    background-color: var(--color-charcoal);
    border-radius: var(--radius-md);
    overflow: hidden;
}

/* Stage — fills the embed area for both the facade and the placeholder */
.youtube-embed-stage {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
}

/* Facade — clickable thumbnail + play icon */
.youtube-embed-facade {
    cursor: pointer;
}

/* Thumbnail image fills the stage */
.youtube-embed-thumb {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* The big triangle play icon over the thumbnail */
.youtube-embed-play-icon {
    position: relative;
    z-index: 1;
    font-size: 3rem;
    color: var(--color-white);
    background-color: rgba(196, 82, 26, 0.85);
    width: 64px;
    height: 64px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.youtube-embed-facade:hover .youtube-embed-play-icon {
    background-color: var(--color-accent);
    transform: scale(1.10);
}

/* Actual iframe fills the stage after click */
.youtube-embed-iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: none;
    display: block;
}

/* Placeholder tile when VideoId is empty */
.youtube-embed-placeholder .youtube-embed-stage {
    background-color: var(--color-charcoal);
    cursor: default;
}

.youtube-embed-placeholder-text {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: rgba(245, 240, 232, 0.50);
    font-style: italic;
}

/* TrackList component — public-facing ordered track list */

.track-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    list-style: none;
    padding: 0;
    margin: var(--space-4) 0 0;
    border-top: var(--border-thin);
}

.track-row {
    display: grid;
    grid-template-columns: 28px 1fr auto auto;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-2);
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    transition: background-color var(--duration-fast) var(--ease-out);
}

.track-row:last-child {
    border-bottom: none;
}

.track-row:hover {
    background-color: var(--color-cream-deep);
}

.track-number {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* .track-title already styled in section 32 (.track-title) — no duplicate */

.track-duration {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.track-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.track-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: none;
    border: var(--border-thin);
    border-radius: 50%;
    color: var(--color-charcoal-muted);
    cursor: pointer;
    padding: 0;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out);
}

.track-button:hover {
    background-color: var(--color-accent);
    color: var(--color-white);
    border-color: var(--color-accent);
}

.track-button-play {
    /* Same as .track-button — no extra override needed */
}

.track-button-queue {
    /* Same as .track-button — no extra override needed */
}

.track-external {
    font-size: var(--text-xs);
    color: var(--color-accent);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    padding: var(--space-1) var(--space-2);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    border-color: var(--color-accent);
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.track-external:hover {
    background-color: var(--color-accent);
    color: var(--color-white);
}

/* track-version-notes — description text inside the audio-row dropdown
   (band portal / SongPortal audio tab) */
.track-version-notes {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    font-style: italic;
    cursor: pointer;
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.track-version-notes:hover {
    color: var(--color-charcoal);
}

/* DropdownView — wrapper + floating popup */
.dropdown-wrapper {
    position: relative;
    display: inline-block;
}

.popup-container {
    position: fixed;        /* JS positions via positionPopup() */
    z-index: 600;
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    padding: var(--space-3) var(--space-4);
    min-width: 220px;
    max-width: 360px;
}

/* .dismiss — used in Blazor error UI (already styled under #blazor-error-ui .dismiss)
   and as a standalone utility in a few other places */
.dismiss {
    cursor: pointer;
    background: none;
    border: none;
    color: inherit;
    opacity: 0.75;
    padding: 0 var(--space-2);
    font-size: var(--text-base);
    transition: opacity var(--duration-fast) var(--ease-out);
}

.dismiss:hover {
    opacity: 1;
}

/* .reload — "Reload" link/button in error state panels */
.reload {
    display: inline-flex;
    align-items: center;
    padding: var(--space-2) var(--space-4);
    background-color: var(--color-accent);
    color: var(--color-white);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    text-decoration: none;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.reload:hover {
    background-color: var(--color-accent-light);
    color: var(--color-white);
}


/* --------------------------------------------------------------------------
   36-B. BAND PORTAL GAPS
   -------------------------------------------------------------------------- */

/* Dashboard input — text inputs on dashboard cards */
.dashboard-input {
    padding: var(--space-2) var(--space-3);
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    transition: border-color var(--duration-fast) var(--ease-out);
}

.dashboard-input:focus {
    outline: none;
    border-color: var(--color-accent);
}

/* dashboard-mode is already on .admin-container.dashboard-mode (Section 23) */

/* Pager footer (PagerControl.razor) */
.dashboard-pager-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border-top: var(--border-thin);
    margin-top: var(--space-2);
    background-color: var(--surface-page);
}

.pager-buttons {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.pager-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: none;
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    color: var(--color-charcoal-muted);
    cursor: pointer;
    padding: 0;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.pager-btn:hover:not(:disabled) {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

.pager-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.pager-info {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    font-variant-numeric: tabular-nums;
}

/* Discussion list / panel / footer (SongPortal discussion tab) */
.discussion-panel {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    min-height: 200px;
}

.discussion-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    flex: 1;
    overflow-y: auto;
    padding: var(--space-2) 0;
}

.discussion-footer {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding-top: var(--space-3);
    border-top: var(--border-thin);
}

/* .conversation-mode already styled in Section 22 (.am-body.conversation-mode) */

/* Replying-to banner (SongPortal discussion + Conversation component) */
.replying-to-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background-color: var(--color-cream-deep);
    border-left: 3px solid var(--color-accent);
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

/* Song editor classes */
.song-detail-notes {
    width: 100%;
    min-height: 80px;
    padding: var(--space-2) var(--space-3);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    resize: vertical;
}

.song-detail-notes:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-dim);
}

/* SortableSongList grid */
.song-sortable-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: var(--border-thin);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.song-grid-header {
    background-color: var(--color-cream-deep);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal-muted);
}

.song-grid-row {
    display: grid;
    /* 7 cols: handle | seq | title | artist | key | bpm | actions */
    grid-template-columns: 28px 32px 2fr 1fr 60px 60px 60px;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-bottom: var(--border-thin);
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    transition: background-color var(--duration-fast) var(--ease-out);
}

.song-grid-row:last-child {
    border-bottom: none;
}

.song-draggable-row {
    cursor: grab;
}

.song-draggable-row:hover {
    background-color: var(--color-cream);
}

.song-draggable-row.is-dragging {
    opacity: 0.55;
    background-color: var(--color-accent-dim);
}

.drag-handle-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-charcoal-muted);
    cursor: grab;
    flex-shrink: 0;
}

.song-seq-text {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.song-title-text {
    font-weight: 600;
    color: var(--color-charcoal);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.song-artist-text {
    color: var(--color-charcoal-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.song-meta-text {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

.song-actions-cell {
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

.song-col-header-action {
    text-align: right;
}

/* PlaylistLyricsView / SongHistoryView — print/lyric popout classes */
.playlist-lyrics-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-4) var(--page-gutter);
    border-bottom: var(--border-thin);
    background-color: var(--color-cream);
    print-color-adjust: exact;
}

.playlist-title-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.playlist-main-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--color-charcoal);
    font-variation-settings: 'WONK' 0;
}

/* .playlist-detail-notes — notes on a playlist detail (PlaylistPortal) */
.playlist-detail-notes {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    font-style: italic;
    line-height: var(--leading-relaxed);
}

/* .playlist-songs — the songs section in the playlist detail modal */
.playlist-songs {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

/* Print / lyric page styles */
.lyrics-view-container {
    background-color: #fff;
    color: #000;
    max-width: 820px;
    margin: 0 auto;
    padding: var(--space-5) var(--page-gutter);
    font-family: var(--font-body);
    font-size: 13px;
    line-height: 1.5;
}

.lyrics-body {
    padding: var(--space-3) 0 var(--space-6);
}

.lyrics-body pre {
    font-family: var(--font-body);
    font-size: 12px;
    white-space: pre-wrap;
    word-break: break-word;
    line-height: 1.6;
}

.lyrics-display {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    white-space: pre-wrap;
    word-break: break-word;
    line-height: var(--leading-relaxed);
    padding: var(--space-3) 0;
}

.lyric-page-break {
    break-inside: avoid;
    page-break-inside: avoid;
    margin-bottom: var(--space-6);
}

.song-header-inline {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
    padding-bottom: var(--space-2);
    border-bottom: var(--border-thin);
}

/* .song-title already styled elsewhere; used in lyric view context */
.song-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--color-charcoal);
    font-variation-settings: 'WONK' 0;
}

.song-meta-inline {
    display: flex;
    gap: var(--space-4);
    flex-wrap: wrap;
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

/* --- Chord chart (ChordChartView / PlaylistChordChartView via ChordSheet) ---
   Sheet-music density: bold, glanceable chord symbols; sections never split across a page break.
   Reuses .lyrics-view-container / .playlist-lyrics-header / .btn-print from the lyrics print styles. */
.chord-body {
    padding: var(--space-3) 0 var(--space-6);
}

.chord-sheet {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.chord-section {
    break-inside: avoid;
    page-break-inside: avoid;
}

.chord-section-head {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    margin-bottom: var(--space-2);
    padding-bottom: var(--space-1);
    border-bottom: var(--border-thin);
}

.chord-section-label {
    font-family: var(--font-display);
    font-size: var(--text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal);
}

.chord-section-tag,
.chord-section-hint {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    font-style: italic;
}

.chord-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-5);
    align-items: baseline;
}

/* Large, bold chord symbols — readable at arm's length on a music stand. */
.chord-symbol {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--color-charcoal);
    min-width: 2.5ch;
}

.chord-row-empty {
    color: var(--color-charcoal-muted);
    font-size: 1.25rem;
}

@media print {
    .chord-symbol { color: #000; }
    .chord-section { break-inside: avoid; page-break-inside: avoid; }
}

/* Interactive chart controls (transpose stepper + Nashville toggle + print) — hidden in print,
   so the printed chart shows the chosen rendering without the on-screen buttons. */
.chart-controls {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.transpose-stepper {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    background-color: var(--color-cream);
}

.transpose-stepper.is-disabled {
    opacity: 0.45;
}

.ts-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border: none;
    border-radius: var(--radius-sm);
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
    font-size: var(--text-md);
    font-weight: 700;
    cursor: pointer;
}

.ts-btn:disabled {
    cursor: default;
}

.ts-btn:not(:disabled):hover {
    background-color: var(--color-accent);
    color: var(--color-white);
}

.ts-label {
    min-width: 3ch;
    text-align: center;
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--color-charcoal);
}

.btn-mode {
    padding: var(--space-2) var(--space-3);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    background-color: var(--color-cream);
    color: var(--color-charcoal-mid);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
}

.btn-mode.is-active {
    background-color: var(--color-charcoal);
    color: var(--color-cream);
}

/* Segmented chord-display selector (Letters / Nashville / Roman) — buttons read as one control. */
.mode-group {
    display: inline-flex;
    gap: var(--space-1);
}

@media print {
    .chart-controls { display: none !important; }
}

/* --- Lyric-with-chords idiom (ChordProSheet) ---
   Interim view: each section's chord row (from its "> chords:" attribute) above its lyric lines.
   NOT syllable-anchored — see PrintableTabsCharts-v1.md M2 tech-debt note. */
.chordpro-sheet {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.chordpro-section {
    break-inside: avoid;
    page-break-inside: avoid;
}

.chordpro-heading {
    font-family: var(--font-display);
    font-size: var(--text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal);
    margin-bottom: var(--space-2);
    padding-bottom: var(--space-1);
    border-bottom: var(--border-thin);
}

.chordpro-chord-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    align-items: baseline;
    margin-bottom: var(--space-2);
}

/* Bold, glanceable chords sitting above the lyric block (the ONE pop color marks them as chords). */
.chordpro-chord {
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--color-accent);
    min-width: 2ch;
}

.chordpro-lines {
    display: flex;
    flex-direction: column;
}

.chordpro-line {
    font-family: var(--font-body);
    font-size: var(--text-md);
    line-height: var(--leading-relaxed);
    color: var(--color-charcoal);
}

.chordpro-gap {
    height: var(--space-3);
}

.chordpro-instrumental {
    font-size: var(--text-sm);
    font-style: italic;
    color: var(--color-charcoal-muted);
}

@media print {
    .chordpro-chord { color: #000; }
    .chordpro-line { color: #000; }
    .chordpro-section { break-inside: avoid; page-break-inside: avoid; }
}

/* --- Chord-diagram boxes (ChordDiagram.razor) ---
   Own SVG, standard style. Ink follows the charcoal token; finger numbers contrast on the filled
   dots; prints black-on-white. Geometry is in the component; this is color/type only. */
.chord-diagram {
    color: var(--color-charcoal);
    display: inline-block;
    vertical-align: top;
}

.chord-diagram .cd-ink {
    stroke: currentColor;
}

.chord-diagram .cd-open {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.4;
}

.chord-diagram .cd-mute {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
}

.chord-diagram .cd-dot,
.chord-diagram .cd-barre {
    fill: currentColor;
}

.chord-diagram .cd-name {
    fill: currentColor;
    font-family: var(--font-display);
    font-weight: 700;
}

.chord-diagram .cd-pos {
    fill: currentColor;
    font-weight: 600;
}

.chord-diagram .cd-finger {
    fill: var(--color-cream);
    font-weight: 700;
    font-size: 9px;                 /* fit inside the dot (was inheriting the page size) */
    dominant-baseline: central;     /* vertically center the number in the circle */
}

.chord-diagram .cd-label {
    fill: var(--color-charcoal-muted);
}

@media print {
    .chord-diagram { color: #000; }
    .chord-diagram .cd-finger { fill: #fff; }
    .chord-diagram .cd-label { fill: #000; }
}

/* Chord legend — a row of diagrams for the song's distinct chords (ChordLegend.razor). */
.chord-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    align-items: flex-start;
    padding: var(--space-3) 0 var(--space-5);
    margin-bottom: var(--space-4);
    border-bottom: var(--border-thin);
}

.chord-legend-noshape {
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--color-charcoal-muted);
    padding: var(--space-3) var(--space-2);
}

@media print {
    .chord-legend { border-color: #000; break-inside: avoid; }
}

/* Legend chord is a button — click opens its inversions. */
.chord-legend-btn {
    appearance: none;
    background: none;
    border: none;
    margin: 0;
    padding: var(--space-1);
    line-height: 0;
    cursor: pointer;
    border-radius: var(--radius-md);
}

.chord-legend-btn:hover {
    background-color: var(--color-cream-deep);
}

.chord-legend-btn:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

@media print {
    .chord-legend-btn:hover { background: none; }
}

/* --- Inversions popover (ChordInversionsPopover.razor) — screen-only --- */
.chord-pop-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
    background-color: rgba(0, 0, 0, 0.45);
}

.chord-pop {
    background-color: var(--color-cream);
    color: var(--color-charcoal);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-5);
    max-width: min(92vw, 760px);
    max-height: 85vh;
    overflow-y: auto;
}

.chord-pop-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-3);
    padding-bottom: var(--space-2);
    border-bottom: var(--border-thin);
}

.chord-pop-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--color-charcoal);
}

.chord-pop-close {
    appearance: none;
    border: none;
    background: none;
    padding: var(--space-1) var(--space-2);
    font-size: var(--text-xl);
    line-height: 1;
    cursor: pointer;
    color: var(--color-charcoal-muted);
}

.chord-pop-close:hover {
    color: var(--color-accent);
}

.chord-pop-group {
    margin-top: var(--space-4);
}

.chord-pop-group-label {
    font-family: var(--font-display);
    font-size: var(--text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal-muted);
    margin-bottom: var(--space-2);
}

.chord-pop-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

.chord-pop-none {
    font-size: var(--text-sm);
    font-style: italic;
    color: var(--color-charcoal-muted);
}

.chord-pop-footer {
    margin-top: var(--space-5);
    padding-top: var(--space-3);
    border-top: var(--border-thin);
}

.chord-pop-explore {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-accent);
    text-decoration: none;
}

.chord-pop-explore:hover {
    text-decoration: underline;
}

@media print {
    .chord-pop-backdrop { display: none !important; }
}

/* --- Chord Explorer page (ChordExplorer.razor) --- */
.explorer {
    max-width: 1100px;
    margin: 0 auto;
    padding: var(--space-5) var(--page-gutter);
}

.explorer-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--color-charcoal);
}

.explorer-sub {
    color: var(--color-charcoal-muted);
    margin-bottom: var(--space-4);
}

.explorer-controls {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4);
    margin-bottom: var(--space-5);
    background-color: var(--color-cream-deep);
    border-radius: var(--radius-lg);
}

.explorer-group {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
}

.explorer-label {
    min-width: 4.5rem;
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-charcoal-muted);
}

.explorer-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
}

.chip {
    appearance: none;
    border: var(--border-thin);
    border-radius: var(--radius-md);
    background-color: var(--color-cream);
    color: var(--color-charcoal-mid);
    padding: var(--space-1) var(--space-3);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
}

.chip:hover {
    border-color: var(--color-accent);
}

.chip.is-active {
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    border-color: var(--color-charcoal);
}

.explorer-span {
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
}

.explorer-result {
    margin-top: var(--space-5);
}

.explorer-result-label {
    font-family: var(--font-display);
    font-size: var(--text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal);
    margin-bottom: var(--space-3);
    padding-bottom: var(--space-2);
    border-bottom: var(--border-thin);
}

.explorer-count {
    margin-left: var(--space-2);
    color: var(--color-charcoal-muted);
    font-weight: 600;
}

.explorer-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

.explorer-empty {
    color: var(--color-charcoal-muted);
    font-style: italic;
}

/* --- Voicings appendix (ChordVoicingsAppendix.razor) — per-chord inversions; prints on its own page --- */
.voicings-appendix {
    margin-top: var(--space-6);
    padding-top: var(--space-4);
    border-top: var(--border-thin);
}

.voicings-appendix-title {
    font-family: var(--font-display);
    font-size: var(--text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal);
    margin-bottom: var(--space-4);
}

.voicings-chord {
    margin-bottom: var(--space-5);
    break-inside: avoid;
    page-break-inside: avoid;
}

.voicings-chord-name {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    margin-bottom: var(--space-2);
}

.voicings-chord-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-5);
}

.voicings-inv {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-1);
}

.voicings-inv-label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-charcoal-muted);
}

@media print {
    .voicings-appendix { break-before: page; }
    .voicings-chord { break-inside: avoid; page-break-inside: avoid; }
}

/* --- Print tablature (TabStaff.razor) — own "ts-" classes, decoupled from the editor's TabView --- */
.ts-staff {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    color: var(--color-charcoal);
}

.ts-phrase {
    break-inside: avoid;
    page-break-inside: avoid;
}

.ts-phrase-label {
    font-family: var(--font-display);
    font-size: var(--text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal);
    margin-bottom: var(--space-2);
}

.ts-system {
    display: grid;
    row-gap: 0;
    column-gap: 0;
    align-items: stretch;
    margin-bottom: var(--space-4);
    font-family: var(--font-mono, ui-monospace, "Cascadia Mono", Consolas, monospace);
}

.ts-strlabel {
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

/* Each cell carries the string line through its vertical middle, so the lines run continuously
   across the row; the fret number sits in a paper-colored box that masks the line behind it. */
.ts-cell {
    box-sizing: border-box;
    position: relative;
    min-height: 1.6em;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--text-sm);
    background-image: linear-gradient(to bottom,
        transparent calc(50% - 0.6px), var(--color-charcoal-mid) calc(50% - 0.6px),
        var(--color-charcoal-mid) calc(50% + 0.6px), transparent calc(50% + 0.6px));
}

.ts-bar-start { border-left: 1.5px solid var(--color-charcoal); }
.ts-bar-end { border-right: 1.5px solid var(--color-charcoal); }

.ts-fret {
    position: relative;
    padding: 0 0.2em;
    font-weight: 700;
    color: var(--color-charcoal);
    background-color: var(--color-cream);
}

.ts-tech {
    font-size: var(--text-xs);
    color: var(--color-accent);
}

@media print {
    .ts-staff { color: #000; }
    .ts-cell {
        background-image: linear-gradient(to bottom,
            transparent calc(50% - 0.6px), #000 calc(50% - 0.6px),
            #000 calc(50% + 0.6px), transparent calc(50% + 0.6px));
    }
    .ts-bar-start { border-left-color: #000; }
    .ts-bar-end { border-right-color: #000; }
    .ts-fret { background-color: #fff; color: #000; }
}

/* Per-song tab sheet (TabSheet.razor) — one part (bass, guitar, …) per instrument line. */
.tab-sheet {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}

.tab-part {
    break-inside: avoid;
}

.tab-part-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
    padding-bottom: var(--space-2);
    border-bottom: 2px solid var(--color-charcoal);
}

.tab-part-role {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
}

.tab-part-summary {
    font-size: var(--text-sm);
    font-style: italic;
    color: var(--color-charcoal-muted);
}

.tab-part-approach {
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
    line-height: var(--leading-relaxed);
    margin-top: var(--space-3);
}

/* Setlist chord charts (PlaylistChordChartView) — each song titled; one song per page in print. */
.chord-setlist-song {
    margin-bottom: var(--space-6);
}

.chord-song-header {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
    padding-bottom: var(--space-2);
    border-bottom: 2px solid var(--color-charcoal);
}

.chord-song-index {
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--color-charcoal-muted);
}

.chord-song-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
}

.chord-song-artist,
.chord-song-key {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

@media print {
    .chord-setlist-song { break-before: page; }
    .chord-setlist-song:first-child { break-before: auto; }
}

/* SongHistoryView print table */
.history-print-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}

.history-print-table th {
    text-align: left;
    padding: var(--space-2) var(--space-3);
    border-bottom: 2px solid var(--color-charcoal);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal-muted);
}

.history-print-meta td {
    padding: var(--space-2) var(--space-3);
    border-bottom: var(--border-thin);
    vertical-align: top;
    font-size: 12px;
    color: var(--color-charcoal);
}

.history-print-lyrics-cell {
    padding: 0 !important;
    border-bottom: 2px solid var(--color-charcoal-mid) !important;
}

.history-print-lyrics-box {
    padding: var(--space-3) var(--space-5);
    background-color: var(--color-cream);
}

.history-print-lyrics-text {
    font-family: var(--font-body);
    font-size: 11px;
    white-space: pre-wrap;
    word-break: break-word;
    line-height: 1.55;
    color: var(--color-charcoal);
    margin: 0;
}

/* version-header — in the Lyrics tab of SongPortal */
.version-header {
    padding-bottom: var(--space-3);
    border-bottom: var(--border-thin);
    margin-bottom: var(--space-4);
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
}

/* Attachment UI (SongPortal / Links tab) */
.add-attachment-panel {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-4);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-5);
}

.add-song-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    flex-wrap: wrap;
}

/* Playlist editor: shuffle + duplicate-detection toolbar above the sortable
   song list (Phase 8 WS-1). */
.playlist-tools {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin: var(--space-3) 0;
}

/* Buttons that pair an icon with a text label — keeps the AppIcon and span on
   one baseline-aligned row. */
.btn-icon-text {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.playlist-dup-warning {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-warning, #b45309);
    margin-left: auto; /* push the duplicate notice + action to the right */
}

.attachment-mode-toggle {
    display: flex;
    gap: var(--space-5);
    align-items: center;
    flex-wrap: wrap;
}

.attachment-mode-toggle label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
    cursor: pointer;
}

.attachment-grid {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: var(--border-thin);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.attachment-row {
    display: grid;
    grid-template-columns: 32px auto 1fr auto;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-thin);
    background-color: var(--color-white);
    transition: background-color var(--duration-fast) var(--ease-out);
}

.attachment-row:last-child {
    border-bottom: none;
}

.attachment-row:hover {
    background-color: var(--color-cream);
}

.attachment-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-charcoal-muted);
    flex-shrink: 0;
}

.attachment-meta {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

.attachment-type-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--space-2);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-charcoal-muted);
    white-space: nowrap;
}

.attachment-desc-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.attachment-desc-text {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-charcoal);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.attachment-link {
    font-size: var(--text-xs);
    color: var(--color-accent);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.attachment-link:hover {
    color: var(--color-accent-light);
    text-decoration: underline;
}

.attachment-actions {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex-shrink: 0;
}

/* Audio tab (SongPortal) */
.audio-tab {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.audio-grid {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: var(--border-thin);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.audio-row {
    display: grid;
    /* Type | Ver | Actions | Notes */
    grid-template-columns: 100px 80px 1fr 1fr;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-thin);
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    background-color: var(--color-white);
}

.audio-row:first-child {
    background-color: var(--color-cream-deep);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal-muted);
}

.audio-row:last-child {
    border-bottom: none;
}

/* .header-cell — column header within the audio-row header */
.header-cell {
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal-muted);
}

/* File upload components */
.upload-wrapper {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.upload-file-label {
    display: inline-flex;
    align-items: center;
    padding: var(--space-2) var(--space-4);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out);
}

.upload-file-label:hover {
    background-color: var(--color-cream-mid);
    border-color: var(--color-charcoal-muted);
}

/* Progress bar — generic Bootstrap-like pattern */
.progress {
    width: 100%;
    height: 8px;
    background-color: var(--color-cream-mid);
    border-radius: var(--radius-full);
    overflow: hidden;
}

.progress-bar {
    height: 100%;
    background-color: var(--color-accent);
    border-radius: var(--radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--text-xs);
    color: transparent;  /* text is invisible inside 8px bar; still in DOM for aria */
    transition: width 150ms linear;
}

.upload-progress-track {
    width: 100%;
    height: 6px;
    background-color: var(--color-cream-mid);
    border-radius: var(--radius-full);
    overflow: hidden;
    margin: var(--space-2) 0;
}

.upload-progress-fill {
    height: 100%;
    background-color: var(--color-accent);
    border-radius: var(--radius-full);
    transition: width 150ms linear;
}

/* song-version-option — <option> elements in the audio track version select */
.song-version-option {
    /* <option> styling is limited by browsers; just ensure readable text */
    color: var(--color-charcoal);
    background-color: var(--color-white);
}

/* ToDoItem display */
.todo-input {
    flex: 1;
    padding: var(--space-2) var(--space-3);
    background-color: var(--color-white);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    transition: border-color var(--duration-fast) var(--ease-out);
}

.todo-input:focus {
    outline: none;
    border-color: var(--color-accent);
}

.todo-item-display {
    /* Modifier on .todo-item-row for the read-only display variant */
    cursor: default;
}

.todo-item-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border-bottom: var(--border-thin);
    transition: background-color var(--duration-fast) var(--ease-out);
}

.todo-item-row:last-child {
    border-bottom: none;
}

.todo-item-row:hover {
    background-color: var(--color-cream);
}

.todo-item-row.completed {
    opacity: 0.55;
}

.todo-text-display {
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    flex: 1;
    line-height: var(--leading-normal);
}

/* Drag-reorder list container (band portal drag interactions) */
.drag-handle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    color: var(--color-charcoal-muted);
    cursor: grab;
    flex-shrink: 0;
}

.reorder-list-container {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: var(--border-thin);
    border-radius: var(--radius-md);
    overflow: hidden;
}

/* Sortable table headers */
.sortable-th {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    transition: color var(--duration-fast) var(--ease-out);
}

.sortable-th:hover {
    color: var(--color-charcoal);
}

.sort-indicator-inactive {
    opacity: 0.35;
    margin-left: var(--space-1);
    font-size: var(--text-xs);
}

/* Band portal action buttons */
.delete-btn {
    /* Alias for .btn-delete — same pattern */
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3);
    background-color: transparent;
    color: #B91C1C;
    border: 1px solid #FCA5A5;
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.delete-btn:hover {
    background-color: #FEE2E2;
    border-color: #B91C1C;
}

.btn-add-song {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.btn-add-song:hover {
    background-color: var(--color-accent);
}

.btn-queue {
    /* inline queue button in the audio row */
    /* Shares .btn-secondary visual but smaller padding */
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    background-color: transparent;
    color: var(--color-charcoal-mid);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 600;
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.btn-queue:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

.btn-print {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    text-decoration: none;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.btn-print:hover {
    background-color: var(--color-accent);
    color: var(--color-white);
}

.btn-modal {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal-mid);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.btn-modal:hover {
    background-color: var(--color-cream-mid);
    color: var(--color-charcoal);
}

.btn-small-delete {
    /* Compact delete used in SortableSongList rows */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-1) var(--space-2);
    background-color: transparent;
    color: #B91C1C;
    border: 1px solid #FCA5A5;
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    cursor: pointer;
    line-height: 1;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.btn-small-delete:hover {
    background-color: #FEE2E2;
    border-color: #B91C1C;
}

.btn-close-small {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    background: none;
    border: none;
    border-radius: 50%;
    color: var(--color-charcoal-muted);
    font-size: var(--text-md);
    cursor: pointer;
    padding: 0;
    transition: background-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.btn-close-small:hover {
    background-color: var(--color-cream-deep);
    color: var(--color-charcoal);
}

.btn-link-action {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: none;
    border: none;
    color: var(--color-accent);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
    transition: color var(--duration-fast) var(--ease-out);
}

.btn-link-action:hover {
    color: var(--color-accent-light);
}

.btn-external {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    background-color: transparent;
    color: var(--color-charcoal-mid);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: border-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.btn-external:hover {
    border-color: var(--color-accent);
    color: var(--color-accent);
}

.btn-group {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}


/* --------------------------------------------------------------------------
   36-C. ADMIN GAPS
   -------------------------------------------------------------------------- */

/* admin-table — generic data table used in Newsletter + Subscribers admin */
.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}

.admin-table th {
    text-align: left;
    padding: var(--space-2) var(--space-3);
    border-bottom: 2px solid var(--color-cream-mid);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-charcoal-muted);
    white-space: nowrap;
    background-color: var(--color-cream-deep);
}

.admin-table td {
    padding: var(--space-2) var(--space-3);
    border-bottom: var(--border-thin);
    color: var(--color-charcoal);
    vertical-align: middle;
}

.admin-table tbody tr:hover td {
    background-color: var(--color-cream);
}

/* Buttons grouped inside a table cell (e.g. the contact-inbox row actions). */
.admin-cell-actions {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* Free-text cell that preserves the visitor's line breaks and stays readable. */
.admin-cell-message {
    max-width: 32rem;
    white-space: pre-wrap;
}

/* Rows the admin has marked handled read as de-emphasized. */
.admin-table tbody tr.is-handled td {
    opacity: 0.55;
}

/* admin-page-toolbar — filter bar above admin tables */
.admin-page-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
    padding: var(--space-3) var(--space-4);
    background-color: var(--color-cream-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
}

.admin-page-toolbar-count {
    margin-left: auto;
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* admin-input-narrowest — very narrow text field (e.g. year/code inputs) */
.admin-input-narrowest {
    max-width: 80px;
}

/* Newsletter admin compose page */
.newsletter-admin {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-6);
    align-items: start;
}

.newsletter-admin-section-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    margin-bottom: var(--space-4);
    font-variation-settings: 'WONK' 0;
}

.newsletter-admin-compose {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.newsletter-admin-body {
    min-height: 200px;
    font-family: var(--font-body);
    font-size: var(--text-sm);
}

.newsletter-admin-blast-fieldset {
    border-color: var(--color-accent);
}

.newsletter-admin-confirm {
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    line-height: var(--leading-normal);
    margin-bottom: var(--space-3);
}

.newsletter-admin-dev-banner {
    padding: var(--space-3) var(--space-4);
    background-color: #FEF3C7;
    color: #92400E;
    border: 1px solid #FCD34D;
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
}

.newsletter-admin-history {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

@media (max-width: 880px) {
    .newsletter-admin {
        grid-template-columns: 1fr;
    }
}

/* Images-admin library — grid of all site images with usage annotations */
.images-admin-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); }
.images-admin-upload { cursor: pointer; }
.images-admin-upload input { display: none; }
.images-admin-summary { font-size: var(--text-sm); color: var(--color-charcoal-muted); margin-bottom: var(--space-3); }
.images-admin-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-4); }
.images-admin-card {
    display: flex; flex-direction: column;
    border: 1px solid var(--color-cream-dark); border-radius: var(--radius-md);
    overflow: hidden; background: var(--color-cream-light);
}
.images-admin-card.is-unused { border-color: #FCA5A5; }
.images-admin-thumb { width: 100%; aspect-ratio: 1 / 1; object-fit: contain; background: var(--color-cream-deep); }
.images-admin-meta { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-2) var(--space-3); }
.images-admin-name { font-weight: 600; font-size: var(--text-sm); word-break: break-all; color: var(--color-charcoal); }
.images-admin-dims { font-size: 0.72rem; color: var(--color-charcoal-muted); display: flex; flex-wrap: wrap; gap: var(--space-1); align-items: center; }
.images-admin-folder { padding: 0 var(--space-1); border-radius: var(--radius-sm); background: var(--color-cream-mid); color: var(--color-charcoal-mid); }
.images-admin-badge { align-self: flex-start; font-size: 0.66rem; font-weight: 700; padding: 1px var(--space-2); border-radius: var(--radius-sm); }
.images-admin-badge-unused { background: #FEE2E2; color: #991B1B; }
.images-admin-uses { font-size: 0.72rem; color: var(--color-charcoal-mid); }
.images-admin-uses summary { cursor: pointer; color: var(--color-accent); font-weight: 600; }
.images-admin-uses ul { margin: var(--space-1) 0 0; padding-left: var(--space-3); display: flex; flex-direction: column; gap: 2px; }
.images-admin-use-kind { font-weight: 700; color: var(--color-charcoal); }
.images-admin-use-where { color: var(--color-charcoal-muted); }
.images-admin-copy { align-self: flex-start; margin-top: var(--space-1); }

/* FFT-timeline library admin */
.audio-fft-url { font-size: 0.72rem; color: var(--color-charcoal-muted); word-break: break-all; }
.audio-fft-actions { display: flex; gap: var(--space-1); white-space: nowrap; }

/* Email-test admin — SMTP diagnostics surface */
.email-test {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    max-width: 640px;
}

.email-test-actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.email-test-section-title {
    font-size: var(--text-lg);
    margin-bottom: var(--space-3);
}

.email-test-detail {
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    white-space: pre-wrap;
    word-break: break-word;
}

.email-test-detail.is-ok {
    background-color: #DCFCE7;
    color: #166534;
    border: 1px solid #86EFAC;
}

.email-test-detail.is-error {
    background-color: #FEE2E2;
    color: #991B1B;
    border: 1px solid #FCA5A5;
}

.email-test-config {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-1) var(--space-4);
    margin-top: var(--space-3);
    font-size: var(--text-sm);
}

.email-test-config dt {
    font-weight: 600;
    color: var(--color-charcoal-muted);
}

.email-test-config dd {
    margin: 0;
    color: var(--color-charcoal);
    word-break: break-word;
}


/* --------------------------------------------------------------------------
   36-D. IDENTITY GAPS
   -------------------------------------------------------------------------- */

/* login-local — the email/password form section */
.login-local {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    width: 100%;
    max-width: 380px;
}

/* login-external / social-login — the "Log In with Google" section */
.login-external,
.social-login {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    width: 100%;
    max-width: 380px;
}

/* .btn-google — Google sign-in button */
.btn-google {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    padding: var(--space-3) var(--space-5);
    background-color: var(--color-white);
    color: var(--color-charcoal);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
    justify-content: center;
    transition: background-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
    box-shadow: var(--shadow-sm);
}

.btn-google:hover {
    background-color: var(--color-cream-deep);
    box-shadow: var(--shadow-md);
}

/* Google "G" icon placeholder */
.google-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background-color: #4285F4;
    color: var(--color-white);
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 700;
    flex-shrink: 0;
}

/* btn-passkey-action — passkey action buttons (rename/delete on passkey items) */
.btn-passkey-action {
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-xs);
}

/* hr-replacement-separator — horizontal divider between login sections */
.hr-replacement-separator {
    width: 100%;
    height: 1px;
    background-color: var(--color-cream-mid);
    margin: var(--space-4) 0;
}

/* passkey-section — section wrapping passkey sign-in in Login page */
.passkey-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    align-items: flex-start;
}

/* Manage layout classes */

/* manage-content — the main content column in ManageLayout */
.manage-content {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    min-width: 0;
}

/* manage-nav — alias target for the nav panel in manage layout */
.manage-nav {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* manage-form-wrapper — wraps forms on manage pages */
.manage-form-wrapper {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    max-width: 480px;
    width: 100%;
}

/* recovery-grid-item — individual code cell in the 2FA recovery grid */
.recovery-grid-item {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--color-charcoal);
    font-family: var(--font-body);
    text-align: center;
    letter-spacing: 0.08em;
}

/* step-form — multi-step form wrapper (e.g. EnableAuthenticator) */
.step-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    max-width: 480px;
}

/* sectioned-container — a form divided into labeled sections */
.sectioned-container {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}

/* panel-padding — adds interior padding to a panel/card */
.panel-padding {
    padding: var(--space-4);
}

/* gap-bottom — simple bottom spacer utility */
.gap-bottom {
    margin-bottom: var(--space-4);
}


/* --------------------------------------------------------------------------
   36-E. BLAZOR RECONNECT MODAL
   -------------------------------------------------------------------------- */

/*
 * Blazor's ReconnectModal renders a <dialog> element. The dialog is styled
 * by the framework's own JS visibility management: it adds CSS classes to
 * the <body> tag (components-reconnect-show, etc.) but the modal's *child
 * content* uses the classes below. We style it as a centered overlay tile
 * in the editorial cream/charcoal palette.
 *
 * AI Note: the <dialog> element gets its position from the framework JS
 * (not from this CSS). We only need to style the container content and
 * the conditional-visibility text/button elements.
 */

#components-reconnect-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 9000;
    background-color: var(--color-cream);
    color: var(--color-charcoal);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-6);
    max-width: min(90vw, 400px);
    width: 100%;
    border-color: var(--color-cream-mid);
}

#components-reconnect-modal::backdrop {
    background-color: rgba(28, 26, 23, 0.55);
    backdrop-filter: blur(2px);
}

.components-reconnect-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
    text-align: center;
}

/* Animated "rejoining" spinner — two bouncing dots */
.components-rejoining-animation {
    display: flex;
    gap: var(--space-3);
    align-items: center;
    justify-content: center;
}

.components-rejoining-animation div {
    width: 10px;
    height: 10px;
    background-color: var(--color-accent);
    border-radius: 50%;
    animation: reconnect-bounce 1.2s ease-in-out infinite;
}

.components-rejoining-animation div:nth-child(2) {
    animation-delay: 0.3s;
}

@keyframes reconnect-bounce {
    0%, 80%, 100% { transform: scale(0.75); opacity: 0.5; }
    40%            { transform: scale(1.0);  opacity: 1.0; }
}

/* All the conditional-visibility paragraphs — hidden by default */
.components-reconnect-container p {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
    line-height: var(--leading-normal);
    margin: 0;
}

.components-reconnect-container button {
    display: inline-flex;
    align-items: center;
    padding: var(--space-3) var(--space-6);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.components-reconnect-container button:hover {
    background-color: var(--color-accent);
}

/* Visibility classes toggled by Blazor's reconnect JS
   The framework uses these class names to show/hide specific messages. */
.components-reconnect-first-attempt-visible,
.components-reconnect-repeated-attempt-visible,
.components-reconnect-failed-visible,
.components-pause-visible,
.components-resume-failed-visible {
    /* These start hidden; the framework removes/adds visibility states.
       We provide base display so they render correctly when visible. */
    display: block;
}

/* Re-use reduced-motion preference */
@media (prefers-reduced-motion: reduce) {
    .components-rejoining-animation div {
        animation: none;
        opacity: 0.7;
    }
}


/* --------------------------------------------------------------------------
   36-F. ALERTS / UTILITY GAPS
   -------------------------------------------------------------------------- */

/* alert-warning — amber-tinted warning alert (used in audio-tab guard) */
.alert-warning {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background-color: #FEF3C7;
    color: #92400E;
    border: 1px solid #FCD34D;
    border-left: 4px solid #D97706;
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
}

/* alert-link — link inside an alert */
.alert-link {
    color: inherit;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.alert-link:hover {
    opacity: 0.8;
}

/* alert-text-block — body paragraph within an alert */
.alert-text-block {
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
}

/* empty-state — inline empty-state message within a panel */
.empty-state {
    padding: var(--space-5) var(--space-4);
    text-align: center;
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    font-style: italic;
}

/* empty-layout — body-level background for popout/print pages
   (EmptyLayout.razor — no header/nav chrome) */
.empty-layout {
    background-color: #fff;
    color: #000;
    min-height: 100dvh;
}


/* --------------------------------------------------------------------------
   36-G. HELPER CLASSES
   -------------------------------------------------------------------------- */

/* text-secondary — muted secondary text (used in several band portal spots) */
.text-secondary {
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
}

/* global-background — override for body background when needed outside layouts */
.global-background {
    background-color: var(--surface-page);
    min-height: 100dvh;
}

/* table-responsive — horizontal-scroll wrapper for tables on narrow screens */
.table-responsive {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* edit-mode-container — wraps lyrics / version editor inputs */
.edit-mode-container {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* about-members / about-performances — section containers on About page */
.about-members {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.about-performances {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}


/* =========================================================
   37. HOME TILES ADMIN — /admin/home-tiles
   ========================================================= */
/* Three-pane layout: tile list (left), edit form (center), live preview
   (right). Preview re-renders the home grid with in-memory edits so the
   admin sees changes immediately. */

.home-tiles-admin-layout {
    display: grid;
    grid-template-columns: 240px 1fr 380px;
    gap: var(--space-4);
    align-items: start;
}

.home-tiles-admin-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    background-color: var(--surface-raised);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    max-height: 80vh;
    overflow-y: auto;
}

.home-tiles-admin-form {
    background-color: var(--surface-raised);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    padding: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.home-tiles-admin-preview {
    background-color: var(--surface-deep);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    position: sticky;
    top: calc(var(--header-height, 48px) + var(--space-3));
    max-height: calc(100vh - 80px);
    overflow-y: auto;
}

.home-tiles-admin-preview .tile-eyebrow {
    color: var(--surface-deep-text-muted);
    margin-bottom: var(--space-2);
}

/* Scale the preview down so the full 4-column home grid fits in the
   right pane. transform: scale shrinks; transform-origin top-left keeps
   the grid pinned to the upper-left of the preview frame. */
.home-tiles-admin-preview-frame {
    transform: scale(0.4);
    transform-origin: top left;
    width: 250%;            /* compensate for the 0.4 scale → 1/0.4 */
    pointer-events: none;   /* clicks on preview tiles do nothing */
}

.home-tiles-admin-preview-frame .home-hero {
    padding: var(--space-2);
}

/* Inline 4-input row for grid coordinates */
.home-tiles-admin-grid-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-2);
}

.home-tiles-admin-grid-row .admin-field {
    margin: 0;
}

.admin-field-help {
    font-size: var(--text-xs);
    color: var(--surface-raised-text-muted);
    margin-top: 2px;
}

/* Two-column settings form used by /admin/general. Labels right-aligned
   in column 1, inputs + help text in column 2. Stacks on narrow viewports. */
.admin-form-grid {
    display: grid;
    grid-template-columns: 200px 1fr;
    gap: var(--space-3) var(--space-5);
    align-items: start;
    margin-bottom: var(--space-5);
}

.admin-form-grid-label {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    text-align: right;
    padding-top: 0.55rem;   /* aligns label baseline with input text */
    color: inherit;
}

.admin-form-grid-input {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.admin-form-grid-input code {
    background-color: rgba(0, 0, 0, 0.05);
    padding: 1px 4px;
    border-radius: 3px;
    font-size: 0.92em;
}

/* Section header that spans both columns inside .admin-form-grid.
   Used to break a long settings form into labeled groups. Contains
   an eyebrow line + optional help text. The top border + spacing
   visually separates it from the row above. */
.admin-form-grid-section {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding-top: var(--space-4);
    margin-top: var(--space-2);
    border-top: 1px solid var(--surface-raised-border);
}

.admin-form-grid-section:first-child {
    padding-top: 0;
    margin-top: 0;
    border-top: none;
}

.admin-form-grid-section .tile-eyebrow {
    /* eyebrow already styled globally; tighten margins for in-form use */
    margin: 0;
}

/* Inline row that pairs two narrow inputs with a separator between them
   (e.g. width × height, min × max). Lives inside .admin-form-grid-input. */
.admin-form-grid-pair {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.admin-form-grid-pair-sep {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    color: var(--surface-raised-text-muted);
    user-select: none;
    line-height: 1;
}

@media (max-width: 720px) {
    .admin-form-grid {
        grid-template-columns: 1fr;
    }

    .admin-form-grid-label {
        text-align: left;
        padding-top: 0;
    }
}

/* Responsive: stack on narrower viewports */
@media (max-width: 1280px) {
    .home-tiles-admin-layout {
        grid-template-columns: 200px 1fr;
    }
    .home-tiles-admin-preview {
        grid-column: 1 / -1;
        position: static;
        max-height: none;
    }
    .home-tiles-admin-preview-frame {
        transform: scale(0.55);
        width: 182%;
    }
}

@media (max-width: 880px) {
    .home-tiles-admin-layout {
        grid-template-columns: 1fr;
    }
    .home-tiles-admin-list {
        max-height: none;
    }
}

/* ==========================================================================
   SECTION 37 — IMAGE PICKER MODAL
   ImagePickerModal.razor — admin image browser (HomeTilesAdmin Media section).
   Classes: .img-picker-backdrop, .img-picker-dialog, .img-picker-header,
            .img-picker-title, .img-picker-close, .img-picker-body,
            .img-picker-empty, .img-picker-group-label, .img-picker-row,
            .img-picker-row-active, .img-picker-thumb, .img-picker-meta,
            .img-picker-filename, .img-picker-dims, .img-picker-path,
            .img-picker-footer
   ========================================================================== */

/* Semi-transparent full-viewport backdrop. Clicking it closes the modal. */
.img-picker-backdrop {
    position: fixed;
    inset: 0;
    background-color: rgba(28, 26, 23, 0.55);
    backdrop-filter: blur(2px);
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
}

/* The dialog panel itself. Fixed width, scrollable body, capped height. */
.img-picker-dialog {
    background-color: var(--color-cream);
    color: var(--color-charcoal);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: min(680px, 100%);
    max-height: 82vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Title bar: heading on the left, × button on the right. */
.img-picker-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-4) var(--space-5);
    border-bottom: var(--border-thin);
    flex-shrink: 0;
}

.img-picker-title {
    font-size: var(--text-md);
    font-weight: 600;
    margin: 0;
    color: var(--color-charcoal);
}

.img-picker-close {
    background: none;
    border: none;
    font-size: var(--text-lg);
    line-height: 1;
    color: var(--color-charcoal-muted);
    cursor: pointer;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    transition: color var(--duration-fast) var(--ease-out),
                background-color var(--duration-fast) var(--ease-out);
}

.img-picker-close:hover {
    color: var(--color-charcoal);
    background-color: var(--color-cream-dark);
}

/* Scrollable image list. */
.img-picker-body {
    overflow-y: auto;
    flex: 1 1 auto;
    padding: var(--space-2) var(--space-4);
}

.img-picker-empty {
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
    padding: var(--space-6) 0;
    text-align: center;
}

/* Sub-folder section divider label. */
.img-picker-group-label {
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-charcoal-muted);
    padding: var(--space-3) 0 var(--space-2);
    border-bottom: var(--border-thin);
    margin-bottom: var(--space-1);
}

/* Clickable image row: thumbnail on left, text metadata on right. */
.img-picker-row {
    display: flex;
    gap: var(--space-3);
    align-items: center;
    width: 100%;
    padding: var(--space-2);
    background: none;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    cursor: pointer;
    text-align: left;
    transition: background-color var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out);
    margin-bottom: var(--space-1);
}

.img-picker-row:hover {
    background-color: var(--color-cream-dark);
}

/* Highlight applied immediately on click, cleared when modal closes. */
.img-picker-row-active {
    background-color: color-mix(in srgb, var(--color-amber) 12%, transparent);
    border-color: color-mix(in srgb, var(--color-amber) 40%, transparent);
}

/* Square thumbnail with centered cover crop. */
.img-picker-thumb {
    width: 64px;
    height: 64px;
    object-fit: cover;
    object-position: center;
    border-radius: var(--radius-sm);
    border: var(--border-thin);
    flex-shrink: 0;
    /* Subtle placeholder while loading="lazy" images arrive. */
    background-color: var(--color-cream-mid);
}

/* Three-line stacked text block: filename, size+dimensions, path. */
.img-picker-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1;
}

.img-picker-filename {
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-charcoal);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.img-picker-dims {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

.img-picker-path {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    font-family: var(--font-mono, ui-monospace, monospace);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Footer bar with Cancel button. */
.img-picker-footer {
    padding: var(--space-3) var(--space-5);
    border-top: var(--border-thin);
    display: flex;
    justify-content: flex-end;
    flex-shrink: 0;
}

/* Narrow viewport: modal takes full width with reduced padding. */
@media (max-width: 720px) {
    .img-picker-backdrop {
        padding: var(--space-2);
    }

    .img-picker-header,
    .img-picker-footer {
        padding-left: var(--space-3);
        padding-right: var(--space-3);
    }

    .img-picker-body {
        padding-left: var(--space-3);
        padding-right: var(--space-3);
    }
}

/* ==========================================================================
   SECTION 38 — STEM MIX PANEL (SongPortal audio tab, BandMember)
   "Play a mix" selector: Original / Cover / Stem Mix (+ per-stem checkboxes).
   ========================================================================== */
.stem-mix-panel {
    margin-top: var(--space-5);
    padding: var(--space-4);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    background-color: var(--color-cream-mid);
}

.stem-mix-panel h4 {
    margin: 0 0 var(--space-1);
    font-size: var(--text-sm);
    font-weight: 600;
}

.stem-mix-hint {
    margin: 0 0 var(--space-3);
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

.stem-mix-controls {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    flex-wrap: wrap;
}

.stem-mix-source {
    max-width: 240px;
}

/* Stem checkboxes — wrap into a tidy row of pill-ish labels. */
.stem-mix-stems {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: var(--border-thin);
}

.stem-mix-stem {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    cursor: pointer;
}

.stem-mix-stem input[type="checkbox"] {
    accent-color: var(--color-amber);
    width: 15px;
    height: 15px;
    cursor: pointer;
}

/* ==========================================================================
   SECTION 39 — BATCH DOWNLOADER (BandDownloader.razor)
   Song multi-select + a scrollable list + progress.
   ========================================================================== */
.downloader-songs {
    margin-top: var(--space-5);
}

.downloader-songs-header {
    padding-bottom: var(--space-2);
    border-bottom: var(--border-thin);
    margin-bottom: var(--space-2);
    font-weight: 600;
}

.downloader-song-list {
    display: flex;
    flex-direction: column;
    max-height: 360px;
    overflow-y: auto;
    border: var(--border-thin);
    border-radius: var(--radius-md);
}

.downloader-song-head,
.downloader-song-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) minmax(60px, 0.7fr) 3rem 3.4rem 3.4rem;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
}

/* Column header row — sticky so labels stay visible while scrolling. */
.downloader-song-head {
    position: sticky;
    top: 0;
    background-color: var(--color-cream);
    border-bottom: var(--border-thin);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-charcoal-muted);
    z-index: 1;
}

.downloader-song-row {
    cursor: pointer;
    border-bottom: var(--border-thin);
}

.downloader-song-row:last-child {
    border-bottom: none;
}

.downloader-song-row:hover {
    background-color: var(--color-cream-dark);
}

.downloader-song-row input[type="checkbox"] {
    accent-color: var(--color-amber);
    width: 15px;
    height: 15px;
    cursor: pointer;
}

.downloader-song-name {
    font-weight: 500;
    color: var(--color-charcoal);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.downloader-song-artist {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Original / Cover / Stems availability indicators. */
.downloader-flag,
.downloader-flag-head {
    text-align: center;
}

.downloader-flag.on {
    color: var(--color-amber);
    font-weight: 700;
}

.downloader-flag.off {
    color: var(--color-charcoal-muted);
    opacity: 0.45;
}

.downloader-progress {
    margin-top: var(--space-4);
}

/* ===== MIDI key check — MV5 read-only review surface (.mv-) ===== */
.mv-summary {
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
    margin-bottom: var(--space-4);
}

.mv-summary strong { color: var(--color-accent); }

.mv-link { color: var(--color-accent); }

.mv-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.mv-row {
    background-color: var(--surface-raised);
    color: var(--surface-raised-text);
    border: 1px solid var(--surface-border);
    border-radius: var(--radius-md, 8px);
    padding: var(--space-3) var(--space-4);
}

/* The most actionable verdict gets the one pop color as a left rule. */
.mv-row:has(.mv-badge-likelywrong) { border-left: 3px solid var(--color-accent); }

.mv-row-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-3);
}

.mv-song {
    font-family: var(--font-display);
    font-size: var(--text-md);
    color: var(--color-charcoal);
}

.mv-keys { font-size: var(--text-sm); color: var(--color-charcoal-mid); }
.mv-key-stored { font-weight: 600; }
.mv-arrow { color: var(--color-charcoal-muted); margin: 0 0.15em; }
.mv-key-proposed { font-weight: 600; color: var(--color-accent); }
.mv-transpose { color: var(--color-charcoal-muted); }

.mv-explain {
    margin: var(--space-2) 0 0;
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
}

.mv-meta {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-top: var(--space-2);
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

/* Status badges — palette-respecting: the accent is loudest (likely wrong), neutrals for the rest. */
.mv-badge {
    display: inline-block;
    padding: 0.1em 0.6em;
    border-radius: var(--radius-pill, 999px);
    font-size: var(--text-xs);
    font-weight: 600;
    white-space: nowrap;
}

.mv-badge-likelywrong { background-color: var(--color-accent); color: var(--color-white); }
.mv-badge-suspect { background-color: var(--color-accent-dim); color: var(--color-accent); }
.mv-badge-possibletransposition { background-color: var(--color-cream-deep); color: var(--color-charcoal-mid); border: 1px solid var(--color-cream-mid); }
.mv-badge-confirmed { background-color: var(--color-cream-deep); color: var(--color-charcoal-muted); }
.mv-badge-insufficient { background-color: var(--color-cream-mid); color: var(--color-charcoal-muted); }

.mv-sources { margin-top: var(--space-2); }

.mv-sources > summary {
    cursor: pointer;
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

.mv-source-list {
    list-style: none;
    margin: var(--space-2) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    font-size: var(--text-xs);
}

.mv-source {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-2);
    color: var(--color-charcoal-mid);
}

.mv-source-status { font-weight: 600; color: var(--color-charcoal-muted); }
.mv-source-used { color: var(--color-accent); }
.mv-source-label { color: var(--color-charcoal-mid); }
.mv-source-key { color: var(--color-charcoal); }
.mv-source-note { color: var(--color-charcoal-muted); font-style: italic; }
.mv-source-url { color: var(--color-accent); }

/* MX-E6: "adopt the MIDI version" expander inside an instrument-line editor. */
.ile-midi { margin-top: var(--space-3); }

.ile-midi > summary {
    cursor: pointer;
    user-select: none;
    font-size: var(--text-sm);
    color: var(--color-accent);
}


/* =========================================================
   37. PRACTICE GAMES — LYRIC GAMES
   (ClozeGame, SequencerGame, NextLineGame,
    FadingScaffoldGame, WrongWordGame)
   ========================================================= */

/* ---------- Shared setup-screen pattern ---------- */
/* All lyric games share this setup layout (max-width 480px centered card). */
.cloze-setup-wrap,
.seq-setup-wrap {
    max-width: 480px;
    margin: 0 auto;
    padding: 1.5rem 1rem;
}

/* ---------- ClozeGame ---------- */
/* Fullscreen drill: fixed topbar, scrolling lyrics zone, fixed bottom option bar. */

.cloze-back {
    display: inline-block;
    margin-bottom: 1rem;
    font-size: 0.9rem;
    color: var(--game-light-primary);
    text-decoration: none;
}
.cloze-back:hover { text-decoration: underline; }

/* Viewport-filling stage split at 48 / 52 vh */
.cloze-topbar {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: 3.2rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1rem;
    background: var(--game-card);
    border-bottom: 1px solid var(--game-border);
    z-index: 100;
}
.cloze-timer {
    font-variant-numeric: tabular-nums;
    font-size: 1.4rem;
    font-weight: 800;
    color: var(--game-light-primary);
}
.cloze-progress  { font-size: 0.9rem; color: var(--game-text-muted); }
.cloze-misses    { font-size: 0.9rem; color: var(--game-light-danger); }
.cloze-cancel {
    margin-left: auto;
    border: none;
    background: transparent;
    font-size: 1.2rem;
    color: var(--game-text-muted);
    cursor: pointer;
    padding: 0.3rem 0.5rem;
}
.cloze-cancel:hover { color: var(--game-text); }

.cloze-lyrics-scroll {
    position: fixed;
    top: 3.2rem;
    left: 0; right: 0;
    height: 48vh;
    overflow-y: auto;
    padding: 1rem;
}
.cloze-lyrics-content { max-width: 680px; margin: 0 auto; }
.cloze-zip { font-size: 0.65rem; color: var(--game-text-muted); letter-spacing: 0.04em; text-transform: uppercase; margin-bottom: 0.5rem; }

.cloze-section    { margin-bottom: 1.2rem; }
.cloze-section-head { /* handled by global section heading styles */ }
.cloze-line       { line-height: 1.8; margin-bottom: 0.15rem; }
.cloze-word       { margin-right: 0.3em; }
.cloze-tok        {
    display: inline-block;
    padding: 0 0.2em;
    border-radius: 3px;
    transition: background var(--duration-fast);
}
/* Glide highlight — emphasizes the active blank's lyrics context */
.cloze-tok.is-glide {
    background: color-mix(in srgb, var(--game-light-primary) 18%, transparent);
}

/* Fixed option/result bar at the bottom */
.cloze-optionbar,
.cloze-resultbar {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: 52vh;
    overflow-y: auto;
    padding: 1rem;
    background: var(--game-bg);
    border-top: 1px solid var(--game-border);
}
.cloze-optiongrid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    justify-content: center;
    max-width: 600px;
    margin: 0 auto;
}
.cloze-option {
    padding: 0.6rem 1.1rem;
    border-radius: 8px;
    border: 1px solid var(--game-border);
    background: var(--game-card);
    color: var(--game-text);
    font-size: 1rem;
    cursor: pointer;
    transition: border-color var(--duration-fast), background var(--duration-fast);
}
.cloze-option:hover:not(:disabled) { border-color: var(--game-accent); }
.cloze-option.is-wrong {
    border-color: var(--game-danger-border);
    background: var(--game-danger-bg);
    color: var(--game-danger);
    cursor: not-allowed;
    animation: cloze-shake 0.25s;
}
@keyframes cloze-shake {
    0%, 100% { transform: translateX(0); }
    25%       { transform: translateX(-5px); }
    75%       { transform: translateX(5px); }
}

/* Results + trouble list (shared shape across all lyric games) */
.cloze-result-score  { font-size: 2rem; font-weight: 800; color: var(--game-light-primary); }
.cloze-result-sub    { font-size: 1rem; color: var(--game-text-muted); font-variant-numeric: tabular-nums; }
.cloze-result-best   { font-size: 0.95rem; color: var(--game-text-muted); font-variant-numeric: tabular-nums; }
.cloze-result-best.is-new { color: var(--game-light-success); font-weight: 700; }
.cloze-result-actions { display: flex; gap: 0.6rem; margin-top: 0.8rem; }
.cloze-trouble-list  { width: 100%; max-width: 440px; text-align: left; margin-top: 0.5rem; }
.cloze-trouble-list h4 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--game-light-danger); margin: 0 0 0.3rem; }
.cloze-trouble-line  { font-size: 0.9rem; padding: 0.18rem 0; border-bottom: 1px dotted var(--game-border); }
.cloze-trouble-more  { font-size: 0.8rem; color: var(--game-text-muted); margin-top: 0.25rem; }

/* Recent-miss counter chips in the topbar */
.cloze-recent       { display: inline-flex; gap: 0.3rem; }
.cloze-recent-chip  {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.4rem; height: 1.4rem;
    padding: 0 0.2rem;
    border-radius: var(--radius-full);
    font-size: 0.72rem;
    font-weight: 700;
    background: var(--game-danger-border);
    color: var(--game-text);
}


/* ---------- SequencerGame ---------- */
/* flex-column 100vh stage (not fixed-position like Cloze). */

.seq-topbar {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.8rem 1rem;
    border-bottom: 1px solid var(--game-border);
    background: var(--game-card);
}
.seq-sofar   { padding: 0.8rem 1rem; font-size: 0.9rem; color: var(--game-text-muted); }
.seq-chips   { display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0.5rem 1rem 0.8rem; }
.seq-chip {
    padding: 0.4rem 0.8rem;
    border-radius: 8px;
    border: 1px solid var(--game-border);
    background: var(--game-card);
    color: var(--game-text);
    font-size: 0.95rem;
    cursor: pointer;
    transition: border-color var(--duration-fast);
}
.seq-chip:hover { border-color: var(--game-accent); }
.seq-chip.is-correct { border-color: var(--game-success-border); background: var(--game-success-bg); color: var(--game-success); cursor: default; }
.seq-chip.is-wrong   { border-color: var(--game-danger-border);  background: var(--game-danger-bg);  color: var(--game-danger);  cursor: default; animation: seq-shake 0.25s; }
@keyframes seq-shake {
    0%, 100% { transform: translateX(0); }
    25%       { transform: translateX(-4px); }
    75%       { transform: translateX(4px); }
}

.seq-tray {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    align-content: flex-start;
}
.seq-card {
    padding: 0.55rem 0.9rem;
    border-radius: 8px;
    border: 1px solid var(--game-border);
    background: var(--game-card);
    color: var(--game-text);
    font-size: 0.95rem;
    cursor: pointer;
    transition: border-color var(--duration-fast), background var(--duration-fast);
}
.seq-card:hover  { border-color: var(--game-accent); }
.seq-card.is-used { opacity: 0.35; cursor: default; }

.seq-results { padding: 1.5rem 1rem; text-align: center; }
.seq-result-score { font-size: 2rem; font-weight: 800; color: var(--game-light-primary); }
.seq-result-sub   { font-size: 1rem; color: var(--game-text-muted); }
.seq-result-best  { font-size: 0.9rem; color: var(--game-text-muted); }
.seq-result-best.is-new { color: var(--game-light-success); font-weight: 700; }
.seq-result-actions { display: flex; gap: 0.6rem; justify-content: center; margin-top: 0.8rem; }
.seq-trouble-list { width: 100%; max-width: 440px; text-align: left; margin: 0.5rem auto 0; }
.seq-trouble-list h4 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--game-light-danger); margin: 0 0 0.3rem; }
.seq-trouble-line { font-size: 0.9rem; padding: 0.18rem 0; border-bottom: 1px dotted var(--game-border); }
.seq-trouble-more { font-size: 0.8rem; color: var(--game-text-muted); margin-top: 0.25rem; }


/* ---------- NextLineGame ---------- */
/* Fixed-position stage: top 48 vh = cue, bottom 52 vh = options. */

.nl-topbar {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: 3.2rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1rem;
    background: var(--game-card);
    border-bottom: 1px solid var(--game-border);
    z-index: 100;
}

.nl-cue {
    position: fixed;
    top: 3.2rem; left: 0; right: 0;
    height: calc(48vh - 3.2rem);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    text-align: center;
}
.nl-cue-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--game-text-muted); margin-bottom: 0.5rem; }
.nl-cue-line  { font-size: 1.4rem; font-weight: 600; line-height: 1.4; max-width: 640px; }

.nl-reveal {
    position: fixed;
    top: 3.2rem; left: 0; right: 0;
    height: calc(48vh - 3.2rem);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    text-align: center;
    background: var(--game-light-success-bg);
}

.nl-answerbar {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: 52vh;
    overflow-y: auto;
    padding: 1rem;
    background: var(--game-bg);
    border-top: 1px solid var(--game-border);
}
.nl-optiongrid {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    max-width: 600px;
    margin: 0 auto;
}
.nl-option {
    padding: 0.7rem 1rem;
    border-radius: 10px;
    border: 1px solid var(--game-border);
    background: var(--game-card);
    color: var(--game-text);
    font-size: 1rem;
    text-align: left;
    cursor: pointer;
    transition: border-color var(--duration-fast), background var(--duration-fast);
}
.nl-option:hover:not(:disabled) { border-color: var(--game-accent); }
.nl-option.is-correct { border-color: var(--game-success-border); background: var(--game-success-bg); color: var(--game-success); cursor: default; }
.nl-option.is-wrong   { border-color: var(--game-danger-border);  background: var(--game-danger-bg);  color: var(--game-danger);  cursor: not-allowed; animation: nl-shake 0.25s; }
.nl-type { font-size: 0.78rem; color: var(--game-text-muted); margin-top: 0.3rem; }

@keyframes nl-shake {
    0%, 100% { transform: translateX(0); }
    25%       { transform: translateX(-5px); }
    75%       { transform: translateX(5px); }
}
@keyframes nl-slide-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

.nl-results {
    height: 100vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 1.5rem 1rem;
    text-align: center;
}
.nl-result-score { font-size: 2rem; font-weight: 800; color: var(--game-light-primary); }
.nl-result-sub   { font-size: 1rem; color: var(--game-text-muted); font-variant-numeric: tabular-nums; }
.nl-result-best  { font-size: 0.9rem; color: var(--game-text-muted); font-variant-numeric: tabular-nums; }
.nl-result-best.is-new { color: var(--game-light-success); font-weight: 700; }
.nl-result-actions { display: flex; gap: 0.6rem; margin-top: 0.8rem; }
.nl-trouble-list { width: 100%; max-width: 440px; text-align: left; margin-top: 0.5rem; }
.nl-trouble-list h4 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--game-light-danger); margin: 0 0 0.3rem; }
.nl-trouble-line { font-size: 0.9rem; padding: 0.18rem 0; border-bottom: 1px dotted var(--game-border); }
.nl-trouble-more { font-size: 0.8rem; color: var(--game-text-muted); margin-top: 0.25rem; }


/* ---------- FadingScaffoldGame ---------- */
/* Full-height flex-column; progressive blanking of lyrics. */

.fs-stage  { display: flex; flex-direction: column; min-height: 100vh; }
.fs-topbar {
    flex: 0 0 3.2rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1rem;
    background: var(--game-card);
    border-bottom: 1px solid var(--game-border);
}
.fs-body    { flex: 1 1 auto; overflow-y: auto; padding: 1rem; }
.fs-section { margin-bottom: 1.4rem; }

/* Each scaffold rung: full/blank/partial variants */
.fs-rung-full   { opacity: 1; }
.fs-rung-hint   { opacity: 0.65; }
.fs-rung-blank  { opacity: 0.35; }

.fs-line     { line-height: 1.8; margin-bottom: 0.1rem; }
.fs-scaffold { display: inline; }
.fs-word     { display: inline; }
.fs-full     { display: inline; }
.fs-blank-bar {
    display: inline-block;
    width: 5em;
    height: 0.15em;
    background: var(--game-text-muted);
    border-radius: 2px;
    vertical-align: middle;
    margin: 0 0.15em;
}
.fs-prompt {
    padding: 0.8rem 1rem;
    border-top: 1px solid var(--game-border);
    text-align: center;
    font-size: 1.2rem;
    font-weight: 600;
}
.fs-reveal { color: var(--game-light-success); }

/* Rate buttons after each section */
.fs-rate    { display: flex; gap: 0.5rem; flex-wrap: wrap; justify-content: center; margin-top: 0.5rem; }
.fs-ratebtn {
    padding: 0.4rem 0.9rem;
    border-radius: 8px;
    border: 1px solid var(--game-border);
    background: var(--game-card);
    color: var(--game-text);
    cursor: pointer;
    transition: border-color var(--duration-fast);
}
.fs-ratebtn:hover { border-color: var(--game-accent); }
.fs-ratebtn.is-good { border-color: var(--game-success-border); background: var(--game-success-bg); color: var(--game-success); }
.fs-ratebtn.is-bad  { border-color: var(--game-danger-border);  background: var(--game-danger-bg);  color: var(--game-danger);  }

@keyframes fs-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes fs-pop {
    0%   { transform: scale(1); }
    50%  { transform: scale(1.06); }
    100% { transform: scale(1); }
}

.fs-results { padding: 1.5rem 1rem; text-align: center; }
.fs-result-score { font-size: 2rem; font-weight: 800; color: var(--game-light-primary); }
.fs-result-sub   { font-size: 1rem; color: var(--game-text-muted); }
.fs-result-best  { font-size: 0.9rem; color: var(--game-text-muted); }
.fs-result-best.is-new { color: var(--game-light-success); font-weight: 700; }
.fs-result-actions { display: flex; gap: 0.6rem; justify-content: center; margin-top: 0.8rem; }
.fs-trouble-list { width: 100%; max-width: 440px; text-align: left; margin: 0.5rem auto 0; }
.fs-trouble-list h4 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--game-light-danger); margin: 0 0 0.3rem; }
.fs-trouble-line { font-size: 0.9rem; padding: 0.18rem 0; border-bottom: 1px dotted var(--game-border); }
.fs-trouble-more { font-size: 0.8rem; color: var(--game-text-muted); margin-top: 0.25rem; }


/* ---------- WrongWordGame ---------- */
/* Full-height flex-column; walk through the song word-by-word. */

.ww-stage  { display: flex; flex-direction: column; min-height: 100vh; }
.ww-topbar {
    flex: 0 0 3.2rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1rem;
    background: var(--game-card);
    border-bottom: 1px solid var(--game-border);
}
.ww-scroll { flex: 1 1 auto; overflow-y: auto; padding: 1rem; }

.ww-section-head {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--game-text-muted);
    margin: 1rem 0 0.3rem;
}
.ww-row {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.4rem 0;
    border-radius: 6px;
    transition: background var(--duration-fast), opacity var(--duration-fast);
}
.ww-row.is-done     { opacity: 0.4; }
.ww-row.is-active   { background: color-mix(in srgb, var(--game-light-primary) 8%, transparent); padding-left: 0.5rem; }
.ww-row.is-upcoming { opacity: 0.55; }
.ww-word {
    padding: 0 0.18em;
    border-radius: 3px;
    transition: background var(--duration-fast), color var(--duration-fast);
}
.ww-word.is-current  { background: color-mix(in srgb, var(--game-light-primary) 20%, transparent); }
.ww-word.is-correct  { background: var(--game-light-success-bg); color: var(--game-light-success); }
.ww-word.is-wrong    { background: var(--game-light-danger-bg);  color: var(--game-light-danger); animation: ww-shake 0.25s; }

.ww-foot       { flex: 0 0 auto; padding: 0.8rem 1rem; border-top: 1px solid var(--game-border); background: var(--game-bg); }
.ww-hint       { font-size: 0.88rem; color: var(--game-text-muted); margin-bottom: 0.5rem; }
.ww-correction { font-size: 0.88rem; color: var(--game-light-success); margin-top: 0.3rem; }

@keyframes ww-row-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}
@keyframes ww-shake {
    0%, 100% { transform: translateX(0); }
    25%       { transform: translateX(-4px); }
    75%       { transform: translateX(4px); }
}
@keyframes ww-pop {
    0%   { transform: scale(1); }
    50%  { transform: scale(1.08); }
    100% { transform: scale(1); }
}

.ww-results { padding: 1.5rem 1rem; text-align: center; }
.ww-result-score { font-size: 2rem; font-weight: 800; color: var(--game-light-primary); }
.ww-result-sub   { font-size: 1rem; color: var(--game-text-muted); }
.ww-result-best  { font-size: 0.9rem; color: var(--game-text-muted); }
.ww-result-best.is-new { color: var(--game-light-success); font-weight: 700; }
.ww-result-actions { display: flex; gap: 0.6rem; justify-content: center; margin-top: 0.8rem; }
.ww-trouble-list { width: 100%; max-width: 440px; text-align: left; margin: 0.5rem auto 0; }
.ww-trouble-list h4 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--game-light-danger); margin: 0 0 0.3rem; }
.ww-trouble-line { font-size: 0.9rem; padding: 0.18rem 0; border-bottom: 1px dotted var(--game-border); }
.ww-trouble-more { font-size: 0.8rem; color: var(--game-text-muted); margin-top: 0.25rem; }

@media (prefers-reduced-motion: reduce) {
    .cloze-option.is-wrong,
    .seq-chip.is-wrong,
    .nl-option.is-wrong,
    .ww-word.is-wrong { animation: none; }
    .nl-option.is-wrong,
    .cloze-option.is-wrong { transform: none; }
}


/* =========================================================
   38. PRACTICE GAMES — CHORD GAMES, WHICH-VERSION & DASHBOARD
   (ChordClozeGame, WrongChordGame, NextChordGame,
    ProgressionSequencerGame, WhichVersionGame,
    PracticeDashboard, NoteLineGame)
   ========================================================= */

/* ---------- Shared chord-game setup pattern ---------- */
/* All chord games share this centered max-width setup card. */
.cg-setup-wrap,
.wc-setup-wrap,
.nc-setup-wrap,
.ps-setup-wrap {
    max-width: 560px;
    margin: 0 auto;
    padding: var(--space-6);
}
.cg-back, .wc-back, .nc-back, .ps-back {
    font-size: 0.85rem;
    color: var(--game-accent);
    text-decoration: none;
}
.cg-back:hover, .wc-back:hover, .nc-back:hover, .ps-back:hover { text-decoration: underline; }

.cg-blurb, .wc-blurb, .nc-blurb, .ps-blurb {
    color: var(--game-text-muted);
    margin: 0 0 var(--space-5);
}
.cg-setup, .wc-setup, .nc-setup, .ps-setup {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}
.cg-field, .wc-field, .nc-field, .ps-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 0.85rem;
    color: var(--game-text-muted);
}
.cg-select-wide, .wc-select-wide, .nc-select-wide, .ps-select-wide { width: 100%; }
.cg-start, .wc-start, .nc-start, .ps-start { align-self: flex-start; }
.cg-note,  .wc-note,  .nc-note,  .ps-note  { color: var(--game-text-muted); font-size: 0.85rem; }
.cg-error, .wc-error, .nc-error, .ps-error  { color: var(--game-danger); }

/* ---------- Shared chord-game stage topbar + key-line ---------- */
.cg-topbar, .wc-topbar, .nc-topbar, .ps-topbar {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    font-variant-numeric: tabular-nums;
    margin-bottom: var(--space-4);
}
.cg-timer, .wc-timer, .nc-timer, .ps-timer { font-size: 1.1rem; font-weight: 700; }
.cg-progress, .cg-accuracy,
.wc-progress, .wc-accuracy,
.nc-progress, .nc-accuracy,
.ps-count { color: var(--game-text-muted); }
.cg-cancel, .wc-cancel, .nc-cancel, .ps-cancel {
    margin-left: auto;
    background: none;
    border: none;
    color: var(--game-text-muted);
    font-size: 1.1rem;
    cursor: pointer;
}
.cg-cancel:hover, .wc-cancel:hover, .nc-cancel:hover, .ps-cancel:hover { color: var(--game-text); }
.cg-keyline, .wc-keyline, .nc-keyline, .ps-keyline {
    color: var(--game-text-muted);
    font-size: 0.9rem;
    margin-bottom: var(--space-4);
}
.cg-keyline strong, .wc-keyline strong, .nc-keyline strong, .ps-keyline strong { color: var(--game-text); }

/* ---------- Shared chord-section layout ---------- */
.cg-sections, .wc-sections { display: flex; flex-direction: column; gap: var(--space-5); }
.cg-section-head, .wc-section-head {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--game-text-muted);
    margin-bottom: 6px;
}
.cg-progression, .wc-progression {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: flex-start;
}

/* ---------- ChordClozeGame (cg-*) ---------- */
.cg-stage { max-width: 820px; margin: 0 auto; padding: var(--space-5); }

.cg-chip {
    display: inline-flex;
    align-items: center;
    min-width: 3.2rem;
    justify-content: center;
    padding: 0.5rem 0.7rem;
    border-radius: 8px;
    font-weight: 700;
    font-size: 1.15rem;
    border: 2px solid var(--game-border);
    background: var(--game-card);
}
.cg-chip-given   { color: var(--game-text); }
.cg-chip-correct { border-color: var(--game-success-border); background: var(--game-success-bg); color: var(--game-success); }

.cg-blank {
    display: inline-grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px;
    padding: 4px;
    border-radius: 8px;
    border: 2px dashed var(--game-accent);
}
.cg-choice {
    border: 1px solid var(--game-border);
    border-radius: 6px;
    background: var(--game-card-alt);
    color: var(--game-text);
    font-weight: 700;
    font-size: 1rem;
    padding: 0.35rem 0.6rem;
    cursor: pointer;
    transition: border-color var(--duration-fast), background var(--duration-fast);
}
.cg-choice:hover:not(:disabled) { border-color: var(--game-accent); background: var(--game-card-hover); }
.cg-choice:focus-visible         { outline: 2px solid var(--game-accent); outline-offset: 1px; }
.cg-choice.is-wrong              { border-color: var(--game-danger-border); background: var(--game-danger-bg); color: var(--game-danger); cursor: not-allowed; }

.cg-foot { margin-top: var(--space-6); }

.cg-results      { max-width: 480px; margin: 0 auto; padding: var(--space-6); text-align: center; }
.cg-result-score { font-size: 2rem; font-weight: 800; }
.cg-result-sub   { color: var(--game-text-muted); margin: var(--space-2) 0 var(--space-4); }
.cg-result-best  { color: var(--game-text-muted); margin-bottom: var(--space-4); }
.cg-result-best.is-new { color: var(--game-gold); font-weight: 700; }
.cg-result-actions { display: flex; gap: var(--space-3); justify-content: center; }


/* ---------- WrongChordGame (wc-*) ---------- */
.wc-stage { max-width: 820px; margin: 0 auto; padding: var(--space-5); }

.wc-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-width: 3.2rem;
    justify-content: center;
    padding: 0.5rem 0.7rem;
    border-radius: 8px;
    font-weight: 700;
    font-size: 1.15rem;
    cursor: pointer;
    border: 2px solid var(--game-border);
    background: var(--game-card);
    color: var(--game-text);
    transition: border-color var(--duration-fast), background var(--duration-fast);
}
.wc-chip:hover:not(:disabled) { border-color: var(--game-accent); }
.wc-chip:focus-visible         { outline: 2px solid var(--game-accent); outline-offset: 2px; }
.wc-chip:disabled              { cursor: default; }
.wc-chip-found   { border-color: var(--game-success-border); background: var(--game-success-bg); color: var(--game-success); }
.wc-chip-tapped  { border-color: var(--game-danger-border);  background: var(--game-danger-bg);  color: var(--game-danger); }
.wc-mark         { font-size: 0.8rem; }
.wc-reveal       { font-size: 0.85rem; color: var(--game-text-muted); margin-top: 6px; }
.wc-lure         { color: var(--game-danger); }
.wc-reveal strong { color: var(--game-success); }
.wc-foot         { margin-top: var(--space-6); }

.wc-results      { max-width: 480px; margin: 0 auto; padding: var(--space-6); text-align: center; }
.wc-result-score { font-size: 2rem; font-weight: 800; }
.wc-result-sub   { color: var(--game-text-muted); margin: var(--space-2) 0 var(--space-4); }
.wc-result-best  { color: var(--game-text-muted); margin-bottom: var(--space-4); }
.wc-result-best.is-new { color: var(--game-gold); font-weight: 700; }
.wc-result-actions { display: flex; gap: var(--space-3); justify-content: center; }


/* ---------- NextChordGame (nc-*) ---------- */
.nc-stage { max-width: 820px; margin: 0 auto; padding: var(--space-5); }

.nc-trail {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    padding: var(--space-4);
    border-radius: 8px;
    background: var(--game-card);
    margin-bottom: var(--space-4);
    min-height: 3.5rem;
}
.nc-section {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--game-text-muted);
    border-left: 2px solid var(--game-border);
    padding-left: 6px;
    margin-left: 4px;
}
.nc-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.8rem;
    padding: 0.4rem 0.6rem;
    border-radius: 8px;
    font-weight: 700;
    font-size: 1.1rem;
    border: 2px solid var(--game-border);
    background: var(--game-bg);
    color: var(--game-text);
}
.nc-chip-current { border-color: var(--game-accent); }
.nc-chip-unknown { color: var(--game-text-muted); border-style: dashed; }
.nc-arrow        { color: var(--game-text-muted); font-size: 1.2rem; }

.nc-prompt  { font-weight: 600; margin-bottom: var(--space-3); }
.nc-options { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.nc-choice {
    min-width: 3.5rem;
    padding: 0.6rem 1rem;
    border-radius: 8px;
    border: 2px solid var(--game-border);
    background: var(--game-card-alt);
    color: var(--game-text);
    font-weight: 700;
    font-size: 1.1rem;
    cursor: pointer;
    transition: border-color var(--duration-fast), background var(--duration-fast);
}
.nc-choice:hover:not(:disabled) { border-color: var(--game-accent); background: var(--game-card-hover); }
.nc-choice:focus-visible         { outline: 2px solid var(--game-accent); outline-offset: 2px; }
.nc-choice.is-wrong              { border-color: var(--game-danger-border); background: var(--game-danger-bg); color: var(--game-danger); cursor: not-allowed; }

.nc-results      { max-width: 480px; margin: 0 auto; padding: var(--space-6); text-align: center; }
.nc-result-score { font-size: 2rem; font-weight: 800; }
.nc-result-sub   { color: var(--game-text-muted); margin: var(--space-2) 0 var(--space-4); }
.nc-result-best  { color: var(--game-text-muted); margin-bottom: var(--space-4); }
.nc-result-best.is-new { color: var(--game-gold); font-weight: 700; }
.nc-result-actions { display: flex; gap: var(--space-3); justify-content: center; }


/* ---------- ProgressionSequencerGame (ps-*) ---------- */
.ps-stage   { max-width: 640px; margin: 0 auto; padding: var(--space-5); }
.ps-keyline { color: var(--game-text-muted); font-size: 0.9rem; margin-bottom: var(--space-4); }
.ps-keyline strong { color: var(--game-text); }

.ps-banner {
    padding: var(--space-3) var(--space-4);
    border-radius: 8px;
    margin-bottom: var(--space-4);
    font-weight: 600;
    background: var(--game-card);
    border: 1px solid var(--game-border);
}
.ps-banner.is-perfect { background: #1a3a24; border-color: #2a5a34; color: var(--game-success); }
.ps-best-new { color: var(--game-gold); }

.ps-list {
    list-style: none;
    margin: 0 0 var(--space-5);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}
.ps-card {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-radius: 8px;
    border: 2px solid var(--game-border);
    background: var(--game-card);
}
.ps-card.is-ok  { border-color: var(--game-success-border); background: var(--game-success-bg); }
.ps-card.is-bad { border-color: var(--game-danger-border);  background: var(--game-danger-bg); }

.ps-pos {
    flex-shrink: 0;
    width: 1.8rem; height: 1.8rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--game-bg);
    color: var(--game-text-muted);
    font-weight: 700;
    font-size: 0.9rem;
}
.ps-body   { flex: 1; min-width: 0; }
.ps-label  { font-weight: 600; margin-bottom: 4px; }
.ps-chords { display: flex; flex-wrap: wrap; gap: 4px; }
.ps-chord {
    font-size: 0.85rem;
    font-weight: 700;
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--game-bg);
    color: var(--game-text);
    border: 1px solid var(--game-border);
}
.ps-should { font-size: 0.8rem; color: var(--game-danger); margin-top: 4px; }
.ps-moves  { display: flex; flex-direction: column; gap: 4px; flex-shrink: 0; }
.ps-move {
    width: 2rem; height: 1.7rem;
    border-radius: 6px;
    cursor: pointer;
    line-height: 1;
    font-size: 1rem;
    border: 1px solid var(--game-border);
    background: var(--game-bg);
    color: var(--game-text);
}
.ps-move:hover:not(:disabled)    { border-color: var(--game-accent); }
.ps-move:disabled                 { opacity: 0.35; cursor: not-allowed; }
.ps-move:focus-visible            { outline: 2px solid var(--game-accent); outline-offset: 1px; }
.ps-foot { display: flex; gap: var(--space-3); }


/* ---------- WhichVersionGame (wv-*) ---------- */
/* Variant-discrimination drill: light surface theme with timeline + option cards. */

.wv-setup-wrap  { max-width: 480px; margin: 0 auto; padding: 1.5rem 1rem; }
.wv-back        { display: inline-block; margin-bottom: 1rem; font-size: 0.9rem; color: var(--game-light-primary); text-decoration: none; }
.wv-back:hover  { color: var(--game-light-primary); text-decoration: underline; }
.wv-blurb       { color: var(--game-text-muted); font-size: 0.95rem; margin-bottom: 1.2rem; }
.wv-setup       { display: flex; flex-direction: column; gap: 1.2rem; }
.wv-field       { display: flex; flex-direction: column; gap: 0.45rem; }
.wv-field > span { font-size: 0.85rem; font-weight: 600; color: var(--game-text-muted); }
.wv-select-wide { padding: 0.6rem 0.7rem; border: 1px solid var(--game-light-border); border-radius: 8px; background: var(--color-white); font-size: 1rem; }
.wv-start       { font-size: 1.1rem; padding: 0.8rem 1.4rem; }
.wv-error       { color: var(--game-light-danger); }

.wv-howto {
    margin: 0 0 1.3rem;
    padding-left: 1.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: 46ch;
    color: var(--game-text-muted);
    font-size: 0.9rem;
    line-height: 1.45;
}
.wv-howto-q, .wv-cap-q, .wv-ask-q {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.2rem; height: 1.2rem;
    border-radius: var(--radius-full);
    background: var(--game-light-primary);
    color: var(--color-white);
    font-weight: 800;
    font-size: 0.78rem;
    vertical-align: middle;
}
.wv-howto-hl {
    color: var(--game-light-warn);
    background: var(--game-light-warn-bg);
    border-radius: 4px;
    padding: 0 0.2rem;
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 2px;
    font-weight: 600;
}

.wv-stage { display: flex; flex-direction: column; height: 100vh; }

.wv-topbar {
    flex: 0 0 3.4rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1rem;
    border-bottom: 1px solid var(--game-light-border);
    background: var(--color-white);
}
.wv-actionbar {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.8rem;
    flex-wrap: wrap;
    padding: 0.7rem 1rem;
    border-bottom: 1px solid var(--game-light-border);
    background: var(--color-white);
}
.wv-timer        { font-variant-numeric: tabular-nums; font-size: 1.7rem; font-weight: 800; color: var(--game-light-primary); }
.wv-progress     { font-size: 0.95rem; color: var(--game-text-muted); }
.wv-accuracy     { font-size: 0.95rem; color: #444; }
.wv-cancel       { margin-left: auto; border: none; background: transparent; font-size: 1.3rem; color: var(--game-text-muted); cursor: pointer; padding: 0.3rem 0.5rem; }
.wv-cancel:hover { color: var(--color-charcoal); }
.wv-check-hint   { font-size: 0.85rem; color: var(--game-text-muted); }
.wv-result-inline { font-size: 1rem; color: var(--game-text-muted); }
.wv-result-inline strong { color: var(--game-light-primary); font-size: 1.15rem; }
.wv-action-spacer { flex: 1 1 auto; }

.wv-timeline-caption {
    flex: 0 0 auto;
    margin: 0;
    padding: 0.5rem 1rem 0;
    text-align: center;
    color: var(--game-text-muted);
    font-size: 0.82rem;
}
.wv-timeline {
    flex: 0 0 auto;
    max-height: 24vh;
    overflow-y: auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    padding: 0.8rem 1rem;
    border-bottom: 1px solid var(--game-light-border);
}
.wv-tl-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.6rem;
    border-radius: var(--radius-full);
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
    background: #f3f3f6;
    color: var(--game-text-muted);
    border: 1px solid transparent;
}
.wv-tl-pill .wv-tl-label { line-height: 1.1; }
.wv-tl-pill.is-variant { background: var(--color-white); border: 1px dashed var(--game-light-border); color: var(--color-charcoal); }
.wv-tl-pill.is-active  { border: 2px solid var(--game-light-primary); color: var(--game-light-primary); background: color-mix(in srgb, var(--game-light-primary) 10%, #fff); animation: wv-pulse 1.3s ease-in-out infinite; }
.wv-tl-pill.is-filled  { background: var(--game-light-success-bg); border: 1px solid var(--game-light-success); color: var(--game-light-success); animation: none; }
.wv-tl-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 1.25rem; height: 1.25rem; padding: 0 0.2rem; border-radius: var(--radius-full); font-size: 0.78rem; font-weight: 800; }
.wv-tl-badge.is-q     { background: var(--game-light-primary); color: var(--color-white); }
.wv-tl-badge.is-q-dim { background: rgba(0,0,0,0.1); color: var(--game-text-muted); }
.wv-tl-badge.is-placed { background: var(--game-light-success); color: var(--color-white); }
@keyframes wv-pulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--game-light-primary) 45%, transparent); }
    50%       { box-shadow: 0 0 0 5px color-mix(in srgb, var(--game-light-primary) 0%, transparent); }
}

.wv-struct {
    flex: 0 0 auto;
    max-height: 32vh;
    overflow-y: auto;
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    justify-content: center;
    gap: 0.5rem;
    padding: 1rem;
    border-bottom: 1px solid var(--game-light-border);
}
.wv-ctx {
    display: inline-flex;
    align-items: center;
    padding: 0.45rem 0.7rem;
    border-radius: 8px;
    background: #f3f3f6;
    color: var(--game-text-muted);
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
}
.wv-slot {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    min-width: 6rem;
    padding: 0.5rem 0.7rem;
    border-radius: 10px;
    background: var(--color-white);
    border: 2px dashed var(--game-light-border);
    cursor: pointer;
    transition: border-color var(--duration-fast), background var(--duration-fast), box-shadow var(--duration-fast);
}
.wv-slot-label  { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--game-text-muted); font-weight: 700; }
.wv-slot-empty  { font-size: 1.3rem; font-weight: 800; color: var(--game-light-primary); line-height: 1; }
.wv-slot-tag    { font-size: 0.95rem; font-weight: 800; color: var(--color-charcoal); }
.wv-slot-fix    { font-size: 0.72rem; color: var(--game-light-danger); }
.wv-slot.is-filled    { border-style: solid; border-color: var(--game-light-primary); }
.wv-slot.is-droppable { box-shadow: 0 0 0 2px color-mix(in srgb, var(--game-light-primary) 40%, transparent); }
.wv-slot.is-correct   { border-style: solid; background: var(--game-light-success-bg); border-color: var(--game-light-success); cursor: default; }
.wv-slot.is-correct .wv-slot-tag { color: var(--game-light-success); }
.wv-slot.is-wrong     { border-style: solid; background: var(--game-light-danger-bg); border-color: var(--game-light-danger); cursor: default; }
.wv-slot.is-wrong .wv-slot-tag   { color: var(--game-light-danger); }

.wv-instruction { flex: 0 0 auto; text-align: center; padding: 0.6rem 1rem 0; color: var(--game-text-muted); font-size: 0.9rem; }
.wv-selhint     { display: block; margin-top: 0.2rem; color: var(--game-light-primary); font-size: 0.85rem; }

.wv-vtray {
    flex: 1 1 auto;
    overflow-y: auto;
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    align-content: flex-start;
    justify-content: center;
    padding: 1rem;
    width: 100%;
    max-width: 760px;
    margin: 0 auto;
}
.wv-vcard {
    flex: 0 1 240px;
    align-self: flex-start;
    padding: 0.8rem 1rem;
    border-radius: 14px;
    border: 1px solid var(--game-light-border);
    background: var(--color-white);
    color: var(--color-charcoal);
    cursor: grab;
    user-select: none;
    transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
}
.wv-vcard:hover   { border-color: var(--game-light-primary); }
.wv-vcard:active  { cursor: grabbing; }
.wv-vcard.is-selected { border-color: var(--game-light-primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--game-light-primary) 35%, transparent); }
.wv-vcard-head    { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 800; color: var(--game-light-primary); margin-bottom: 0.3rem; }
.wv-vcard-lyrics  { font-size: 1rem; line-height: 1.45; }

.wv-ask {
    flex: 0 0 auto;
    padding: 0.9rem 1rem 0.6rem;
    text-align: center;
    animation: wv-slide-in 0.2s ease-out;
}
@keyframes wv-slide-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.wv-ask-text { font-size: 1.25rem; font-weight: 700; line-height: 1.3; }
.wv-ask-sub  { font-size: 0.9rem; color: var(--game-text-muted); margin-top: 0.2rem; }
.wv-ask-legend { margin: 0.3rem 0 0; color: var(--game-text-muted); font-size: 0.82rem; }

.wv-linemap {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    width: 100%;
    max-width: 320px;
    margin: 0.6rem auto 0.2rem;
}
.wv-linemap-row  { display: flex; align-items: center; gap: 0.5rem; }
.wv-linemap-arrow { flex: 0 0 1rem; text-align: right; color: var(--game-light-warn); font-weight: 800; font-size: 1rem; }
.wv-linemap-bar  { flex: 1 1 auto; height: 0.55rem; border-radius: var(--radius-full); background: #e7e6ef; }
.wv-linemap-row.is-target .wv-linemap-bar { background: var(--game-light-warn-bg); box-shadow: inset 0 0 0 2px var(--game-light-warn-border); }

.wv-options {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    width: 100%;
    max-width: 600px;
    margin: 0 auto;
}
.wv-card {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    width: 100%;
    text-align: left;
    padding: 0.9rem 1rem;
    border: 1px solid var(--game-light-border);
    border-radius: 14px;
    background: var(--color-white);
    color: var(--color-charcoal);
    font-size: 1.05rem;
    line-height: 1.5;
    cursor: pointer;
    transition: border-color var(--duration-fast), background var(--duration-fast);
}
.wv-card:hover { border-color: var(--game-light-primary); }
.wv-card-head  { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700; color: var(--game-text-muted); display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.2rem; }
.wv-card-mark  { font-size: 1rem; }
.wv-card-line  { display: block; }
.wv-tok.is-variant {
    color: var(--game-light-warn);
    background: var(--game-light-warn-bg);
    border-radius: 4px;
    padding: 0 0.15rem;
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 2px;
    font-weight: 600;
}
.wv-card.is-correct { background: var(--game-light-success-bg); border-color: var(--game-light-success); }
.wv-card.is-correct .wv-card-head { color: var(--game-light-success); }
.wv-card.is-wrong   { background: var(--game-light-danger-bg); border-color: var(--game-light-danger); cursor: default; animation: wv-shake 0.25s; }
.wv-card.is-wrong .wv-card-head   { color: var(--game-light-danger); }
@keyframes wv-shake {
    0%, 100% { transform: translateX(0); }
    25%       { transform: translateX(-5px); }
    75%       { transform: translateX(5px); }
}

.wv-checkbar      { flex: 0 0 auto; display: flex; align-items: center; gap: 0.8rem; justify-content: center; padding: 0.8rem 1rem 1.1rem; border-top: 1px solid var(--game-light-border); }
.wv-checkbar-hint { font-size: 0.85rem; color: var(--game-text-muted); }
.wv-banner {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    padding: 1rem;
    border-top: 1px solid var(--game-light-border);
    background: color-mix(in srgb, var(--game-light-primary) 5%, var(--color-white));
}

.wv-check.is-ready { animation: wv-check-pulse 1.4s ease-in-out infinite; }
@keyframes wv-check-pulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--game-light-primary) 55%, transparent); }
    50%       { box-shadow: 0 0 0 7px color-mix(in srgb, var(--game-light-primary) 0%, transparent); }
}

.wv-results {
    height: 100vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 1.5rem 1rem;
    text-align: center;
}
.wv-result-score { font-size: 2rem; font-weight: 800; color: var(--game-light-primary); }
.wv-result-sub   { font-variant-numeric: tabular-nums; font-size: 1rem; color: var(--game-text-muted); }
.wv-result-best  { font-size: 0.95rem; color: var(--game-text-muted); font-variant-numeric: tabular-nums; }
.wv-result-best.is-new { color: var(--game-light-success); font-weight: 700; }
.wv-trouble-list { width: 100%; max-width: 440px; text-align: left; margin-top: 0.5rem; }
.wv-trouble-list h4 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--game-light-danger); margin: 0 0 0.3rem; }
.wv-trouble-line { font-size: 0.9rem; padding: 0.18rem 0; border-bottom: 1px dotted var(--game-light-border); }
.wv-trouble-more { font-size: 0.8rem; color: var(--game-text-muted); margin-top: 0.25rem; }
.wv-result-actions { display: flex; gap: 0.6rem; margin-top: 0.8rem; }

@media (max-width: 600px) {
    .wv-ask-text  { font-size: 1.1rem; }
    .wv-card      { font-size: 1rem; }
    .wv-tl-pill   { font-size: 0.78rem; }
    .wv-vcard     { flex-basis: 100%; }
    .wv-slot      { min-width: 5rem; }
}
@media (prefers-reduced-motion: reduce) {
    .wv-ask                   { animation: none; }
    .wv-card.is-wrong         { animation: none; }
    .wv-tl-pill.is-active     { animation: none; box-shadow: 0 0 0 2px var(--game-light-primary); }
    .wv-check.is-ready        { animation: none; box-shadow: 0 0 0 3px var(--game-light-primary); }
}


/* ---------- PracticeDashboard (practice-*) ---------- */

.practice-page {
    max-width: 720px;
    margin: 0 auto;
    padding: 1rem;
}
.practice-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.2rem;
}
.practice-head h1  { font-size: 1.6rem; margin: 0; }
.practice-play     { white-space: nowrap; text-decoration: none; }

.practice-mode {
    display: inline-flex;
    gap: 4px;
    padding: 3px;
    border-radius: var(--radius-full);
    background: var(--game-light-bg);
    border: 1px solid var(--game-light-border);
}
.practice-mode-btn {
    border: none;
    background: none;
    color: var(--game-text-muted);
    font-weight: 600;
    font-size: 0.9rem;
    padding: 0.35rem 0.95rem;
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: color var(--duration-fast), background var(--duration-fast);
}
.practice-mode-btn:hover            { color: var(--color-charcoal); }
.practice-mode-btn.is-active        { background: var(--game-light-primary); color: var(--color-white); }
.practice-mode-btn:focus-visible    { outline: 2px solid var(--game-light-primary); outline-offset: 2px; }

.practice-games {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.7rem;
    margin-bottom: 1.6rem;
}
.practice-game-btn {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    padding: 0.9rem 1rem;
    border-radius: 12px;
    text-decoration: none;
    color: var(--color-white);
    background: var(--game-light-primary);
    transition: filter var(--duration-fast);
}
.practice-game-btn:hover       { filter: brightness(1.07); }
.practice-game-btn-name        { font-weight: 700; font-size: 1.1rem; }
.practice-game-btn-desc        { font-size: 0.8rem; opacity: 0.9; }

@media (max-width: 520px) { .practice-games { grid-template-columns: 1fr; } }

.practice-error { color: var(--game-light-danger); }
.practice-empty {
    padding: 1.5rem;
    border: 1px dashed var(--game-light-border);
    border-radius: 12px;
    text-align: center;
}
.practice-empty-sub { font-size: 0.9rem; color: var(--game-text-muted); margin-top: 0.4rem; }

.practice-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-bottom: 1.2rem;
    border-bottom: 1px solid var(--game-light-border);
}
.practice-tab {
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 0.5rem 0.85rem;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--game-text-muted);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    border-radius: 8px 8px 0 0;
    transition: color var(--duration-fast), background var(--duration-fast);
}
.practice-tab:hover     { color: var(--color-charcoal); background: var(--game-light-bg); }
.practice-tab.is-active { color: var(--game-light-primary); border-bottom-color: var(--game-light-primary); }

.practice-tab-wrap {
    display: inline-flex;
    align-items: center;
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    border-radius: 8px 8px 0 0;
}
.practice-tab-wrap.is-active                    { border-bottom-color: var(--game-light-primary); }
.practice-tab-wrap.is-active .practice-tab-pinned { color: var(--game-light-primary); }
.practice-tab-pinned { border-bottom: none; margin-bottom: 0; padding-right: 0.25rem; }
.practice-tab-x {
    border: none;
    background: transparent;
    cursor: pointer;
    color: #aaa;
    font-size: 0.72rem;
    line-height: 1;
    padding: 0.25rem 0.45rem 0.25rem 0.1rem;
    border-radius: 6px;
}
.practice-tab-x:hover { color: var(--game-light-danger); background: var(--game-light-bg); }
.practice-tab-add     { display: inline-flex; align-items: center; }
.practice-tab-addbtn  { color: var(--game-light-primary); }
.practice-tab-picker {
    padding: 0.4rem 0.5rem;
    margin-bottom: 0.3rem;
    border: 1px solid var(--game-light-border);
    border-radius: 8px;
    background: var(--color-white);
    font-size: 0.9rem;
}

.practice-metrics {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.7rem;
    margin-bottom: 1.6rem;
}
.practice-metric {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    padding: 0.9rem 0.5rem;
    border-radius: 12px;
    background: var(--game-light-bg);
    border: 1px solid var(--game-light-border);
}
.practice-metric-value {
    font-size: 1.7rem;
    font-weight: 800;
    line-height: 1;
    color: var(--game-light-primary);
}
.practice-metric-label {
    font-size: 0.78rem;
    color: var(--game-text-muted);
    text-align: center;
}
.practice-metric.is-trouble .practice-metric-value { color: var(--game-light-danger); }

.practice-subhead {
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--game-text-muted);
    margin: 0 0 0.6rem;
}
.practice-songs    { display: flex; flex-direction: column; gap: 0.6rem; }
.practice-song {
    display: block;
    padding: 0.8rem 1rem;
    border: 1px solid var(--game-light-border);
    border-radius: 12px;
    text-decoration: none;
    color: inherit;
    transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
}
.practice-song:hover { border-color: var(--game-light-primary); box-shadow: 0 2px 10px rgba(106, 90, 205, 0.12); }
.practice-song-top  { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
.practice-song-name { font-weight: 700; font-size: 1.05rem; }
.practice-song-pct  { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--game-light-primary); }

.practice-bar { height: 7px; border-radius: var(--radius-full); background: var(--game-light-border); margin: 0.45rem 0; overflow: hidden; }
.practice-bar-fill { height: 100%; border-radius: var(--radius-full); background: var(--game-light-primary); }

.practice-song-badges { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.practice-badge { font-size: 0.75rem; padding: 0.1rem 0.5rem; border-radius: var(--radius-full); font-weight: 600; }
.practice-badge.due     { background: var(--game-light-badge-due);  color: var(--game-light-badge-due-text); }
.practice-badge.trouble { background: var(--game-light-danger-bg);  color: var(--game-light-danger); }
.practice-badge.muted   { background: var(--game-light-bg); color: var(--game-text-muted); font-weight: 500; }

@media (max-width: 520px) { .practice-metrics { grid-template-columns: repeat(2, 1fr); } }


/* ---------- NoteLineGame (inline <style> extracted) ---------- */
/* Note-reading drill: note grid + multiple-choice answer buttons. */

.cg-game-wrap {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    padding: 16px;
    max-width: 720px;
    margin: 0 auto;
}
.cg-phrase-label {
    font-size: 1rem;
    font-weight: 600;
    color: var(--game-text-muted);
    margin: 12px 0 4px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.cg-note-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 12px 0;
}
.cg-note-cell {
    min-width: 44px;
    padding: 6px 8px;
    text-align: center;
    border-radius: 6px;
    border: 1px solid var(--game-border);
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
    font-size: 0.85rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    background: var(--game-card);
    transition: background var(--duration-fast), border-color var(--duration-fast);
}
.cg-note-cell--rest  { opacity: 0.4; border-style: dashed; }
.cg-note-cell--blank { border-color: var(--game-accent); border-width: 2px; font-size: 0.95rem; min-width: 50px; }
.cg-note-cell--active {
    border-color: var(--game-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--game-accent) 35%, transparent);
    animation: nl-pulse 1.2s ease-in-out infinite;
}
@keyframes nl-pulse {
    0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--game-accent) 35%, transparent); }
    50%       { box-shadow: 0 0 0 6px color-mix(in srgb, var(--game-accent) 15%, transparent); }
}
.cg-note-cell--correct {
    border-color: var(--game-success);
    background: color-mix(in srgb, var(--game-success) 15%, var(--game-card));
    animation: none;
}
.cg-note-cell--wrong {
    border-color: var(--game-danger);
    background: color-mix(in srgb, var(--game-danger) 20%, var(--game-card));
    animation: nl-shake 0.4s ease-in-out;
}
@keyframes nl-shake {
    0%, 100% { transform: translateX(0); }
    20%       { transform: translateX(-4px); }
    60%       { transform: translateX(4px); }
}
.cg-syllable {
    font-size: 0.7rem;
    color: var(--game-text-muted);
    font-family: var(--font-body);
}
.cg-choices-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    max-width: 360px;
    margin: 16px auto;
}
.cg-choice-btn {
    min-height: 48px;
    border: 1px solid var(--game-border);
    border-radius: 8px;
    background: var(--game-card);
    color: var(--game-text);
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
    font-size: 1rem;
    cursor: pointer;
    transition: background var(--duration-fast), border-color var(--duration-fast);
}
.cg-choice-btn:hover:not(:disabled) { background: var(--game-card-alt); border-color: var(--game-accent); }
.cg-choice-btn--wrong {
    border-color: var(--game-danger);
    background: color-mix(in srgb, var(--game-danger) 20%, var(--game-card));
    opacity: 0.5;
    cursor: not-allowed;
}
.cg-result-list {
    margin: 16px 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.cg-result-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    border-radius: 6px;
    border: 1px solid var(--game-border);
    font-size: 0.9rem;
}
.cg-result-row.is-clean  { border-color: var(--game-success); background: color-mix(in srgb, var(--game-success) 10%, transparent); }
.cg-result-row.is-missed { border-color: var(--game-danger);  background: color-mix(in srgb, var(--game-danger)  10%, transparent); }
/* AI Note: .cg-foot is also used by ChordClozeGame; both need margin-top + text-align, which this rule covers. */
.cg-foot { margin-top: 24px; text-align: center; }

@media (prefers-reduced-motion: reduce) {
    .cg-note-cell--active,
    .cg-note-cell--wrong { animation: none; }
    .wv-check.is-ready   { animation: none; }
}


/* =========================================================
   39. STORE PAGES
   (Store, StoreProduct, StoreCart)
   ========================================================= */

/* ---------- Store — product grid ---------- */

.store-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr));
    gap: var(--space-5);
    margin-top: var(--space-5);
}

.store-card {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--color-white);
    transition: box-shadow var(--duration-fast), transform var(--duration-fast);
    text-decoration: none;
    color: inherit;
}
.store-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.store-card-media {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    display: block;
    background: var(--color-cream-deep);
}

.store-card-noimage {
    width: 100%;
    aspect-ratio: 1 / 1;
    background: var(--color-cream-deep);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
}

.store-card-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    flex: 1 1 auto;
}

.store-card-price {
    font-weight: 700;
    color: var(--color-accent);
    margin-top: auto;
}


/* ---------- StoreProduct — detail page ---------- */

.store-detail-crumbs {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    margin-bottom: var(--space-4);
}

.store-detail {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);   /* overflow guard on both columns */
    gap: var(--space-7);
    align-items: flex-start;
    margin-top: var(--space-5);
}
@media (max-width: 720px) {
    .store-detail { grid-template-columns: 1fr; }
}

.store-detail-main {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.store-detail-noimage {
    width: 100%;
    aspect-ratio: 1 / 1;
    background: var(--color-cream-deep);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
    border-radius: var(--radius-md);
}

.store-detail-thumbs {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-top: var(--space-2);
}

.store-detail-thumb {
    width: 60px;
    height: 60px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    border: 2px solid var(--color-cream-mid);
    cursor: pointer;
    transition: border-color var(--duration-fast);
}
.store-detail-thumb.is-selected { border-color: var(--color-accent); }

.store-detail-sku {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
}

.store-detail-added {
    color: var(--color-accent);
    font-weight: 700;
}


/* ---------- StoreCart — cart line items ---------- */

.cart-item {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
}

.cart-thumb {
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: var(--color-cream-deep);
    flex: 0 0 auto;
}

/* ---------- StoreCheckout — test-mode hint ---------- */

.store-test-hint {
    background: var(--color-cream-deep);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    margin-bottom: var(--space-4);
}

/* ---------- StorefrontCheckoutReturn — order confirmation ---------- */

.checkout-return {
    max-width: 600px;
    margin-top: var(--space-6);
}

.checkout-return-meta {
    background: var(--color-cream-light);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-md);
    padding: var(--space-4) var(--space-5);
    margin-bottom: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.checkout-return-status-pending {
    display: inline-block;
    background: var(--color-cream-deep);
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
    font-weight: 600;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-full);
}

.checkout-return-status-paid {
    display: inline-block;
    background: #d1fae5;
    color: #065f46;
    font-size: var(--text-sm);
    font-weight: 600;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-full);
}

.checkout-return-refresh {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    margin-bottom: var(--space-4);
}

.checkout-return-address {
    margin-top: var(--space-5);
}

.checkout-return-address-block {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    line-height: 1.7;
    margin-top: var(--space-2);
}


/* =========================================================
   40. LAYOUT — RECONNECT MODAL
   (ReconnectModal.razor — extracted from isolated CSS)
   ========================================================= */

/* Blazor reconnect modal — state-driven show/hide via .components-reconnect-* classes. */

#components-reconnect-modal {
    display: none;
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    z-index: 1000;
    overflow: hidden;
    animation: components-reconnect-fade-in 0.3s ease-out;
    background: rgba(0, 0, 0, 0.5);
}

/* The host element carries the state class; show the modal for non-hidden states. */
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
    align-items: center;
    justify-content: center;
}

.components-reconnect-dialog {
    background: var(--color-white);
    border-radius: var(--radius-lg);
    padding: var(--space-7) var(--space-8);
    text-align: center;
    max-width: 400px;
    width: 90%;
    box-shadow: var(--shadow-lg);
}

.components-reconnect-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--color-charcoal);
    margin-bottom: var(--space-3);
}

.components-reconnect-body {
    font-size: var(--text-sm);
    color: var(--color-charcoal-muted);
    margin-bottom: var(--space-5);
}

/* Reconnect state tokens — blues scoped to the modal only. */
:root {
    --reconnect-blue:       #0087ff;
    --reconnect-blue-light: #6b9ed2;
    --reconnect-blue-dark:  #3b6ea2;
}

.components-rejoining-animation {
    display: inline-block;
    margin-bottom: var(--space-4);
}
.components-rejoining-animation span {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: var(--radius-full);
    background: var(--reconnect-blue);
    margin: 0 3px;
    animation: components-reconnect-bounce 1.2s ease-in-out infinite;
}
.components-rejoining-animation span:nth-child(2) { animation-delay: 0.15s; }
.components-rejoining-animation span:nth-child(3) { animation-delay: 0.30s; }

@keyframes components-reconnect-bounce {
    0%, 80%, 100% { transform: scale(0.6); background: var(--reconnect-blue-light); }
    40%            { transform: scale(1.0); background: var(--reconnect-blue); }
}
@keyframes components-reconnect-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.components-reconnect-failed .components-reconnect-dialog { border-top: 4px solid var(--reconnect-blue-dark); }
.components-reconnect-rejected .components-reconnect-dialog { border-top: 4px solid var(--color-accent); }

@media (prefers-reduced-motion: reduce) {
    .components-rejoining-animation span { animation: none; }
    #components-reconnect-modal          { animation: none; }
}


/* =========================================================
   41. ADMIN TOOLS
   (StorefrontCatalog, LyricSheet, LyricMigration,
    SongArrangementsAdmin, TabView, ChordChartEditor,
    InstrumentLineEditor, GrandStaffView, MelodyView,
    TabEditor)
   ========================================================= */

/* ---------- StorefrontCatalog — image manager grid ---------- */

.storefront-image-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 140px), 1fr));
    gap: var(--space-3);
    margin-top: var(--space-3);
}

.storefront-image-card {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--color-white);
}

.storefront-image-thumb {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    display: block;
    background: var(--color-cream-deep);
}

.storefront-image-badge {
    position: relative;
}
.storefront-image-badge::after {
    content: attr(data-label);
    position: absolute;
    top: var(--space-1);
    left: var(--space-1);
    background: rgba(0, 0, 0, 0.65);
    color: var(--color-white);
    font-size: var(--text-xs);
    padding: 1px var(--space-2);
    border-radius: var(--radius-sm);
}

.storefront-image-actions {
    display: flex;
    gap: var(--space-2);
    padding: var(--space-2);
    justify-content: flex-end;
}

.storefront-image-alt {
    font-size: var(--text-xs);
    color: var(--color-charcoal-muted);
    padding: 0 var(--space-2) var(--space-2);
    word-break: break-all;
}


/* ---------- LyricSheet — structured lyric display + print ---------- */

.lyric-sheet-section  { margin-bottom: 1.25rem; }

.lyric-sheet-heading {
    font-weight: 700;
    font-size: 0.9rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-accent);
    margin: 0 0 0.2rem;
}

.lyric-sheet-notes {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 1rem;
    margin: 0 0 0.4rem;
}
.lyric-sheet-note {
    font-size: 0.78rem;
    font-style: italic;
    color: var(--color-charcoal-mid);
}

.lyric-sheet-line {
    font-family: var(--font-body);
    line-height: 1.55;
    white-space: pre-wrap;
    word-break: break-word;
}

.lyric-sheet-gap { height: 0.6rem; }

.lyric-sheet-instrumental {
    font-style: italic;
    color: var(--color-charcoal-muted);
}

@media print {
    .lyric-sheet-heading { color: #000; break-after: avoid; }
    .lyric-sheet-note    { color: #333; }
}


/* ---------- LyricMigration — side-by-side diff + lint ---------- */

.lyric-migration-status { margin-left: 0.75rem; font-size: 0.9rem; }

.lyric-migration-lint {
    margin: 0.25rem 0 0.5rem;
    padding-left: 1.1rem;
    color: #9a5b00;
    font-size: 0.85rem;
}

.lyric-migration-diff {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    margin: 0.5rem 0;
}
.lyric-migration-diff h4 { margin: 0 0 0.25rem; font-size: 0.85rem; }
.lyric-migration-diff pre {
    white-space: pre-wrap;
    word-break: break-word;
    font-size: 0.8rem;
    line-height: 1.45;
    background: var(--color-cream-deep);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-md);
    padding: 0.5rem 0.6rem;
    max-height: 340px;
    overflow: auto;
}
@media (max-width: 720px) { .lyric-migration-diff { grid-template-columns: 1fr; } }


/* ---------- SongArrangementsAdmin (arr-*) ---------- */

.admin-page-wide { max-width: none; }

.arr-search   { margin-bottom: var(--space-3); }
.arr-progress { margin: var(--space-2) 0 var(--space-3); font-size: var(--text-xs); color: var(--color-charcoal-muted); }

.arr-queue {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    max-height: 58vh;
    overflow-y: auto;
    padding-right: var(--space-2);
}

.arr-tag {
    display: inline-block;
    margin-left: var(--space-2);
    padding: 0 var(--space-2);
    font-size: var(--text-xs);
    border-radius: var(--radius-full);
    background: var(--color-accent-dim);
    color: var(--color-accent);
}

.arr-badges { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.arr-badge {
    padding: 1px var(--space-3);
    font-size: var(--text-xs);
    line-height: 1.6;
    border-radius: var(--radius-full);
    background: var(--color-cream-deep);
    color: var(--color-charcoal-mid);
    border: 1px solid var(--color-cream-mid);
    white-space: nowrap;
}
.arr-badge-empty { background: transparent; color: var(--color-charcoal-muted); border-style: dashed; }
.arr-badge-state-needsreview { background: #FBEED9; color: #8A5A12; border-color: #E9D3A8; }
.arr-badge-state-approved    { background: #E2F0E0; color: #2F6B33; border-color: #BFE0BD; }
.arr-badge-state-draft       { background: var(--color-cream-deep); color: var(--color-charcoal-muted); }
.arr-badge-conf-low          { color: #9A3B2A; }
.arr-badge-conf-medium       { color: #8A5A12; }
.arr-badge-conf-high         { color: #2F6B33; }

.arr-quick-approve {
    display: inline-block;
    margin-top: var(--space-2);
    padding: 1px var(--space-3);
    font-size: var(--text-xs);
    border-radius: var(--radius-full);
    border: 1px solid #BFE0BD;
    background: #E2F0E0;
    color: #2F6B33;
    cursor: pointer;
}
.arr-quick-approve:hover { background: #CFE7CC; }

.arr-detail-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.arr-field-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    align-items: flex-end;
}
.arr-field-row > .admin-field { flex: 1 1 8rem; margin-bottom: 0; }
.arr-hint { font-weight: 400; font-size: var(--text-xs); color: var(--color-charcoal-muted); }

.arr-chart-block { margin: var(--space-4) 0 var(--space-5); }
.arr-chart-head {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}

.arr-preview {
    margin: var(--space-5) 0;
    padding: var(--space-4);
    background: var(--color-cream-deep);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-md);
}
.arr-preview-head {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}
.arr-preview-title {
    font-family: var(--font-display);
    font-size: var(--text-md);
    color: var(--color-charcoal);
}
.arr-transpose { display: flex; align-items: center; gap: var(--space-2); }
.arr-tpose-btn {
    width: 1.6rem; height: 1.6rem;
    border-radius: var(--radius-full);
    border: 1px solid var(--color-cream-dark);
    background: var(--color-white);
    color: var(--color-charcoal);
    font-size: var(--text-md);
    line-height: 1;
    cursor: pointer;
}
.arr-tpose-btn:hover    { border-color: var(--color-accent); color: var(--color-accent); }
.arr-tpose-readout      { font-size: var(--text-xs); color: var(--color-charcoal-mid); min-width: 9rem; text-align: center; }
.arr-tpose-note         { color: var(--color-accent); }
.arr-tpose-reset        { font-size: var(--text-xs); background: none; border: none; color: var(--color-accent); cursor: pointer; text-decoration: underline; }

.arr-preview-body  { display: flex; flex-direction: column; gap: var(--space-3); }
.arr-prev-section  { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2); }
.arr-prev-heading  { flex: 0 0 7rem; font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-charcoal-muted); }
.arr-chip {
    display: inline-block;
    padding: 1px var(--space-3);
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
    font-size: var(--text-sm);
    border-radius: var(--radius-sm);
    background: var(--color-white);
    color: var(--color-charcoal);
    border: 1px solid var(--color-cream-mid);
}
.arr-prev-scale { font-size: var(--text-sm); font-style: italic; color: var(--color-charcoal-muted); }

.arr-instruments .admin-field { margin-bottom: var(--space-3); }
.arr-provenance { margin: var(--space-4) 0; font-size: var(--text-sm); color: var(--color-charcoal-mid); }
.arr-provenance summary { cursor: pointer; color: var(--color-charcoal-muted); }
.arr-rejected { margin: var(--space-3) 0 0; padding-left: var(--space-5); color: var(--color-charcoal-muted); }
.arr-rejected li { margin-bottom: var(--space-2); }

.admin-button-approve { background: #2F6B33; color: var(--color-white); border-color: #2F6B33; }
.admin-button-approve:hover { background: #265628; }


/* ---------- TabView (tab-*) ---------- */

.tab-empty  { font-size: var(--text-sm); font-style: italic; color: var(--color-charcoal-muted); }
.tab-phrase { margin-bottom: var(--space-4); }
.tab-plabel {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-charcoal-muted);
    margin-bottom: var(--space-1);
}
.tab-grid {
    display: grid;
    align-items: stretch;
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
    font-size: var(--text-sm);
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    overflow-x: auto;
}
.tab-open {
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    color: var(--color-charcoal-muted);
    background: var(--color-cream-deep);
    border-right: 1px solid var(--color-cream-mid);
    padding: 0 var(--space-1);
}
.tab-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-cream-dark);
    padding: 1px 2px;
    min-height: 1.5em;
}
.tab-cell-on { color: var(--color-charcoal); font-weight: 600; }
.tab-tech    { font-size: var(--text-xs); color: var(--color-accent); }


/* ---------- ChordChartEditor (cce-*) ---------- */

.cce { display: flex; flex-direction: column; gap: var(--space-4); }
.cce-error { margin: 0 0 var(--space-2); }
.cce-empty {
    padding: var(--space-4);
    border: 1px dashed var(--color-cream-dark);
    border-radius: var(--radius-md);
    color: var(--color-charcoal-muted);
    text-align: center;
}
.cce-sections { display: flex; flex-direction: column; gap: var(--space-3); }
.cce-section {
    padding: var(--space-3) var(--space-4);
    background: var(--color-cream-deep);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-md);
    transition: opacity var(--duration-fast), border-color var(--duration-fast), background var(--duration-fast);
}
.cce-section-dragging  { opacity: 0.5; }
.cce-section-droptarget { border-color: var(--color-accent); background: var(--color-cream-mid); }

.cce-drag {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-charcoal-muted);
    cursor: grab;
    padding: 0 2px;
}
.cce-drag:hover  { color: var(--color-accent); }
.cce-drag:active { cursor: grabbing; }

.cce-section-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}
.cce-heading {
    flex: 1 1 auto;
    min-width: 6rem;
    font-family: var(--font-display);
    font-size: var(--text-md);
    color: var(--color-charcoal);
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    padding: 2px var(--space-2);
}
.cce-heading:focus { outline: none; border-color: var(--color-accent); }
.cce-type {
    flex: 0 0 auto;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-charcoal-muted);
    padding: 1px var(--space-2);
    border-radius: var(--radius-full);
    background: var(--color-cream-mid);
}
.cce-section-tools { flex: 0 0 auto; display: inline-flex; gap: 2px; }
.cce-tool {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem; height: 1.5rem;
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-cream-dark);
    background: var(--color-white);
    color: var(--color-charcoal-mid);
    font-size: var(--text-sm);
    line-height: 1;
    cursor: pointer;
}
.cce-tool:hover:not(:disabled)        { border-color: var(--color-accent); color: var(--color-accent); }
.cce-tool:disabled                     { opacity: 0.35; cursor: default; }
.cce-tool-danger:hover:not(:disabled)  { border-color: #9A3B2A; color: #9A3B2A; }

.cce-chords { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; }
.cce-ins {
    border: none;
    background: none;
    cursor: pointer;
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
    line-height: 1;
    padding: 0 1px;
    opacity: 0.35;
    transition: opacity var(--duration-fast), color var(--duration-fast);
}
.cce-ins:hover { opacity: 1; color: var(--color-accent); }

.cce-chip {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    padding: 1px 2px 1px var(--space-2);
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
}
.cce-chip:focus-within { border-color: var(--color-accent); }
.cce-chip-unknown { border-style: dashed; border-color: var(--color-cream-dark); background: var(--color-cream-deep); }

.cce-chip-input {
    border: none;
    background: transparent;
    outline: none;
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    padding: 1px 0;
}
.cce-chip-x {
    border: none;
    background: none;
    cursor: pointer;
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
    line-height: 1;
    padding: 0 2px;
    border-radius: var(--radius-sm);
}
.cce-chip-x:hover { color: #9A3B2A; }

.cce-addchord {
    margin-left: var(--space-2);
    border: 1px dashed var(--color-cream-dark);
    background: transparent;
    color: var(--color-charcoal-mid);
    font-size: var(--text-xs);
    border-radius: var(--radius-sm);
    padding: 2px var(--space-2);
    cursor: pointer;
}
.cce-addchord:hover { border-color: var(--color-accent); color: var(--color-accent); }

.cce-scale { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-3); }
.cce-scale-label { flex: 0 0 auto; font-size: var(--text-xs); color: var(--color-charcoal-muted); }
.cce-scale-input {
    flex: 1 1 auto;
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    padding: 2px var(--space-2);
}
.cce-scale-input:focus { outline: none; border-color: var(--color-accent); }

.cce-sounds {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
    padding-top: var(--space-2);
    border-top: 1px dashed var(--color-cream-mid);
}
.cce-sounds-label { font-size: var(--text-xs); font-style: italic; color: var(--color-charcoal-muted); }
.cce-sounds-chip {
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
    font-size: var(--text-sm);
    color: var(--color-charcoal-mid);
    padding: 0 var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--color-cream-mid);
}

.cce-addbar       { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.cce-addbar-label { font-size: var(--text-sm); color: var(--color-charcoal-mid); }
.cce-add-select {
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    padding: 2px var(--space-2);
}

.cce-raw          { font-size: var(--text-sm); }
.cce-raw summary  { cursor: pointer; color: var(--color-charcoal-muted); font-size: var(--text-xs); }
.cce-raw-hint     { margin: var(--space-2) 0; font-size: var(--text-xs); color: var(--color-charcoal-muted); }
.cce-raw-box {
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
}


/* ---------- InstrumentLineEditor (ile-*) ---------- */

.ile {
    margin-bottom: var(--space-5);
    padding-bottom: var(--space-4);
    border-bottom: 1px solid var(--color-cream-mid);
}
.ile:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
.ile-head { font-family: var(--font-display); font-size: var(--text-md); color: var(--color-charcoal); margin-bottom: var(--space-2); }
.ile-hint { font-weight: 400; font-size: var(--text-xs); color: var(--color-charcoal-muted); }
.ile-notes {
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
}
.ile-preview { margin-top: var(--space-2); }

.ile-viewtoggle { display: inline-flex; gap: 2px; margin-bottom: var(--space-2); }
.ile-vbtn {
    border: 1px solid var(--color-cream-dark);
    background: var(--color-white);
    color: var(--color-charcoal-muted);
    font-size: var(--text-xs);
    padding: 2px var(--space-2);
    cursor: pointer;
}
.ile-vbtn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.ile-vbtn:last-child  { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.ile-vbtn-on          { background: var(--color-accent); color: var(--color-white); border-color: var(--color-accent); }

.ile-preview-label { display: block; font-size: var(--text-xs); color: var(--color-charcoal-muted); margin-bottom: var(--space-2); }

.ile-advanced { margin-top: var(--space-3); }
.ile-advanced > summary { cursor: pointer; user-select: none; font-size: var(--text-sm); color: var(--color-charcoal-muted); }

.ile-paste { margin-top: var(--space-3); }
.ile-paste > summary { cursor: pointer; user-select: none; font-size: var(--text-sm); color: var(--color-charcoal-muted); }
.ile-paste-hint { margin: var(--space-2) 0; font-size: var(--text-xs); color: var(--color-charcoal-muted); }
.ile-paste-box {
    /* AI Note: white-space: pre is required — tab columns must stay aligned; do not change to pre-wrap. */
    white-space: pre;
    overflow-x: auto;
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
}
.ile-paste-actions { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-2); }
.ile-paste-status  { font-size: var(--text-xs); color: var(--color-charcoal-muted); }


/* ---------- GrandStaffView (gs-*) ---------- */

.gs { display: flex; flex-direction: column; gap: var(--space-3); overflow-x: auto; }
.gs-empty { font-size: var(--text-sm); color: var(--color-charcoal-muted); }
.gs-label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-charcoal-muted);
    margin-bottom: 2px;
}
/* SVG canvas + overlaid glyph spans share the same origin box. */
.gs-canvas { position: relative; }
.gs-svg {
    display: block;
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
}

/* SVG element classes — stroke/fill properties target the inline SVG elements. */
.gs-line        { stroke: var(--color-charcoal-mid); stroke-width: 1; }
.gs-ledger      { stroke: var(--color-charcoal-mid); stroke-width: 1; }
.gs-barline     { stroke: var(--color-charcoal); stroke-width: 1.4; }
.gs-barline-thin { stroke: var(--color-cream-dark); stroke-width: 1; }
.gs-head        { fill: var(--color-white); stroke: var(--color-charcoal); stroke-width: 1.3; }
.gs-head-filled { fill: var(--color-charcoal); }
.gs-stem        { stroke: var(--color-charcoal); stroke-width: 1.3; }
.gs-flag        { stroke: var(--color-charcoal); stroke-width: 1.6; }

/* HTML overlaid glyph spans positioned in SVG pixel coordinates. */
.gs-glyph { position: absolute; line-height: 1; pointer-events: none; color: var(--color-charcoal); }
.gs-clef       { font-family: 'Segoe UI Symbol', 'Cambria Math', 'Bravura', serif; font-size: 34px; }
.gs-clef-bass  { font-size: 28px; }
.gs-acc        { font-family: 'Segoe UI Symbol', Arial, sans-serif; font-size: 15px; }
.gs-rest       { font-family: 'Segoe UI Symbol', 'Cambria Math', serif; font-size: 22px; }


/* ---------- MelodyView (roll-*) ---------- */
/* Vocal-melody piano roll. Row height 15px must match MelodyView.RowH. */

.roll-empty  { font-size: var(--text-sm); font-style: italic; color: var(--color-charcoal-muted); }
.roll-phrase { margin-bottom: var(--space-4); }
.roll-line   { margin-bottom: var(--space-3); }
.roll-line:last-child { margin-bottom: 0; }
.roll-plabel {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-charcoal-muted);
    margin-bottom: var(--space-1);
}
.roll-body {
    display: flex;
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    overflow: hidden;
}
.roll-keys { flex: 0 0 auto; border-right: 1px solid var(--color-cream-mid); }
.roll-key {
    height: 15px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 0 4px;
    font-size: 0.6rem;
    line-height: 1;
    color: var(--color-charcoal-muted);
    white-space: nowrap;
}
.roll-key-black { background: var(--color-cream-deep); }
.roll-scroll { flex: 1 1 auto; overflow-x: auto; }
.roll-area   { position: relative; min-width: 100%; }
.roll-bar    { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--color-cream-mid); }
.roll-note {
    position: absolute;
    background: var(--color-accent);
    border-radius: 2px;
    color: var(--color-white);
    font-size: 0.6rem;
    line-height: 1;
    overflow: hidden;
    display: flex;
    align-items: center;
}
.roll-syll { padding: 0 3px; white-space: nowrap; }


/* ---------- TabEditor (te-*) ---------- */

.te { display: flex; flex-direction: column; gap: var(--space-3); }
.te-empty {
    padding: var(--space-3);
    border: 1px dashed var(--color-cream-dark);
    border-radius: var(--radius-sm);
    color: var(--color-charcoal-muted);
    font-size: var(--text-sm);
}
.te-phrase {
    padding: var(--space-3);
    background: var(--color-cream-deep);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-md);
}
.te-phrase-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}
.te-phrase-label {
    flex: 1 1 8rem;
    min-width: 6rem;
    font-family: var(--font-display);
    font-size: var(--text-md);
    color: var(--color-charcoal);
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    padding: 2px var(--space-2);
}
.te-phrase-label:focus { outline: none; border-color: var(--color-accent); }

.te-ctl-l { display: inline-flex; align-items: center; gap: 4px; font-size: var(--text-xs); color: var(--color-charcoal-muted); }
.te-ctl-n {
    width: 3.2rem;
    font-size: var(--text-sm);
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    padding: 2px var(--space-2);
}
.te-ctl {
    font-size: var(--text-sm);
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    padding: 2px var(--space-2);
}
.te-phrase-del {
    margin-left: auto;
    width: 1.6rem; height: 1.6rem;
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-cream-dark);
    background: var(--color-white);
    color: var(--color-charcoal-muted);
    cursor: pointer;
    line-height: 1;
}
.te-phrase-del:hover { border-color: #9A3B2A; color: #9A3B2A; }

.te-grid {
    display: grid;
    gap: 2px;
    max-width: 100%;
    overflow-x: auto;
    padding-bottom: var(--space-2);
    margin-bottom: var(--space-2);
    font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
}
.te-beat { text-align: center; font-size: var(--text-xs); color: var(--color-charcoal-muted); line-height: 1.4; }
.te-strlabel {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding-right: var(--space-2);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-charcoal-mid);
}
.te-cellwrap { position: relative; display: flex; }
.te-cell {
    width: 100%;
    min-width: 0;
    text-align: center;
    font: inherit;
    font-size: var(--text-sm);
    color: var(--color-charcoal);
    background: var(--color-white);
    border: 1px solid var(--color-cream-mid);
    border-radius: var(--radius-sm);
    padding: 2px 0;
    -moz-appearance: textfield;
}
.te-cell:focus  { outline: none; border-color: var(--color-accent); background: #FFFDF6; }
.te-cellwrap.te-sel .te-cell { border-color: var(--color-accent); box-shadow: 0 0 0 1px var(--color-accent); }

/* Bar-start columns get a heavier left edge to read measures at a glance. */
.te-barstart              { border-left: 2px solid var(--color-cream-dark); margin-left: 1px; }
.te-cellwrap.te-barstart  { padding-left: 1px; }

.te-tech {
    position: absolute;
    top: -2px; right: -1px;
    font-size: 0.6rem;
    line-height: 1;
    color: var(--color-accent);
    pointer-events: none;
}

.te-mods        { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: var(--space-3); }
.te-mods-label  { font-size: var(--text-xs); color: var(--color-charcoal-muted); margin-right: var(--space-2); }
.te-mod {
    min-width: 1.8rem;
    padding: 2px var(--space-2);
    font-size: var(--text-sm);
    border: 1px solid var(--color-cream-dark);
    background: var(--color-white);
    color: var(--color-charcoal-mid);
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.te-mod:hover:not(:disabled) { border-color: var(--color-accent); color: var(--color-accent); }
.te-mod:disabled              { opacity: 0.4; cursor: default; }
.te-mod-on                    { background: var(--color-accent); color: var(--color-white); border-color: var(--color-accent); }
.te-mods-hint { font-size: var(--text-xs); font-style: italic; color: var(--color-charcoal-muted); }

.te-addphrase {
    align-self: flex-start;
    padding: 2px var(--space-3);
    font-size: var(--text-xs);
    border: 1px dashed var(--color-cream-dark);
    background: transparent;
    color: var(--color-charcoal-mid);
    border-radius: var(--radius-sm);
    cursor: pointer;
}

/* ==========================================================================
   PRESS KIT DOWNLOAD BUTTON
   Press.razor — "Download Press Kit (PDF)" CTA above the press sections.
   Charcoal/cream matches the newsletter-signup-button pattern used
   elsewhere on public pages.
   ========================================================================== */

.press-download-bar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--space-5);
}

.press-download-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-5);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}

.press-download-btn:hover {
    background-color: var(--color-accent);
    transform: translateY(-1px);
}

/* ==========================================================================
   PRESS KIT PRINT / PDF EXPORT
   Applied when the visitor uses the "Download Press Kit (PDF)" button
   (which triggers window.print()) or Ctrl+P on the press page.

   Hidden sections are not in the DOM at all (ShouldRender() guards with
   @if in Press.razor), so they naturally do not appear in print — no
   extra CSS needed for that case.
   ========================================================================== */

@media print {
    /* Hide site chrome and the download button itself */
    .site-header,
    .site-footer,
    .hamburger-menu,
    .global-player,
    .press-download-bar,
    .press-download-btn,
    .admin-edit-overlay,
    .press-section-hidden-badge { display: none !important; }

    /* Reset backgrounds and text colors for print */
    body,
    .public-page,
    .press-page,
    .press-section,
    .tile,
    .tile-light {
        background: white !important;
        color: #1a1a1a !important;
        box-shadow: none !important;
    }

    /* Press sections as clean, self-contained blocks */
    .press-section {
        page-break-inside: avoid;
        border: 1px solid #ddd !important;
        margin-bottom: 16pt;
        padding: 12pt;
    }

    /* Photos grid: 3 per row in print (overrides the responsive auto-fill) */
    .press-photos-grid {
        grid-template-columns: repeat(3, 1fr) !important;
        gap: 8pt;
    }

    .press-photos-grid figure { page-break-inside: avoid; }

    /* Page header: band name + EPK label injected via CSS */
    .press-page::before {
        content: "HiFi Riff Raff \2014  Electronic Press Kit";
        display: block;
        font-size: 18pt;
        font-weight: bold;
        border-bottom: 2pt solid #1a1a1a;
        padding-bottom: 8pt;
        margin-bottom: 16pt;
    }

    /* Show full URLs after links so the printed copy is useful offline */
    a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: 8pt;
        color: #666;
    }
    a[href^="mailto"]::after {
        content: " (" attr(href) ")";
        font-size: 8pt;
        color: #666;
    }

    /* Prevent links from breaking mid-line across a page boundary */
    a { page-break-inside: avoid; }

    /* Standard 1-inch margins for a clean printed page */
    @page { margin: 1in; }
}
.te-addphrase:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* ==========================================================================
   SCROLL REVEAL — entrance animations
   Elements with class "scroll-reveal" fade + slide up when they enter the
   viewport. The JS module (wwwroot/js/scroll-reveal.js) drives the observer;
   it adds "scroll-reveal--visible" on intersection. One-time per element.
   ========================================================================== */

.scroll-reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.45s ease, transform 0.45s ease;
}

.scroll-reveal--visible {
    opacity: 1;
    transform: translateY(0);
}

/* Respect prefers-reduced-motion: disable transition entirely; keep opacity
   at 1 so content is always visible even if JS has not run yet. */
@media (prefers-reduced-motion: reduce) {
    .scroll-reveal,
    .scroll-reveal--visible {
        transition: none;
        opacity: 1;
        transform: none;
    }
}

/* ==========================================================================
   PAGE LOADING SKELETON — shown while gRPC data is being fetched on WASM
   navigation (the pre-render handoff window).

   Pattern: each public page wraps its data-dependent content in an @if
   (_isLoading) / @else block. The skeleton uses pulsing placeholder bars
   that match the page card-grid or list layout so the page never looks
   blank or frozen.
   ========================================================================== */

/* Shared wrapper: same flow as .public-page */
.page-loading {
    display: flex;
    flex-direction: column;
    gap: var(--space-7);
    width: 100%;
}

/* Pulse animation for all skeleton bars */
@keyframes page-skeleton-pulse {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.45; }
}

/* Generic skeleton bar */
.page-loading-bar {
    background: var(--color-cream-deep);
    border-radius: 6px;
    animation: page-skeleton-pulse 1.6s ease-in-out infinite;
}

/* Grid of skeleton cards — mirrors .videos-grid / .releases-grid /
   .playlists-grid / .about-members-grid responsive breakpoints */
.page-loading-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
    gap: var(--space-7);
}

/* Individual skeleton card */
.page-loading-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    background: var(--color-cream-deep);
    border-radius: 12px;
    padding: var(--space-5);
    animation: page-skeleton-pulse 1.6s ease-in-out infinite;
}

/* Aspect-ratio placeholder for video / image thumbnails (16:9) */
.page-loading-thumb {
    width: 100%;
    aspect-ratio: 16 / 9;
    background: color-mix(in srgb, var(--color-charcoal-muted) 15%, transparent);
    border-radius: 8px;
}

/* Square thumbnail variant for release cover art */
.page-loading-thumb-square {
    width: 100%;
    aspect-ratio: 1 / 1;
    background: color-mix(in srgb, var(--color-charcoal-muted) 15%, transparent);
    border-radius: 8px;
}

/* Text line bars of varying widths */
.page-loading-line {
    height: 14px;
    background: color-mix(in srgb, var(--color-charcoal-muted) 20%, transparent);
    border-radius: 4px;
}
.page-loading-line-title  { height: 18px; width: 70%; }
.page-loading-line-meta   { height: 12px; width: 45%; }
.page-loading-line-body   { height: 12px; width: 90%; }
.page-loading-line-body2  { height: 12px; width: 75%; }

/* List skeleton — mirrors .shows-list */
.page-loading-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

/* Each row in the list skeleton */
.page-loading-list-row {
    display: flex;
    gap: var(--space-5);
    align-items: flex-start;
    background: var(--color-cream-deep);
    border-radius: 10px;
    padding: var(--space-5);
    animation: page-skeleton-pulse 1.6s ease-in-out infinite;
}

.page-loading-list-date {
    width: 48px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    align-items: center;
}

.page-loading-list-date .page-loading-line {
    width: 100%;
}

.page-loading-list-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

/* Stagger the pulse on sibling skeleton items so they pulse in waves */
.page-loading-card:nth-child(2),
.page-loading-list-row:nth-child(2) { animation-delay: 0.2s; }
.page-loading-card:nth-child(3),
.page-loading-list-row:nth-child(3) { animation-delay: 0.4s; }
.page-loading-card:nth-child(4),
.page-loading-list-row:nth-child(4) { animation-delay: 0.2s; }
.page-loading-card:nth-child(5),
.page-loading-list-row:nth-child(5) { animation-delay: 0.4s; }
.page-loading-card:nth-child(6),
.page-loading-list-row:nth-child(6) { animation-delay: 0.6s; }

/* =============================================================
   SOCIAL PROOF — About page section (PP7)
   Default-off: the .about-social-proof element only renders when
   visible items exist. See About.razor for the guard logic.
   ============================================================= */

.about-social-proof {
    margin: 2.5rem 0;
    padding: 0;
}

/* Section label — same pattern as other about-page section headings. */
.about-social-proof .section-label {
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-charcoal-muted, #6b7280);
    margin-bottom: 1.2rem;
}

/* Responsive grid: single column on narrow viewports, auto-fill
   ~280 px columns on wider screens — adapts naturally to 1, 2, or 3
   items without explicit breakpoints. */
.social-proof-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
    gap: 1rem;
}

/* ---- Quote tile ---- */
.social-proof-quote {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 1.2rem 1.4rem;
    margin: 0;
    text-decoration: none;
    color: inherit;
    transition: box-shadow var(--duration-fast);
}

.social-proof-quote:is(a):hover {
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.12);
}

/* ---- Milestone tile ---- */
.social-proof-milestone {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.5rem;
    padding: 1.2rem 1.4rem;
    text-align: center;
}

/* ---- Shared typography ---- */
.social-proof-text {
    font-size: 1rem;
    line-height: 1.55;
    margin: 0;
}

.social-proof-attribution {
    font-size: 0.85rem;
    font-style: normal;
    color: var(--color-charcoal-muted, #6b7280);
    margin: 0;
}

/* ---- Badge tile ---- */
.social-proof-badge-link {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.8rem;
    text-decoration: none;
}

.social-proof-badge-img {
    max-width: 100%;
    max-height: 120px;
    object-fit: contain;
}

/* ---- Mobile: single column ---- */
@media (max-width: 540px) {
    .social-proof-grid {
        grid-template-columns: 1fr;
    }
}

/* ============================================================
   Mini-CMS page builder (docs/features/MiniCMS-v1.md)
   Full-width three-zone editor: Structure / Canvas / Inspector
   + a collapsible Output Console. Uses the full area under the
   app header (intentionally not constrained to the site layout).
   ============================================================ */
.cms-builder {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: 100%;
    min-height: calc(100dvh - 7rem);
    padding: var(--space-3);
    box-sizing: border-box;
}
.cms-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: var(--color-cream-light);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
}
.cms-toolbar-spacer { flex: 1 1 var(--space-4); }
.cms-device-switch { display: inline-flex; gap: var(--space-1); }
.cms-device-switch .is-active { background: var(--color-accent); color: var(--color-white); }

.cms-stage {
    display: flex;
    gap: var(--space-2);
    flex: 1 1 auto;
    min-height: 24rem;
    align-items: stretch;
}
.cms-panel {
    flex: 0 0 auto;
    overflow: auto;
    padding: var(--space-3);
    background: var(--color-cream-light);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
}
.cms-structure { width: 16rem; }
.cms-inspector { width: 22rem; }
.cms-panel-title { font-size: 1rem; margin: 0 0 var(--space-2); }
.cms-structure-head { display: flex; align-items: center; justify-content: space-between; margin: var(--space-3) 0 var(--space-1); }

.cms-tree-row { display: flex; align-items: center; gap: var(--space-1); }
.cms-tree-item {
    flex: 1 1 auto;
    text-align: left;
    padding: var(--space-1) var(--space-2);
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    cursor: pointer;
    color: var(--color-charcoal);
}
.cms-tree-item:hover { background: var(--color-cream-mid); }
.cms-tree-item.is-selected { background: var(--color-accent-light); border-color: var(--color-accent); }
.cms-delete-page { margin-top: var(--space-4); width: 100%; }

/* Reuse / shared-component affordances (full-reuse model). */
.cms-insert-shared { margin-top: var(--space-2); width: 100%; }
.cms-shared-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin: var(--space-3) 0 var(--space-1);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--color-accent-light);
    border: 1px solid var(--color-accent);
}

.cms-canvas {
    flex: 1 1 auto;
    overflow: auto;
    background: var(--color-cream-mid);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    display: flex;
    justify-content: center;
}
.cms-canvas-frame {
    width: 100%;
    transition: max-width 0.2s ease;
    container-type: inline-size;   /* device-frame width drives the @container reflow below */
}
.cms-device-desktop { max-width: 1280px; }
.cms-device-tablet { max-width: 768px; }
.cms-device-mobile { max-width: 390px; }

/* Public page wrapper is also a query container, so the bento reflows by viewport width. */
.cms-page-container { container-type: inline-size; }

/* Grid tracks + cell placement come from CSS custom props (set inline by PageGrid.ToCss /
   BlockHost / the builder), so the container queries below can collapse the bento on mobile. */
.cms-page {
    display: grid;
    grid-template-columns: var(--cms-cols, repeat(4, minmax(0, 1fr)));
    grid-template-rows: var(--cms-rows, none);
    /* Fluid inter-tile gap — grows gently on wide screens, stays tight (current 8px) on small.
       Spec: fluid gap; kept near the existing density rather than jumping to roomy. */
    gap: clamp(var(--space-3), 1.2vw, var(--space-5));
    /* Gutter via custom prop (set by PageGrid.ToCss); unset = 0 = full width. The container queries
       below collapse the side gutter to 0 on phones so content goes edge-to-edge (full-bleed). */
    padding: var(--cms-pad, 0);
}
.cms-block {
    grid-column: var(--cms-col, auto);
    grid-row: var(--cms-row, auto);
    /* Overflow guard: grid/flex children default to min-width:auto, so wide content (long words,
       media, pre) can force the whole grid to overflow horizontally. min-width:0 lets a tile shrink
       to its track instead — the key anti-blowout fix for 320px reflow. */
    min-width: 0;
    /* Global tile rounding (one knob: --cms-tile-radius). overflow:hidden so background
       images, colored surfaces, and the WebGL visualizer all clip to the rounded corner. */
    border-radius: var(--cms-tile-radius);
    overflow: hidden;
}
/* Full-bleed banner: a Full-page block breaks out of the page's centered max-width + gutter
   to span the whole viewport, edge to edge (no rounding). Spans all grid columns via --cms-col. */
.cms-block-fullbleed {
    width: 100vw;
    max-width: 100vw;
    margin-inline: calc(50% - 50vw);
    border-radius: 0;
}

.cms-canvas-cell {
    position: relative;
    min-height: 8rem;
    grid-column: var(--cms-col, auto);
    grid-row: var(--cms-row, auto);
    border-radius: var(--radius-md);
    outline: 1px dashed var(--color-border-subtle);
    outline-offset: -1px;
    cursor: pointer;
    overflow: hidden;
    /* Flex so the block content stretches to fill the cell's full height — matching the public
       page, where the block IS the grid item. Without this the block sat at natural height,
       top-pinned, in a cell stretched to the grid row's min-height. */
    display: flex;
}

/* Bento reflow: 4 cols → 2 cols (tablet) → 1 col full-width (mobile). Keyed to the query
   container (device frame in the builder, viewport on the public page). */
@container (max-width: 760px) {
    .cms-page { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; }
    /* Blocks carry explicit 4-col --cms-col/--cms-row (e.g. "3 / 5"); in a 2-col grid those land in
       non-existent tracks and sit side-by-side/overflow. Reset to auto-flow so they reflow into 2
       columns in order instead of staying pinned to their desktop position. */
    .cms-block, .cms-canvas-cell { grid-column: auto !important; grid-row: auto !important; }
    /* Wide desktop tiles (banners/features spanning >=2 cols, tagged by BlockHost) span BOTH tablet
       columns instead of shrinking to a half-width cell that clips their content. */
    .cms-block-tablet-wide { grid-column: 1 / -1 !important; }
    /* Same collapse risk at the 2-col tablet breakpoint — floor scene/visualizer tile height. */
    .cms-block:has(> .cms-block-bg) { min-height: clamp(12rem, 35vw, 18rem); }
}
@container (max-width: 460px) {
    /* Phones: one column AND full-bleed — drop the side gutter so content uses the full screen width
       instead of leaving margin (the inline-padding-can't-be-overridden problem is solved by --cms-pad). */
    .cms-page { grid-template-columns: 1fr; grid-template-rows: none; padding-inline: var(--space-4); }
    .cms-block, .cms-canvas-cell { grid-column: 1 / -1 !important; grid-row: auto !important; }
    /* Visualizer/scene tiles position their content (canvas + text layers) ABSOLUTELY, so with auto
       rows on mobile they collapse to nothing — squashing the band and clipping the in-tile button.
       Floor their height so the layered content stays visible. (A true fit-to-tallest-layer needs a
       compositor change; this is the robust CSS mitigation.) */
    .cms-block:has(> .cms-block-bg) { min-height: clamp(14rem, 60vw, 20rem); }
}
.cms-canvas-cell.is-selected { outline: 2px solid var(--color-accent); }
.cms-canvas-cell .tile-layer-host { width: 100%; height: 100%; min-height: 8rem; }
.cms-canvas-empty {
    grid-column: 1 / -1;
    display: flex; align-items: center; justify-content: center;
    min-height: 12rem; color: var(--color-charcoal-muted);
    text-align: center;
}

.cms-console {
    flex: 0 0 auto;
    background: var(--color-charcoal);
    color: var(--color-cream);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.cms-console-head { padding: var(--space-1) var(--space-3); background: var(--color-charcoal-mid); font-size: 0.85rem; }
.cms-console-body { padding: var(--space-2) var(--space-3); max-height: 12rem; overflow: auto; }
.cms-console-body .admin-field-help { color: var(--color-cream-mid); }

@media (max-width: 900px) {
    .cms-stage { flex-direction: column; }
    .cms-structure, .cms-inspector { width: 100%; }
}

/* Mini-CMS: admin edit-pencil overlay on public blocks + deep-link flash */
.cms-block { position: relative; }
.cms-block-edit {
    position: absolute;
    top: var(--space-1);
    right: var(--space-1);
    z-index: 5;
    width: 1.75rem; height: 1.75rem;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--color-charcoal);
    color: var(--color-cream);
    border-radius: var(--radius-full);
    text-decoration: none;
    opacity: 0; transition: opacity 0.15s ease;
}
.cms-block:hover .cms-block-edit { opacity: 0.92; }
.cms-block-error, .cms-block-unknown {
    padding: var(--space-2);
    font-size: 0.85rem;
    color: var(--color-charcoal-muted);
    background: var(--color-cream-mid);
    border: 1px dashed var(--color-border-subtle);
    border-radius: var(--radius-sm);
}
@keyframes cmsCellFlash {
    0%, 100% { box-shadow: 0 0 0 0 rgba(0,0,0,0); }
    30% { box-shadow: 0 0 0 4px var(--color-accent); }
}
.cms-cell-flash { animation: cmsCellFlash 1.2s ease; }

/* Mini-CMS builder: tile being dragged for rearrange */
.cms-canvas-cell.is-dragging { opacity: 0.5; }
.cms-canvas-cell[draggable="true"] { cursor: grab; }

/* Mini-CMS builder: publish status + version history */
.cms-status { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-1); }
.cms-status-badge {
    padding: 0.1rem var(--space-2);
    border-radius: var(--radius-full);
    background: var(--color-cream-mid);
    color: var(--color-charcoal);
    font-size: 0.8rem;
}
.cms-status-badge.is-published { background: var(--color-accent); color: var(--color-white); }
/* Amber-ish "draft has edits not yet live" pill. */
.cms-status-badge-dirty { background: #B8860B; color: var(--color-white); }
.cms-status-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
/* Bounded + scrollable so a long history never stretches the inspector column. */
.cms-versions { list-style: none; margin: var(--space-1) 0 0; padding: 0; max-height: 14rem; overflow-y: auto; }
.cms-version-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--admin-gap); padding: var(--space-1) 0;
    border-bottom: 1px solid var(--color-border-subtle);
    font-size: var(--admin-text-control);
}
.cms-version-actions { display: inline-flex; gap: var(--space-1); flex-shrink: 0; }

/* Mini-CMS: contact-form block + Output Console log entries */
.cms-contact-form { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); }
.cms-cf-field { display: flex; flex-direction: column; gap: var(--space-1); }
.cms-cf-field > span { font-size: 0.85rem; color: var(--color-charcoal-mid); }
.cms-cf-field input, .cms-cf-field textarea {
    padding: var(--space-2); min-height: 2.75rem; border: 1px solid var(--color-border-subtle); border-radius: var(--radius-sm);
    font: inherit; background: var(--color-cream-light);
}
.cms-cf-status.is-ok { color: var(--color-accent); }
.cms-cf-status.is-error { color: #b00020; }
/* Honeypot: kept in the DOM for bots to fill, removed from view + a11y tree for
   real users (off-screen, no pointer/tab reach). aria-hidden + tabindex=-1 are
   also set on the input itself. Not display:none — some bots skip hidden fields. */
.cms-cf-hp {
    position: absolute; left: -9999px; width: 1px; height: 1px;
    overflow: hidden; opacity: 0; pointer-events: none;
}
.cms-log { padding: var(--space-1) 0; border-bottom: 1px solid var(--color-charcoal-mid); }
.cms-log-meta { font-size: 0.72rem; opacity: 0.65; }
.cms-log-msg { font-size: 0.85rem; }
.cms-log.is-error .cms-log-msg { color: var(--color-amber); }
.cms-log-detail {
    white-space: pre-wrap; font-size: 0.72rem; margin: var(--space-1) 0 0;
    max-height: 8rem; overflow: auto;
    background: rgba(0, 0, 0, 0.25); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm);
}

/* Mini-CMS: rich-text block content */
.cms-richtext { padding: var(--space-3); overflow-wrap: break-word; }
.cms-richtext > :first-child { margin-top: 0; }
.cms-richtext h2 { margin-top: var(--space-4); }
.cms-richtext img { max-width: 100%; height: auto; }   /* responsive images in prose */

/* Data-backed display blocks (Releases / Shows / Playlists / Featured release).
   Self-contained block styling — consistent across the three embedding contexts. */
.cms-data-block { padding: var(--space-3); }
.cms-data-heading { margin: 0 0 var(--space-3); font-size: var(--step-1); }
.cms-data-empty { color: var(--color-charcoal-soft, inherit); opacity: 0.75; padding: var(--space-2) 0; }
.cms-data-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr));
    gap: var(--space-3);
}
.cms-data-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding: var(--space-3);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    background: var(--color-cream-mid, transparent);
}
.cms-data-cover { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius-sm); margin-bottom: var(--space-1); }
.cms-data-card-title { margin: 0; font-size: 1.05rem; }
.cms-data-card-meta { margin: 0; font-size: 0.85rem; opacity: 0.8; }
.cms-data-card-notes { margin: var(--space-1) 0 0; font-size: 0.85rem; }
.cms-data-tracklist { margin: var(--space-2) 0 0; padding-left: 1.2em; font-size: 0.85rem; }
.cms-data-eyebrow, .cms-data-show-tickets { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.04em; }

/* Upcoming-shows list */
.cms-data-shows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.cms-data-show { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); border: var(--border-thin); border-radius: var(--radius-md); }
.cms-data-show-date { display: flex; flex-direction: column; align-items: center; min-width: 3rem; }
.cms-data-show-month { font-size: 0.75rem; text-transform: uppercase; opacity: 0.8; }
.cms-data-show-day { font-size: 1.4rem; font-weight: 700; line-height: 1; }
.cms-data-show-info { flex: 1 1 auto; }
.cms-data-show-tickets { margin-left: auto; padding: var(--space-1) var(--space-3); border: var(--border-thin); border-radius: var(--radius-sm); text-decoration: none; white-space: nowrap; }

/* Featured release */
.cms-data-featured { display: flex; gap: var(--space-4); flex-wrap: wrap; padding: var(--space-3); }
.cms-data-featured-cover { width: 220px; max-width: 100%; aspect-ratio: 1; object-fit: cover; object-position: var(--tile-focal); border-radius: var(--radius-tile); }
.cms-data-featured-body { flex: 1 1 260px; min-width: 0; }
.cms-data-featured-desc { margin: var(--space-2) 0 0; }
.cms-data-meta { display: block; font-size: 0.85rem; opacity: 0.8; margin-top: var(--space-1); }

/* Featured video (single performance) — the video sits above its title in a tile. */
.cms-data-featured .cms-data-video { flex: 1 1 100%; }
.cms-data-video { aspect-ratio: 16 / 9; border-radius: var(--radius-md); overflow: hidden; }
.cms-data-video iframe, .cms-data-video > * { width: 100%; height: 100%; border: 0; }

/* Featured show — the date-badge card links to /shows; empty state keeps the eyebrow. */
a.cms-data-show { text-decoration: none; color: inherit; }
.cms-data-show-empty { padding: var(--space-2) var(--space-3); }

/* Press quotes */
.cms-data-quotes { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: var(--space-3); }
.cms-data-quote { margin: 0; padding: var(--space-3); border-left: 3px solid var(--color-accent); background: var(--color-cream-mid, transparent); }
.cms-data-quote blockquote { margin: 0; font-style: italic; }
.cms-data-quote figcaption { margin-top: var(--space-2); font-size: 0.85rem; opacity: 0.8; }

/* Newsletter signup */
.cms-newsletter-form { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.cms-newsletter-email { flex: 1 1 220px; min-width: 0; min-height: 2.75rem; padding: var(--space-2) var(--space-3); border: var(--border-thin); border-radius: var(--radius-sm); }
/* Match the site palette button (was an unstyled default button). */
.cms-newsletter-button {
    flex-shrink: 0;
    min-height: 2.75rem;   /* tap target */
    padding: var(--space-2) var(--space-5);
    background-color: var(--color-charcoal);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color var(--duration-fast), transform var(--duration-fast);
}
.cms-newsletter-button:hover:not(:disabled) { background-color: var(--color-accent); transform: translateY(-1px); }
.cms-newsletter-button:disabled { opacity: 0.5; cursor: not-allowed; }
.cms-newsletter-done { font-weight: 600; }
.cms-newsletter-error { color: var(--color-danger, crimson); font-size: 0.85rem; margin-top: var(--space-1); }

/* Mini-CMS: ultra-dense inspector (Visual Studio properties-grid style).
   Scoped to .cms-props so the nested LayerStackEditor keeps its own layout. */
/* Inspector density is now the shared admin token system (no per-rule hardcoded sizes). These rules
   keep only the inspector LAYOUT — the 2-column label|control grid + per-row dividers. Font sizes,
   control heights, and padding come from --admin-* (which the Dense/Ultra toggle drives). */
.cms-inspector .cms-panel-title { font-size: var(--admin-text-section); margin: 0 0 var(--space-1); }
.cms-props { display: flex; flex-direction: column; }
.cms-props > .admin-field {
    display: grid;
    grid-template-columns: minmax(5.5rem, 42%) 1fr;
    align-items: center;
    gap: 0 var(--admin-gap);
    margin: 0;
    padding: var(--admin-pad-y) 0;
    border-bottom: 1px solid var(--color-border-subtle);
}
.cms-props > .admin-field > .admin-field-label {
    color: var(--color-charcoal-mid);
    margin: 0;
    line-height: 1.15;
}
/* Wide controls (markdown, status block, page-grid) span both columns. */
.cms-props > .admin-field > textarea.admin-input { grid-column: 1 / -1; }
.cms-props > .admin-checkbox {
    display: flex; align-items: center; gap: var(--admin-gap);
    padding: var(--admin-pad-y) 0; margin: 0;
    border-bottom: 1px solid var(--color-border-subtle);
}
.cms-props .admin-field-help { grid-column: 1 / -1; margin: 1px 0 0; }
.cms-props .cms-hardcoded-note { padding: var(--space-1); background: var(--color-cream-mid); border-radius: var(--radius-sm); }
.cms-props .cms-status { display: flex; align-items: center; gap: var(--admin-gap); margin: 0; }
/* Field editor: full-row group headers, advanced fold, inline validation errors. */
.cms-props .cms-group-head { grid-column: 1 / -1; margin-top: var(--admin-section-gap); padding-top: var(--space-1); border-top: 1px solid var(--color-border-subtle); font-size: var(--admin-text-section); font-weight: 600; }
.cms-props .cms-advanced-toggle { grid-column: 1 / -1; justify-self: start; margin: 2px 0; padding: 1px var(--admin-pad-x); background: none; border: 0; color: var(--color-charcoal-muted); font-size: var(--admin-text-help); cursor: pointer; }
.cms-props .cms-advanced-toggle:hover { color: var(--color-charcoal); }
.cms-props .cms-field-error { grid-column: 1 / -1; font-size: var(--admin-text-help); margin: 1px 0 0; color: #b00020; }
/* Reusable image field (upload + browse + preview). */
.image-field { display: flex; flex-direction: column; gap: var(--admin-gap); }
.image-field-preview { max-width: 100%; max-height: 110px; border-radius: var(--admin-radius); object-fit: cover; }
.image-field-empty { font-size: var(--admin-text-help); color: var(--color-charcoal-muted); padding: var(--space-1); border: 1px dashed var(--color-border-subtle); border-radius: var(--admin-radius); text-align: center; }
.image-field-actions { display: flex; flex-wrap: wrap; gap: var(--admin-gap); align-items: center; }
.image-field-actions .admin-file-input { max-width: 11rem; }
/* Downloadable-file field (CMS Downloads block) — the non-image counterpart of .image-field. */
.file-field { display: flex; flex-direction: column; gap: var(--admin-gap); }
.file-field-current { font-size: var(--admin-text-help); color: var(--color-accent); word-break: break-all; }
.file-field-empty { font-size: var(--admin-text-help); color: var(--color-charcoal-muted); padding: var(--space-1); border: 1px dashed var(--color-border-subtle); border-radius: var(--admin-radius); text-align: center; }
.file-field-actions { display: flex; flex-wrap: wrap; gap: var(--admin-gap); align-items: center; }
.file-field-actions .admin-file-input { max-width: 11rem; }

/* Mini-CMS builder: canvas renders blocks with the real renderer; disable their pointer
   events so clicks select/drag the tile (and preview forms don't fire). */
.cms-canvas-cell-content { pointer-events: none; width: 100%; height: 100%; display: flex; }
.cms-canvas-cell-content .cms-block { min-height: 4rem; flex: 1; width: 100%; }

/* Mini-CMS builder: don't let a double-click select text in a canvas tile (it can leave an
   unreadable highlight); the tile is a selection target, not selectable content. */
.cms-canvas-cell { user-select: none; }

/* CMS block: the tile-layer substrate is a z-0 background (contained to the block); the
   block's foreground content (text/form/data) sits above it at z-1. Fixes content blocks
   going black when they carry a layer stack (the absolute, charcoal .tile-layer-host used to
   paint over the foreground). */
.cms-block-bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; border-radius: inherit; }
.cms-block > :not(.cms-block-bg):not(.cms-block-edit) { position: relative; z-index: 1; }
.cms-block { min-height: 3rem; }
/* The charcoal .tile-layer-host base is for home tiles. In the CMS the substrate must be
   transparent so a block's own layers (or the page) show through — never a dark box behind
   foreground text. (Belt-and-suspenders with HasStack: an empty stack no longer mounts a host.) */
.cms-block-bg .tile-layer-host { background: transparent; }

/* Builder-canvas stand-in for a Visualizer block — a static placeholder instead of a live WebGL
   compositor per block (heavy/fragile in the canvas). The real animation renders on the page. */
.cms-visualizer-placeholder {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: var(--space-1); min-height: 8rem; width: 100%; padding: var(--space-3);
    border: 1px dashed var(--color-cream-dark); border-radius: inherit; text-align: center;
    color: var(--color-charcoal-muted);
    background: repeating-linear-gradient(45deg,
        var(--color-cream-deep), var(--color-cream-deep) 10px,
        var(--color-cream-mid) 10px, var(--color-cream-mid) 20px);
}
.cms-visualizer-placeholder-label { font-weight: 600; font-size: 0.85rem; }
.cms-visualizer-placeholder-meta { font-size: 0.72rem; }

/* ==========================================================================
   STRUCTURAL / LAYOUT BLOCKS (Phase 3): accordion, tabs, hero, CTA group,
   columns, spacer, embed, gallery, map, countdown.
   ========================================================================== */

.cms-block-heading {
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-charcoal);
    margin: 0 0 var(--space-3);
}

/* ----- Accordion / FAQ ----- */
.cms-accordion { padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.cms-accordion-item {
    border: 1px solid var(--color-cream-dark);
    border-radius: var(--radius-md);
    background: var(--color-cream-light);
    overflow: hidden;
}
.cms-accordion-summary {
    cursor: pointer; list-style: none;
    min-height: 2.75rem;   /* comfortable tap target (WCAG 2.5.5) */
    padding: var(--space-3) var(--space-4);
    font-weight: 600; color: var(--color-charcoal);
    display: flex; align-items: center; justify-content: space-between;
}
.cms-accordion-summary::-webkit-details-marker { display: none; }
.cms-accordion-summary::after { content: "+"; color: var(--color-accent); font-weight: 700; }
.cms-accordion-item[open] .cms-accordion-summary::after { content: "\2212"; }
.cms-accordion-body { padding: 0 var(--space-4) var(--space-3); color: var(--color-charcoal-mid); }
.cms-accordion-body > :first-child { margin-top: 0; }

/* ----- Tabs (pure-CSS radio tabs; labels row via flex order, panels below) ----- */
.cms-tabs { display: flex; flex-wrap: wrap; padding: var(--space-3); gap: 0; }
.cms-tab-radio { position: absolute; opacity: 0; pointer-events: none; }
.cms-tab-label {
    order: 1; cursor: pointer;
    padding: var(--space-2) var(--space-4);
    border-bottom: 2px solid transparent;
    color: var(--color-charcoal-muted); font-weight: 600;
}
.cms-tab-panel {
    order: 2; width: 100%; display: none;
    padding: var(--space-4) var(--space-1) var(--space-2);
    color: var(--color-charcoal-mid);
}
.cms-tab-panel > :first-child { margin-top: 0; }
.cms-tab-radio:checked + .cms-tab-label { color: var(--color-accent); border-bottom-color: var(--color-accent); }
.cms-tab-radio:checked + .cms-tab-label + .cms-tab-panel { display: block; }

/* ----- Hero / Banner ----- */
.cms-hero {
    position: relative; overflow: hidden;
    container-type: inline-size;   /* heading/subheading scale to the hero's own width via cqi */
    border-radius: var(--radius-tile);
    min-height: clamp(16rem, 30vw, 24rem); display: flex;
    padding: var(--space-6) var(--space-5);
    background: var(--color-charcoal);
}
.cms-hero-bg {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; object-position: var(--tile-focal); z-index: 0; opacity: 0.55;
}
.cms-hero-inner {
    position: relative; z-index: 1; max-width: 42rem;
    display: flex; flex-direction: column; gap: var(--space-3); align-self: center;
}
.cms-hero-center { justify-content: center; text-align: center; }
.cms-hero-center .cms-hero-inner { margin: 0 auto; align-items: center; }
.cms-hero-left { justify-content: flex-start; text-align: left; }
.cms-hero-eyebrow { text-transform: uppercase; letter-spacing: 0.08em; font-size: clamp(0.75rem, 2cqi, 0.95rem); color: var(--color-accent-light); font-weight: 700; }
.cms-hero-heading { font-size: clamp(1.6rem, 7cqi, 3.5rem); line-height: 1.1; color: var(--color-white); margin: 0; }
.cms-hero-subheading { font-size: clamp(1rem, 3cqi, 1.4rem); color: var(--color-cream); margin: 0; }
.cms-hero-cta { align-self: flex-start; }
.cms-hero-center .cms-hero-cta { align-self: center; }

/* ----- CTA / button group ----- */
.cms-cta-group { padding: var(--space-3); }
.cms-cta-row { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.cms-cta-btn {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 2.75rem;   /* ~44px comfortable tap target (WCAG 2.5.5 enhanced) */
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-md); font-weight: 600; text-decoration: none;
    transition: transform 0.12s ease, background-color 0.12s ease;
}
.cms-cta-btn:hover { transform: translateY(-1px); }
.cms-cta-primary { background: var(--color-accent); color: var(--color-white); border: 1px solid var(--color-accent); }
.cms-cta-primary:hover { background: var(--color-accent-light); }
.cms-cta-secondary { background: transparent; color: var(--color-accent); border: 1px solid var(--color-accent); }
.cms-cta-secondary:hover { background: var(--color-cream-deep); }

/* ----- Columns / Section ----- */
.cms-columns { padding: var(--space-3); }
.cms-columns-grid {
    display: grid;
    grid-template-columns: repeat(var(--cms-columns, 2), minmax(0, 1fr));   /* minmax(0,..) = column overflow guard */
    gap: var(--space-4);
}
.cms-column-heading { font-size: var(--step-1); margin: 0 0 var(--space-2); color: var(--color-charcoal); }
.cms-column-body { color: var(--color-charcoal-mid); }
.cms-column-body > :first-child { margin-top: 0; }
@media (max-width: 700px) {
    .cms-columns-grid { grid-template-columns: 1fr; }
}

/* ----- Spacer / Divider ----- */
.cms-spacer { width: 100%; }
.cms-spacer-sm { height: var(--space-3); }
.cms-spacer-md { height: var(--space-5); }
.cms-spacer-lg { height: var(--space-7, 3rem); }
.cms-spacer-xl { height: 5rem; }
.cms-spacer-rule {
    border: 0; border-top: 1px solid var(--color-cream-dark);
    margin: 0; position: relative; top: 50%;
}

/* ----- Embed / HTML ----- */
.cms-embed { padding: var(--space-3); }
.cms-embed-frame { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-md); overflow: hidden; }
.cms-embed-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ----- Gallery / Lightbox ----- */
.cms-gallery { padding: var(--space-3); }
.cms-gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 160px), 1fr)); gap: var(--space-3); }
.cms-gallery-item {
    display: block; margin: 0; border-radius: var(--radius-md); overflow: hidden;
    background: var(--color-cream-deep); text-decoration: none; color: inherit;
}
.cms-gallery-item img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: var(--tile-focal); aspect-ratio: 1 / 1; transition: transform 0.2s ease; }
.cms-gallery-grid.is-downloadable .cms-gallery-item { cursor: pointer; }
.cms-gallery-grid.is-downloadable .cms-gallery-item:hover img { transform: scale(1.05); }
.cms-gallery-caption { display: block; padding: var(--space-1) var(--space-2); font-size: var(--text-sm); color: var(--color-charcoal-muted); }

/* ----- Map ----- */
.cms-map { padding: var(--space-3); }
.cms-map-frame { width: 100%; border-radius: var(--radius-md); overflow: hidden; }
.cms-map-frame iframe { width: 100%; border: 0; display: block; }
.cms-map-short iframe { height: 220px; }
.cms-map-medium iframe { height: 360px; }
.cms-map-tall iframe { height: 520px; }

/* ----- Media player (inline, drives the singleton AudioPlayerService) ----- */
.cms-media-player { padding: var(--space-4) var(--space-3); display: flex; flex-direction: column; gap: var(--space-3); }
.cms-media-player-now { display: flex; align-items: center; gap: var(--space-3); }
.cms-media-player-art { width: 3.5rem; height: 3.5rem; border-radius: var(--radius-md); object-fit: cover; object-position: var(--tile-focal); }
.cms-media-player-info { display: flex; flex-direction: column; min-width: 0; }
.cms-media-player-title { font-weight: 700; color: var(--color-charcoal); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cms-media-player-artist { font-size: var(--text-sm); color: var(--color-charcoal-muted); }
.cms-media-player-progress { height: 4px; border-radius: 2px; background: var(--color-cream-dark); overflow: hidden; }
.cms-media-player-progress-fill { height: 100%; background: var(--color-accent); transition: width 0.25s linear; }
.cms-media-player-controls { display: flex; align-items: center; gap: var(--space-2); }
.cms-media-player-btn {
    border: 1px solid var(--color-cream-dark); background: var(--color-cream-light);
    border-radius: 50%; width: 2.25rem; height: 2.25rem; cursor: pointer;
    font-size: 1rem; color: var(--color-charcoal); display: inline-flex; align-items: center; justify-content: center;
}
.cms-media-player-btn:disabled { opacity: 0.4; cursor: default; }
.cms-media-player-play { background: var(--color-accent); color: var(--color-white); border-color: var(--color-accent); width: 2.75rem; height: 2.75rem; }
.cms-media-player-fs { margin-left: auto; }
.cms-media-player-empty { color: var(--color-charcoal-muted); font-size: var(--text-sm); }

/* ----- Countdown ----- */
.cms-countdown { padding: var(--space-4) var(--space-3); text-align: center; }
.cms-countdown-units { display: inline-flex; flex-wrap: wrap; justify-content: center; gap: var(--space-4); }
.cms-countdown-cell { display: flex; flex-direction: column; min-width: 3.5rem; }
.cms-countdown-value { font-size: clamp(1.75rem, 5vw, 2.25rem); font-weight: 700; line-height: 1; color: var(--color-accent); font-variant-numeric: tabular-nums; }
.cms-countdown-unit { font-size: var(--text-sm); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-charcoal-muted); margin-top: var(--space-1); }
.cms-countdown-done { font-size: var(--text-lg); font-weight: 700; color: var(--color-accent); }

/* Mini-CMS pop-out markdown editor modal */
.cms-md-popout { margin: var(--space-1) 0 var(--space-2); }
.cms-md-overlay {
    position: fixed; inset: 0; z-index: 1000;
    background: rgba(0, 0, 0, 0.55);
    display: flex; align-items: center; justify-content: center;
    padding: var(--space-4);
}
.cms-md-modal {
    background: var(--color-cream-light);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: min(1100px, 95vw); height: min(82vh, 820px);
    display: flex; flex-direction: column; overflow: hidden;
}
.cms-md-head { display: flex; align-items: center; justify-content: space-between; padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--color-border-subtle); font-weight: 600; }
.cms-md-toolbar { display: flex; gap: var(--space-1); flex-wrap: wrap; padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--color-border-subtle); }
.cms-md-body { flex: 1 1 auto; display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); padding: var(--space-3); overflow: hidden; }
.cms-md-textarea { width: 100%; height: 100%; resize: none; font-family: ui-monospace, monospace; font-size: 0.9rem; line-height: 1.5; padding: var(--space-2); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-sm); }
.cms-md-preview { overflow: auto; padding: var(--space-2) var(--space-3); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-sm); background: var(--color-cream); }
.cms-md-foot { display: flex; justify-content: flex-end; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-top: 1px solid var(--color-border-subtle); }
@media (max-width: 760px) { .cms-md-body { grid-template-columns: 1fr; } }
