/* ============================================================================
   AEON • premium.css
   Ultra-premium additive layer for the SPX6900 "Aeon" calendar.
   Loaded AFTER style.css (so it wins the cascade). No build step, no CDN,
   no external assets — everything is inline / self-hosted.

   Contents
     1. Token redefinition (refined DARK default) + new design tokens
     2. Explicit dark set + warm-ivory LIGHT theme (toggle-driven only)
     3. Material layer — atmospheric wash + baked grain + art scrims
     4. Premium chrome — glass, bevels, day-cell frame, today ring, elevation
     5. Typography polish — tabular numerals + tracking
     6. Motion — view-transition cross-fade + skeleton shimmer
     7. New components — #aeon-theme-toggle, #aeon-cmdk, #aeon-week, #aeon-tabbar
     8. Accessibility — focus-visible, sr-only, skip-link, reduced-motion, hit areas

   Identity rules honoured:
     • --apple-red stays GOLD (#D4A843) — it is the brand accent, not red.
     • Per-day anime art (.day-bg / #day-view-bg) and gold branding preserved.
     • Motion is compositor-safe (transform / opacity / filter only).
   ============================================================================ */


/* ============================================================================
   1. TOKEN REDEFINITION — refined DARK is the default identity
   Surfaces move off pure #000 to tinted near-blacks (true black stays a valid
   canvas). Adds the gold ramp, spacing, radii, elevation and duration scales.
   ============================================================================ */

:root {
    /* --- Gold ramp (brand) derived from #D4A843 --------------------------- */
    --brand:        #D4A843;   /* core gold — the identity accent            */
    --brand-bright: #F0D27E;   /* highlight gold — glints, hovers            */
    --brand-deep:   #A67C1E;   /* shadowed gold — pressed / gradients        */
    --brand-glow:   rgba(212, 168, 67, 0.45); /* soft bloom for shadows      */
    /* Gold used as TEXT (header buttons, modal actions, active tab, error
       copy) — a separate token from --brand/--apple-red because those are
       ALSO used as solid fills (today's coin, primary buttons), where a
       vivid gold reads fine. As text-on-ivory in the light theme, #9A7B2E
       measured only 3.3-4.0:1 — under the 4.5:1 AA floor. Dark keeps the
       same gold for both, since gold-on-near-black already clears AA by a
       wide margin. */
    --brand-ink: #D4A843;

    /* --- Accent colours — retone the stray blue toward a refined tone ----- */
    --apple-blue:   #5AA9FF;   /* refined link/cancel blue (was harsh #007AFF)*/
    --apple-red:    #D4A843;   /* GOLD brand accent — keep gold              */
    --apple-orange: #FF9F0A;
    --apple-green:  #30D158;
    --apple-purple: #BF5AF2;

    /* --- Text ------------------------------------------------------------- */
    --label:            #FFFFFF;
    --secondary-label:  rgba(235, 235, 245, 0.60);
    --tertiary-label:   rgba(235, 235, 245, 0.30);
    --quaternary-label: rgba(235, 235, 245, 0.18);

    /* --- Backgrounds — tinted near-blacks (never flat) -------------------- */
    --system-background:    #000000;  /* true-black canvas (allowed)          */
    --secondary-background:  #17161A; /* warm-neutral raised surface          */
    --tertiary-background:   #221F26; /* controls / field rows                */
    --grouped-background:    #131217; /* grouped scenes (list / day)          */

    /* --- Separators ------------------------------------------------------- */
    --separator:        rgba(120, 110, 130, 0.30);
    --opaque-separator: #34313A;

    /* --- Glass ------------------------------------------------------------ */
    --glass-bg:       rgba(26, 24, 30, 0.72);
    --glass-bg-thick: rgba(22, 20, 26, 0.92);
    --glass-blur:     saturate(180%) blur(20px);

    /* --- New: spacing scale (4-based) ------------------------------------- */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --space-8: 64px;

    /* --- New: radius scale ------------------------------------------------ */
    --radius-xs:   4px;
    --radius-sm:   6px;
    --radius-md:   8px;
    --radius-lg:  12px;
    --radius-xl:  16px;
    --radius-2xl: 24px;
    --radius-full: 999px;

    /* --- New: elevation — layered, gold-tinted shadows -------------------- */
    --elev-1: 0 1px 2px rgba(0,0,0,.40), 0 0 0 .5px rgba(212,168,67,.06);
    --elev-2: 0 2px 6px rgba(0,0,0,.45), 0 1px 2px rgba(0,0,0,.35);
    --elev-3: 0 6px 18px rgba(0,0,0,.50), 0 2px 6px rgba(0,0,0,.35);
    --elev-4: 0 14px 40px rgba(0,0,0,.55), 0 4px 12px rgba(0,0,0,.40);
    --elev-5: 0 24px 70px rgba(0,0,0,.62), 0 8px 24px rgba(0,0,0,.45);

    /* --- New: durations --------------------------------------------------- */
    --dur-fast: 140ms;
    --dur:      240ms;
    --dur-slow: 420ms;

    /* Atmospheric wash tint (overridden per-theme) */
    --wash-1: rgba(212, 168, 67, 0.10);
    --wash-2: rgba(120, 90, 200, 0.06);
    --wash-3: rgba(0, 0, 0, 0.0);
    /* Bottom scrim over anime art so overlaid text stays WCAG-legible */
    --art-scrim: linear-gradient(180deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.55) 100%);
}


/* ============================================================================
   2. EXPLICIT THEMES — the toggle is the ONLY switch.
   No prefers-color-scheme auto-switch (by design). Dark is redeclared so an
   explicit data-theme="dark" is authoritative; light is a full warm-ivory set.
   ============================================================================ */

/* --- Explicit DARK (mirrors :root, authoritative when stamped) ----------- */
html[data-theme="dark"] {
    --apple-blue:   #5AA9FF;
    --apple-red:    #D4A843;
    --brand-ink:    #D4A843;

    --label:            #FFFFFF;
    --secondary-label:  rgba(235, 235, 245, 0.60);
    --tertiary-label:   rgba(235, 235, 245, 0.30);
    --quaternary-label: rgba(235, 235, 245, 0.18);

    --system-background:    #000000;
    --secondary-background: #17161A;
    --tertiary-background:  #221F26;
    --grouped-background:   #131217;

    --separator:        rgba(120, 110, 130, 0.30);
    --opaque-separator: #34313A;

    --glass-bg:       rgba(26, 24, 30, 0.72);
    --glass-bg-thick: rgba(22, 20, 26, 0.92);

    --wash-1: rgba(212, 168, 67, 0.10);
    --wash-2: rgba(120, 90, 200, 0.06);
    --art-scrim: linear-gradient(180deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.55) 100%);
}

/* --- Warm-ivory LIGHT ----------------------------------------------------
   Canvas ~#F4EFE2, surfaces ~#FBF7EC / #FFF, ink ~#2A2417, gold deepened to
   ~#9A7B2E so it clears AA on light surfaces. Every surface / label /
   separator / glass / shadow / scrim token is redefined here.               */
html[data-theme="light"] {
    /* Gold deepened for legibility on light */
    --brand:        #9A7B2E;
    --brand-bright: #B8912F;
    --brand-deep:   #7C6220;
    --brand-glow:   rgba(154, 123, 46, 0.30);

    --apple-blue:   #1F6FE0;   /* AA-legible link blue on ivory              */
    --apple-red:    #9A7B2E;   /* GOLD accent, deepened — still the identity */
    /* #9A7B2E measures 3.3-4.0:1 as TEXT on the ivory surfaces (canvas/raised/
       white) — under the 4.5:1 AA floor. This deeper shade clears 5.3:1+ on
       all three while --apple-red stays at #9A7B2E for fills, where it reads
       fine (e.g. white text on a gold button is a different contrast pair). */
    --brand-ink:    #7A5E1B;
    --apple-orange: #B25E00;
    --apple-green:  #1E8C3C;
    --apple-purple: #7E3BC4;

    /* Ink on ivory */
    --label:            #2A2417;
    --secondary-label:  rgba(42, 36, 23, 0.62);
    --tertiary-label:   rgba(42, 36, 23, 0.40);
    --quaternary-label: rgba(42, 36, 23, 0.12);

    /* Warm-ivory surfaces */
    --system-background:    #F4EFE2;  /* canvas                              */
    --secondary-background: #FBF7EC;  /* raised cards                        */
    --tertiary-background:  #FFFFFF;  /* controls / field rows               */
    --grouped-background:   #EFE9DA;  /* grouped scenes                      */

    --separator:        rgba(120, 100, 60, 0.26);
    --opaque-separator: #DED4BE;

    /* Frosted ivory glass */
    --glass-bg:       rgba(250, 246, 236, 0.74);
    --glass-bg-thick: rgba(248, 243, 231, 0.92);

    /* Softer, warm shadows on light (less ink, more spread) */
    --elev-1: 0 1px 2px rgba(90,70,20,.10), 0 0 0 .5px rgba(154,123,46,.10);
    --elev-2: 0 2px 6px rgba(90,70,20,.12), 0 1px 2px rgba(90,70,20,.08);
    --elev-3: 0 6px 18px rgba(90,70,20,.14), 0 2px 6px rgba(90,70,20,.08);
    --elev-4: 0 14px 40px rgba(90,70,20,.16), 0 4px 12px rgba(90,70,20,.10);
    --elev-5: 0 24px 70px rgba(90,70,20,.20), 0 8px 24px rgba(90,70,20,.12);

    /* Atmospheric wash — a warm ivory glow, lighter than dark */
    --wash-1: rgba(212, 175, 90, 0.16);
    --wash-2: rgba(180, 140, 70, 0.08);

    /* Art scrim needs to stay dark so white overlaid numerals remain legible
       over anime art even in light mode (the art itself is imagery). */
    --art-scrim: linear-gradient(180deg, rgba(0,0,0,0) 38%, rgba(0,0,0,0.48) 100%);
}

/* Light-mode canvas + ink follow the tokens (html base bg is set inline in
   style.css via var(--system-background), so this Just Works). Nudge the
   default text colour so the reset picks up ink immediately. */
html[data-theme="light"] body { color: var(--label); }

/* On light, the anime day backgrounds read a touch heavy — lift them so the
   ivory identity shows through while art stays present. */
html[data-theme="light"] .day-bg { opacity: 0.42; }


/* ============================================================================
   3. MATERIAL LAYER — atmospheric wash + baked grain + art scrims
   A fixed, non-interactive wash and a data-URI feTurbulence grain sit at
   z-index:-1 BEHIND all content, so they can never cover the grid.
   ============================================================================ */

/* Radial / mesh gradient wash — pinned behind everything */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(120% 90% at 12% -8%,  var(--wash-1) 0%, transparent 55%),
        radial-gradient(120% 90% at 92% 0%,   var(--wash-2) 0%, transparent 50%),
        radial-gradient(140% 120% at 50% 108%, var(--wash-1) 0%, transparent 60%);
}

/* Baked feTurbulence grain, embedded as a data-URI SVG (no external asset).
   soft-light blend + low opacity gives surfaces a premium tactile tooth. */
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    opacity: 0.04;
    mix-blend-mode: soft-light;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size: 140px 140px;
}
html[data-theme="light"] body::after { opacity: 0.05; mix-blend-mode: multiply; }

/* Art scrims — a bottom-dark gradient over the anime imagery so the white
   day numerals / titles layered on top stay WCAG-legible. Added as a pseudo
   so the underlying .day-bg image is untouched. */
.day-cell .day-bg::after,
#day-view-bg::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--art-scrim);
    pointer-events: none;
}
/* .day-bg is set position:absolute in style.css; ensure the pseudo anchors. */
.day-cell .day-bg { }


/* ============================================================================
   4. PREMIUM CHROME — richer glass, bevels, day-cell frame, today ring,
   elevation, refined dots, deeper list cards, brand glow.
   ============================================================================ */

/* --- Glass surfaces: header / weekday-bar / footer -----------------------
   backdrop blur + saturate, hairline bottom border, inset top highlight.   */
#header,
#weekday-bar {
    background: var(--glass-bg);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
}
#header { border-bottom: 0.5px solid var(--separator); }

#footer {
    background: var(--glass-bg-thick);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border-top: 0.5px solid var(--separator);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
}
html[data-theme="light"] #header,
html[data-theme="light"] #weekday-bar,
html[data-theme="light"] #footer {
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.60);
}

/* Brand glow on the month title + gold sheen on identity text */
#month-title {
    letter-spacing: -0.2px;
    background: linear-gradient(180deg, var(--label) 0%, var(--label) 62%, rgba(212,168,67,0.85) 190%);
    -webkit-background-clip: text;
    background-clip: text;
    text-shadow: 0 0 18px var(--brand-glow);
}
html[data-theme="light"] #month-title {
    text-shadow: none; /* keep crisp ink on ivory */
}

/* --- Day-cell frame: hairline border + inner top-highlight bevel --------- */
.day-cell {
    border-right: 0.5px solid var(--separator);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.035);
}
/* Trim the trailing column edge (7-col grid) for a clean right margin. */
.day-cell:nth-child(7n) { border-right: none; }
html[data-theme="light"] .day-cell {
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.45);
}

/* Desktop hover lift — pointer-only, will-change managed via :hover state */
@media (hover: hover) and (pointer: fine) {
    .day-cell {
        transition: background var(--dur-fast) var(--ease-out),
                    transform var(--dur-fast) var(--spring);
    }
    .day-cell:hover {
        will-change: transform;
        transform: translateY(-1px);
        background: rgba(212,168,67,0.06);
        z-index: 2;
    }
    html[data-theme="light"] .day-cell:hover {
        background: rgba(154,123,46,0.08);
    }
}

/* --- Today: glowing gold ring -------------------------------------------
   A gradient hairline ring drawn with mask-composite (where supported) plus
   a soft box-shadow bloom. Graceful fallback to a solid gold hairline.     */
.day-cell.is-today {
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,0.05),
        inset 0 0 0 1px rgba(212,168,67,0.35),
        0 0 18px -4px var(--brand-glow);
}
@supports ((-webkit-mask-composite: xor) or (mask-composite: exclude)) {
    .day-cell.is-today::after {
        content: "";
        position: absolute;
        inset: 0;
        z-index: 2;
        pointer-events: none;
        padding: 1px;
        border-radius: inherit;
        background: linear-gradient(150deg, var(--brand-bright), var(--brand), var(--brand-deep));
        -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
                mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
        -webkit-mask-composite: xor;
                mask-composite: exclude;
    }
    /* Ring drawn by the pseudo — drop the inset hairline, keep the bloom. */
    .day-cell.is-today {
        box-shadow:
            inset 0 1px 0 rgba(255,255,255,0.05),
            0 0 20px -4px var(--brand-glow);
    }
}

/* Today numeral: keep the gold pill, add a crisper gold bloom */
.day-cell.is-today .day-number {
    background: linear-gradient(160deg, var(--brand-bright) 0%, var(--brand) 55%, var(--brand-deep) 100%);
    color: #201700;
    box-shadow: 0 2px 10px -1px var(--brand-glow), inset 0 1px 0 rgba(255,255,255,0.35);
}

/* --- Event dots: refined, softly glowing --------------------------------- */
.event-dot {
    box-shadow: 0 0 4px -1px currentColor, inset 0 0.5px 0 rgba(255,255,255,0.4);
}

/* --- Elevation on floating surfaces -------------------------------------- */
.modal-sheet     { box-shadow: var(--elev-5); }
.action-sheet-group { box-shadow: var(--elev-4); }

/* List cards: more depth + hairline frame + hover lift on desktop */
.list-event-group {
    box-shadow: var(--elev-2);
    border: 0.5px solid var(--separator);
}
@media (hover: hover) and (pointer: fine) {
    .list-event-item {
        transition: background var(--dur-fast) var(--ease-out),
                    transform var(--dur-fast) var(--spring);
    }
    .list-event-item:hover {
        background: rgba(212,168,67,0.06);
    }
    html[data-theme="light"] .list-event-item:hover {
        background: rgba(154,123,46,0.07);
    }
}

/* Refined datetime input tint — was raw blue, now the retoned tone */
.form-field input[type="datetime-local"] { color: var(--apple-blue); }

/* Detail links pick up the refined blue automatically via --apple-blue. */


/* ============================================================================
   5. TYPOGRAPHY POLISH — tabular numerals + tightened tracking, and a fix
   for the cramped list micro-type.
   ============================================================================ */

.day-number,
.hour-label,
.list-event-time,
.aeon-week-hour,
.timeline-event-time,
.event-time {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

#day-title { letter-spacing: -0.2px; }

/* Loosen the tightest list captions so they stop feeling cramped. */
.list-event-time     { font-size: 11px; letter-spacing: 0.2px; line-height: 1.35; }
.list-event-location { font-size: 10px; letter-spacing: 0.1px; line-height: 1.35; }
.list-event-subtitle { font-size: 10px; letter-spacing: 0.1px; line-height: 1.35; }
.list-section-subheader { font-size: 9px; letter-spacing: 0.4px; }


/* ============================================================================
   6. MOTION — view-transition cross-fade + skeleton shimmer.
   All motion is opacity/transform/filter only. Non-essential motion is gated
   behind prefers-reduced-motion (see §8) or provided as an enhancement.
   ============================================================================ */

@media (prefers-reduced-motion: no-preference) {
    /* Cross-document / same-document root view transition — a gentle fade. */
    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation-duration: var(--dur);
        animation-timing-function: var(--ease-in-out);
    }
    ::view-transition-old(root) { animation-name: aeon-vt-out; }
    ::view-transition-new(root) { animation-name: aeon-vt-in; }

    @keyframes aeon-vt-out { to { opacity: 0; } }
    @keyframes aeon-vt-in  { from { opacity: 0; } }
}

/* Gold shimmer sweep for loading skeletons (reused across new components). */
.aeon-skeleton {
    position: relative;
    overflow: hidden;
    background: var(--tertiary-background);
    border-radius: var(--radius-md);
}
.aeon-skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(212,168,67,0.14) 45%,
        rgba(240,210,126,0.22) 50%,
        rgba(212,168,67,0.14) 55%,
        transparent 100%
    );
}
@media (prefers-reduced-motion: no-preference) {
    .aeon-skeleton::after { animation: aeon-shimmer 1.6s var(--ease-in-out) infinite; }
}
@keyframes aeon-shimmer {
    to { transform: translateX(100%); }
}


/* ============================================================================
   7. NEW COMPONENTS
   ============================================================================ */

/* ------------------------------------------------------------------ 7a. Theme
   toggle — <button id="aeon-theme-toggle" class="header-btn"> injected into
   .header-top before #list-view-btn. Styled for both themes; 44px hit area. */
#aeon-theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0 6px;
    color: var(--brand-ink);
    border-radius: var(--radius-full);
    transition: transform var(--dur-fast) var(--spring),
                background var(--dur-fast) var(--ease-out);
}
#aeon-theme-toggle svg { width: 20px; height: 20px; display: block; }
#aeon-theme-toggle:active { transform: scale(0.9); }
@media (hover: hover) and (pointer: fine) {
    #aeon-theme-toggle:hover { background: var(--quaternary-label); }
}


/* ------------------------------------------------------------- 7b. Command
   palette — <dialog id="aeon-cmdk" class="aeon-cmdk"> centred, frosted.
   Opened by Cmd/Ctrl-K or "/".                                              */
.aeon-cmdk {
    border: none;
    padding: 0;
    margin: 0;
    background: transparent;
    max-width: none;
    max-height: none;
    color: var(--label);
    overflow: visible;
}
.aeon-cmdk:not([open]) { display: none; }
/* Native centring for <dialog>; fall back-friendly. */
.aeon-cmdk[open] {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: max(12vh, 64px) var(--space-4) var(--space-4);
}
.aeon-cmdk::backdrop {
    background: rgba(0,0,0,0.45);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}

.aeon-cmdk-box {
    width: 100%;
    max-width: 560px;
    background: var(--glass-bg-thick);
    -webkit-backdrop-filter: saturate(180%) blur(30px);
    backdrop-filter: saturate(180%) blur(30px);
    border: 0.5px solid var(--separator);
    border-radius: var(--radius-xl);
    box-shadow: var(--elev-5), inset 0 1px 0 rgba(255,255,255,0.07);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: min(64vh, 520px);
}
@media (prefers-reduced-motion: no-preference) {
    .aeon-cmdk[open] .aeon-cmdk-box { animation: aeon-cmdk-in var(--dur) var(--spring) both; }
}
@keyframes aeon-cmdk-in {
    from { opacity: 0; transform: translateY(-8px) scale(0.98); }
    to   { opacity: 1; transform: none; }
}

.aeon-cmdk-input {
    appearance: none;
    border: none;
    outline: none;
    background: transparent;
    color: var(--label);
    font-family: inherit;
    font-size: var(--font-title3);
    font-weight: 500;
    padding: var(--space-4) var(--space-4);
    border-bottom: 0.5px solid var(--separator);
    width: 100%;
}
.aeon-cmdk-input::placeholder { color: var(--tertiary-label); }

.aeon-cmdk-list {
    list-style: none;
    margin: 0;
    padding: var(--space-2);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--tertiary-label) transparent;
}
.aeon-cmdk-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-3);
    border-radius: var(--radius-md);
    cursor: pointer;
    color: var(--label);
    min-height: 44px;
    transition: background var(--dur-fast) var(--ease-out);
}
/* Selected item — gold highlight (JS sets aria-selected="true"). */
.aeon-cmdk-item[aria-selected="true"] {
    background: linear-gradient(180deg, rgba(212,168,67,0.22), rgba(212,168,67,0.14));
    box-shadow: inset 0 0 0 0.5px rgba(212,168,67,0.45);
}
html[data-theme="light"] .aeon-cmdk-item[aria-selected="true"] {
    background: rgba(154,123,46,0.14);
    box-shadow: inset 0 0 0 0.5px rgba(154,123,46,0.40);
}
@media (hover: hover) and (pointer: fine) {
    .aeon-cmdk-item:hover { background: var(--quaternary-label); }
}
.aeon-cmdk-icon {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--brand-ink);
}
.aeon-cmdk-icon svg { width: 20px; height: 20px; display: block; }
.aeon-cmdk-label {
    flex: 1;
    min-width: 0;
    font-size: var(--font-callout);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.aeon-cmdk-hint {
    flex-shrink: 0;
    font-size: var(--font-caption1);
    color: var(--secondary-label);
    font-variant-numeric: tabular-nums;
    padding: 2px 7px;
    border-radius: var(--radius-sm);
    background: var(--quaternary-label);
    letter-spacing: 0.3px;
}
.aeon-cmdk-empty {
    list-style: none;
    padding: var(--space-6) var(--space-4);
    text-align: center;
    color: var(--secondary-label);
    font-size: var(--font-subhead);
}


/* --------------------------------------------------------------- 7c. Week view
   <section id="aeon-week" class="aeon-week hidden"> — a full week timeline.
   Shown by removing .hidden then adding .visible (mirrors #list-view).      */
.aeon-week {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    flex-direction: column;
    background: var(--grouped-background);
    transform: translateX(100%);
    transition: transform var(--dur-slow) var(--ease-out);
}
.aeon-week.visible { transform: translateX(0); }
.aeon-week.hidden  { transform: translateX(100%); }

.aeon-week-header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: calc(var(--sat) + 10px) var(--space-4) 10px;
    background: var(--glass-bg);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border-bottom: 0.5px solid var(--separator);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
}
.aeon-week-title {
    flex: 1;
    font-size: var(--font-title2);
    font-weight: 700;
    letter-spacing: -0.2px;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.aeon-week-close,
.aeon-week-nav {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0 6px;
    background: none;
    border: none;
    color: var(--brand-ink);
    font-family: inherit;
    font-size: var(--font-headline);
    cursor: pointer;
    border-radius: var(--radius-full);
    transition: transform var(--dur-fast) var(--spring), background var(--dur-fast) var(--ease-out);
}
.aeon-week-close:active,
.aeon-week-nav:active { transform: scale(0.9); }
.aeon-week-nav svg,
.aeon-week-close svg { width: 18px; height: 18px; display: block; }

/* Sticky day-name header row (aligns with the 7 columns; hours gutter first) */
.aeon-week-daynames {
    display: grid;
    grid-template-columns: 56px repeat(7, 1fr);
    background: var(--glass-bg);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border-bottom: 0.5px solid var(--separator);
    position: sticky;
    top: 0;
    z-index: 3;
}
.aeon-week-dayname {
    grid-column: auto;
    text-align: center;
    padding: 6px 0;
    font-size: var(--font-caption2);
    font-weight: 600;
    color: var(--secondary-label);
    text-transform: uppercase;
    letter-spacing: 0.3px;
    font-variant-numeric: tabular-nums;
}
/* leave the first grid cell (hours gutter) empty */
.aeon-week-daynames::before { content: ""; }
.aeon-week-dayname.is-today {
    color: var(--brand-ink);
    font-weight: 700;
}
.aeon-week-dayname.is-today::after {
    content: "";
    display: block;
    width: 5px; height: 5px;
    margin: 3px auto 0;
    border-radius: 50%;
    background: var(--brand);
    box-shadow: 0 0 6px var(--brand-glow);
}

/* All-day row */
.aeon-week-allday {
    display: grid;
    grid-template-columns: 56px repeat(7, 1fr);
    border-bottom: 0.5px solid var(--separator);
    background: var(--secondary-background);
    min-height: 28px;
}
.aeon-week-allday::before {
    content: "all-day";
    font-size: 9px;
    color: var(--secondary-label);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    align-self: center;
    text-align: right;
    padding-right: 8px;
}
.aeon-week-allday-cell {
    border-left: 0.5px solid var(--separator);
    padding: 3px 4px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

/* Scrollable hour grid */
.aeon-week-scroll {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--tertiary-label) transparent;
    padding-bottom: calc(var(--sab) + var(--space-4));
}
.aeon-week-grid {
    display: grid;
    grid-template-columns: 56px repeat(7, 1fr);
    position: relative;
    height: 1440px; /* 24h × 60px — matches the day timeline scale */
}
.aeon-week-hours {
    position: relative;
    border-right: 0.5px solid var(--separator);
}
.aeon-week-hour {
    height: 60px;
    font-size: var(--font-caption1);
    color: var(--secondary-label);
    text-align: right;
    padding-right: 8px;
    transform: translateY(-7px);
    font-variant-numeric: tabular-nums;
}
.aeon-week-col {
    position: relative;                 /* anchor for absolute events        */
    border-left: 0.5px solid var(--separator);
    background-image: repeating-linear-gradient(
        180deg,
        transparent 0,
        transparent 59.5px,
        var(--separator) 59.5px,
        var(--separator) 60px
    );
}
/* Timed event blocks — positioned by JS via inline top/height. */
.aeon-week-event {
    position: absolute;
    left: 2px;
    right: 2px;
    border-radius: var(--radius-sm);
    padding: 3px 6px;
    font-size: 10px;
    font-weight: 600;
    color: #FFFFFF;
    overflow: hidden;
    min-height: 16px;
    box-shadow: var(--elev-1);
    cursor: pointer;
    /* JS supplies background per event colour; this is a safe fallback. */
    background: var(--brand-deep);
    transition: transform var(--dur-fast) var(--spring);
}
.aeon-week-event:active { transform: scale(0.97); }
/* Gold "now" line spanning the day columns */
.aeon-week-now {
    position: absolute;
    left: 56px;
    right: 0;
    height: 2px;
    background: linear-gradient(90deg, var(--brand-bright) 0%, var(--brand) 55%, transparent 100%);
    box-shadow: 0 0 8px var(--brand-glow), 0 0 3px rgba(255,215,0,0.6);
    z-index: 5;
    pointer-events: none;
}
.aeon-week-now::before {
    content: "";
    position: absolute;
    left: -5px; top: -4px;
    width: 10px; height: 10px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--brand-bright) 0%, var(--brand) 45%, var(--brand-deep) 100%);
    box-shadow: 0 0 8px var(--brand-glow);
}


/* ------------------------------------------------------------ 7d. Tab bar
   <nav id="aeon-tabbar"> — bottom glass bar, ONLY in installed (standalone)
   PWA mode. Adds safe-area bottom inset so it clears the home indicator.    */
#aeon-tabbar {
    display: none; /* hidden by default; revealed only in standalone below   */
}
@media (display-mode: standalone) {
    #aeon-tabbar {
        position: fixed;
        left: 0; right: 0; bottom: 0;
        z-index: 250;
        display: flex;
        justify-content: space-around;
        align-items: stretch;
        gap: 2px;
        padding: 6px var(--space-2);
        padding-bottom: calc(var(--sab) + 6px);
        background: var(--glass-bg-thick);
        -webkit-backdrop-filter: var(--glass-blur);
        backdrop-filter: var(--glass-blur);
        border-top: 0.5px solid var(--separator);
        box-shadow: inset 0 1px 0 rgba(255,255,255,0.05), 0 -6px 20px rgba(0,0,0,0.30);
    }
    /* Keep the footer + scenes clear of the bar. */
    body { }
    #app { padding-bottom: calc(var(--sab) + 58px); }
    #list-content,
    #day-timeline,
    .aeon-week-scroll { padding-bottom: calc(var(--sab) + 74px); }
}
.aeon-tab {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: 44px;
    padding: 4px 0;
    background: none;
    border: none;
    color: var(--secondary-label);
    font-family: inherit;
    cursor: pointer;
    border-radius: var(--radius-md);
    transition: transform var(--dur-fast) var(--spring), color var(--dur-fast) var(--ease-out);
}
.aeon-tab:active { transform: scale(0.92); }
.aeon-tab[aria-current="page"],
.aeon-tab.is-active { color: var(--brand-ink); }
.aeon-tab-icon { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }
.aeon-tab-icon svg { width: 22px; height: 22px; display: block; }
.aeon-tab-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.2px;
}


/* ============================================================================
   8. ACCESSIBILITY
   ============================================================================ */

/* Strong gold focus rings — only for keyboard users (:focus-visible). */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible,
.day-cell:focus-visible,
.header-btn:focus-visible,
.nav-chevron:focus-visible,
#aeon-theme-toggle:focus-visible,
.aeon-cmdk-input:focus-visible,
.aeon-cmdk-item:focus-visible,
.aeon-tab:focus-visible,
.aeon-week-close:focus-visible,
.aeon-week-nav:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}
/* Day cells clip overflow; use an inset ring so focus stays visible. */
.day-cell:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 2px var(--brand);
    z-index: 3;
}

/* Screen-reader-only utility */
.aeon-sr-only {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Skip link — hidden until focused, then a gold pill top-left */
.aeon-skip-link {
    position: fixed;
    top: 0; left: 0;
    z-index: 10000;
    transform: translateY(-120%);
    margin: 8px;
    padding: 10px 16px;
    background: var(--brand);
    color: #201700;
    font-weight: 600;
    border-radius: var(--radius-md);
    box-shadow: var(--elev-3);
    text-decoration: none;
    transition: transform var(--dur-fast) var(--ease-out);
}
.aeon-skip-link:focus { transform: translateY(0); }

/* Guarantee 44px hit areas on the injected controls */
#aeon-theme-toggle,
.aeon-tab,
.aeon-week-close,
.aeon-week-nav { min-width: 44px; min-height: 44px; }

/* Comprehensive reduced-motion override — kill non-essential motion but keep
   opacity state changes usable. Complements style.css's own reduce block. */
@media (prefers-reduced-motion: reduce) {
    body::after { animation: none !important; }
    .aeon-skeleton::after { animation: none !important; }
    .aeon-cmdk[open] .aeon-cmdk-box { animation: none !important; }
    .aeon-week { transition: none !important; }
    ::view-transition-old(root),
    ::view-transition-new(root) { animation: none !important; }
    .day-cell:hover,
    .list-event-item:hover { transform: none !important; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* =========================================================================
   TIMEZONE ADAPTATION — viewer chip + notes
   Shown only when the viewer's clock differs from the calendar's UK home
   time. The chip sits at the right edge of the footer; notes appear in the
   event-detail sheet and the admin edit modal.
   ========================================================================= */

.footer-content { position: relative; }

.footer-tz {
    position: absolute;
    right: 16px;
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.3px;
    /* This chip's whole job is telling a viewer their times are converted —
       tertiary-label read at ~2.45:1, too faint for that to register. */
    color: var(--secondary-label);
    padding: 3px 9px;
    border-radius: 999px;
    border: 0.5px solid var(--separator);
    background: color-mix(in oklab, var(--brand) 6%, transparent);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    cursor: default;
}
.footer-tz svg { color: var(--brand-ink); opacity: 0.85; flex: none; }

/* "Your time · EDT" suffix on the detail sheet's Time row */
.detail-tz-note {
    display: block;
    margin-top: 3px;
    font-size: var(--font-caption2);
    font-weight: 500;
    color: var(--brand-ink);
    /* No opacity reduction: --brand-ink already clears AA at full strength
       (5.3-6.1:1 in light theme), and dimming it below 0.9 was the actual
       cause of the light-theme failure (down to 2.69:1) — the audit flagged
       this rule by name. */
    letter-spacing: 0.2px;
}

/* Hint under Starts/Ends in the admin modal */
.form-tz-note {
    padding: 8px 16px 10px;
    font-size: var(--font-caption2);
    color: var(--tertiary-label);
    text-align: center;
    letter-spacing: 0.2px;
}

/* =========================================================================
   ACCESSIBILITY — grid semantics, density badge, legible numbers, focus
   ========================================================================= */

/* Week wrappers carry role="row" for screen readers but must not disturb the
   7-column CSS grid, so they collapse out of the layout box tree. */
.month-week { display: contents; }

/* Keyboard focus ring on day cells (roving tabindex) and other controls. */
.day-cell:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: -2px;
    z-index: 3;
    border-radius: 4px;
}

/* Day numbers legible over ANY artwork. Dark theme passes on its own; a soft
   halo hardens it. Light theme fades the art onto a near-white page, so the
   white numeral gets a translucent dark coin to guarantee >= 4.5:1 (audit
   found white-on-bright failing at ~1.3:1). */
/* Dark theme relies on white-on-artwork, and the artwork is photographic — so
   the contrast varies per tile. Measured against the real painted pixels, the
   white numerals held 5.6-17.3:1 at median but fell to ~3.1:1 over the brightest
   tiles, and the de-emphasised adjacent-month numerals sat near 1.6:1, which is
   effectively unreadable. A soft radial scrim under the glyph guarantees the
   floor without turning the numeral into a hard pill, keeping the airy look. */
.day-number {
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.75);
    background: radial-gradient(circle,
        rgba(0, 0, 0, 0.55) 0%,
        rgba(0, 0, 0, 0.44) 55%,
        rgba(0, 0, 0, 0) 78%);
}
/* Adjacent-month days stay clearly recessed, but readable rather than ghosted. */
.day-cell.other-month .day-number,
.day-cell.other-month.weekend .day-number {
    color: rgba(255, 255, 255, 0.68);
}
/* No override is needed for the today coin or the light-theme coin: both are
   selected more specifically than the bare `.day-number` scrim above, so they
   already win the cascade and keep their own ground. (An earlier attempt to
   force `background-image: none` here silently erased the today coin's gold
   gradient — it IS a background-image — leaving dark-on-artwork.) */
html[data-theme="light"] .day-cell:not(.is-today) .day-number {
    background: rgba(0, 0, 0, 0.62);
    color: #ffffff;
    text-shadow: none;
}
html[data-theme="light"] .day-cell.other-month:not(.is-today) .day-number {
    background: rgba(0, 0, 0, 0.55);
}

/* Month-cell density: "+N" when a day has more than three events. */
.event-more {
    font-size: 9px;
    font-weight: 700;
    line-height: 1;
    color: var(--secondary-label);
    margin-left: 2px;
    font-variant-numeric: tabular-nums;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}
html[data-theme="light"] .event-more { color: #2a2417; text-shadow: none; }

/* Weekday header labels: lift contrast to meet 1.4.3 (audit: 2.36:1).
   Theme-explicit + higher specificity so they beat the base low-alpha rule. */
html[data-theme="dark"] #weekday-bar span  { color: #e8e0cf; opacity: 0.82; }
html[data-theme="light"] #weekday-bar span { color: #403a26; opacity: 1; }

/* =========================================================================
   TOAST — connectivity / error surfacing
   ========================================================================= */
#aeon-toast {
    position: fixed;
    left: 50%;
    bottom: calc(var(--sab, 0px) + 68px);
    transform: translate(-50%, 12px);
    max-width: min(92vw, 420px);
    padding: 11px 18px;
    border-radius: 999px;
    background: var(--glass-bg-thick, rgba(20,16,10,0.92));
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    backdrop-filter: saturate(180%) blur(14px);
    border: 0.5px solid var(--separator);
    box-shadow: var(--elev-4, 0 8px 30px rgba(0,0,0,0.5));
    color: var(--label);
    font-size: var(--font-footnote, 13px);
    font-weight: 500;
    text-align: center;
    z-index: 500;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur, .25s) ease, transform var(--dur, .25s) var(--spring, ease);
}
#aeon-toast.visible { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
    #aeon-toast { transition: opacity .01ms; }
}

/* Toast action button (e.g. Undo) */
.aeon-toast-action {
    margin-left: 14px;
    padding: 4px 10px;
    border: none;
    background: transparent;
    color: var(--brand-bright, #F0D27E);
    font: inherit;
    font-weight: 700;
    font-size: var(--font-footnote, 13px);
    cursor: pointer;
    border-radius: 6px;
    min-height: 32px;
}
.aeon-toast-action:hover { background: rgba(255,255,255,0.08); }
html[data-theme="light"] .aeon-toast-action { color: var(--brand, #9A7B2E); }
#aeon-toast { display: inline-flex; align-items: center; }

/* =========================================================================
   TOUCH TARGETS + list-header subscribe/search (WCAG 2.5.5 / Apple HIG 44px)
   ========================================================================= */
.header-btn, .nav-chevron {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* #today-btn is text — keep it snug but tall enough to tap. */
#today-btn { min-width: 0; padding-left: 4px; padding-right: 8px; }

#list-header { display: flex; align-items: center; gap: 8px; }
#list-header #list-title { flex: 1; }
#subscribe-btn {
    margin-left: auto;
    color: var(--brand-ink);
    text-decoration: none;
}
#subscribe-btn:hover { opacity: 0.85; }

/* PWA "update available" bar */
#aeon-update-bar {
    position: fixed;
    left: 50%;
    bottom: calc(var(--sab, 0px) + 68px);
    transform: translate(-50%, 14px);
    display: inline-flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px 10px 18px;
    border-radius: 999px;
    background: var(--glass-bg-thick, rgba(20,16,10,0.94));
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    backdrop-filter: saturate(180%) blur(14px);
    border: 0.5px solid var(--separator);
    box-shadow: var(--elev-4, 0 8px 30px rgba(0,0,0,0.5));
    color: var(--label);
    font-size: var(--font-footnote, 13px);
    z-index: 600;
    opacity: 0;
    transition: opacity .25s ease, transform .25s var(--spring, ease);
}
#aeon-update-bar.visible { opacity: 1; transform: translate(-50%, 0); }
#aeon-update-btn {
    border: none;
    background: var(--brand);
    color: #201700;
    font: inherit;
    font-weight: 700;
    padding: 6px 14px;
    border-radius: 999px;
    cursor: pointer;
    min-height: 34px;
}

/* Event-detail action row (Add to Calendar + Share) */
.detail-actions { display: flex; gap: 10px; margin-top: 6px; }
.detail-actions .add-to-calendar-btn { flex: 1; }
.detail-share-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    padding: 12px 16px; min-height: 44px;
    border: 0.5px solid var(--separator);
    border-radius: var(--radius-lg, 12px);
    background: var(--tertiary-background);
    color: var(--label);
    font: inherit; font-weight: 600; cursor: pointer;
}
.detail-share-btn:hover { border-color: var(--brand); }

/* Recurrence plain-English preview under the Repeat control */
.repeat-preview {
    padding: 6px 16px 2px;
    font-size: var(--font-caption1, 12px);
    color: var(--brand-ink);
    /* See .detail-tz-note above — the opacity reduction was what pushed this
       below AA in the light theme (audit-confirmed at 2.69:1). */
}

/* Month empty-state hint (no events this month) */
#month-empty {
    position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%);
    max-width: 88%;
    padding: 8px 16px; border-radius: 999px;
    background: var(--glass-bg-thick); border: 0.5px solid var(--separator);
    -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
    color: var(--secondary-label); font-size: var(--font-caption1, 12px);
    text-align: center; z-index: 4; pointer-events: none;
}

/* "Now" badge on an in-progress event */
.now-badge {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 7px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: #201700;
    background: var(--brand);
    border-radius: 999px;
    vertical-align: middle;
    animation: nowPulse 2s ease-in-out infinite;
}
@keyframes nowPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }
@media (prefers-reduced-motion: reduce) { .now-badge { animation: none; } }

/* =========================================================================
   JOIN CTA · timezone picker · empty-state link
   ========================================================================= */
.detail-join-btn {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    margin: 4px 0 12px;
    padding: 14px 18px; min-height: 48px;
    border-radius: var(--radius-lg, 12px);
    background: var(--brand); color: #201700;
    font-weight: 700; font-size: var(--font-body, 17px);
    text-decoration: none;
    box-shadow: var(--elev-2);
}
.detail-join-btn:hover { filter: brightness(1.06); }
.detail-join-btn.is-live {
    background: linear-gradient(135deg, var(--brand-bright), var(--brand));
    animation: joinPulse 2.4s ease-in-out infinite;
}
@keyframes joinPulse {
    0%,100% { box-shadow: var(--elev-2), 0 0 0 0 var(--brand-glow); }
    50%     { box-shadow: var(--elev-2), 0 0 0 10px rgba(212,168,67,0); }
}
@media (prefers-reduced-motion: reduce) { .detail-join-btn.is-live { animation: none; } }

/* Timezone select sits with the other form rows */
#tz-field select { width: 100%; }

/* Empty-state becomes a real affordance pointing at the next event */
.month-empty-link {
    border: none; background: none; font: inherit; color: var(--brand-ink);
    cursor: pointer; padding: 0; text-align: center;
    text-decoration: underline; text-underline-offset: 3px;
}
.month-empty-link:hover { filter: brightness(1.15); }

/* ------------------------------------------------------------------ 14. Audit
   fixes — modal header buttons.

   .modal-nav-btn carries only `padding: 4px`, which rendered #detail-close
   ("Done") at 48x28 — comfortably wide but 16px short of the 44px minimum
   touch target, and it sits in the corner of a sheet where a mis-tap means
   dismissing something the user wanted to read. Height only; the visual weight
   of the label is unchanged. */
.modal-nav-btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    padding: 4px 8px;
}
