/* 1x2 Codex - Neon Dark Theme */

/* ================================
   DESIGN TOKENS — single source of truth (17.2)
   Solo --sport-color resta inline in base.html perché Django-rendered
   per-sport. Valori canonici = quelli effettivi pre-consolidamento
   (l'inline <style> di base.html vinceva sul cascade).
   ================================ */
:root {
    --bg-dark: #020617;
    --bg-card: rgba(15, 23, 42, 0.6);
    --bg-panel: rgba(30, 41, 59, 0.4);
    --accent-primary: #2563eb;          /* 17.F2: cyan -> blue-600 (perno brand Cap.12) */
    --accent-secondary: #14b8a6;        /* 17.F2: violet -> teal-500 (accento secondario) */
    --accent-glow: rgba(37, 99, 235, 0.3);   /* 17.F2: glow blue (era ciano 6,182,212) */
    --text-main: #f1f5f9;
    --text-muted: #94a3b8;
    --glass-bg: rgba(15, 23, 42, 0.7);
    --glass-border: rgba(255, 255, 255, 0.35);   /* §10.609: era 0.08 — 1,3:1 sul fondo scuro */
    --sidebar-bg: rgba(15, 23, 42, 0.9);
    --glass-shadow: none;          /* dark: nessuna ombra glass (invariato) */
}

/* Tema chiaro (17.5): ridisegno del glass.
   Prima: --glass-bg white 0.8 (quasi opaco) su bg quasi-bianco #f8fafc +
   --glass-border 0.05 (invisibile) => superfici come blocchi piatti, blur
   impercettibile. Ora: pagina leggermente più fredda, glass più trasparente
   (blur percepibile), bordo slate leggero ma visibile e un'ombra morbida per
   staccare la superficie dal fondo. Stesso linguaggio del dark, adattato al
   chiaro. Il dark resta intatto. */
[data-theme="light"] {
    --bg-dark: #eef2f7;
    --bg-card: rgba(255, 255, 255, 0.55);
    --bg-panel: rgba(255, 255, 255, 0.6);
    --text-main: #0f172a;
    --text-muted: #475569;                       /* slate-600: +contrasto vs #64748b */
    --glass-bg: rgba(255, 255, 255, 0.55);       /* era 0.8 opaco -> 0.55 traslucido */
    --glass-border: rgba(15, 23, 42, 0.12);      /* era rgba(0,0,0,0.05) invisibile */
    --sidebar-bg: rgba(255, 255, 255, 0.6);
    --glass-shadow: 0 4px 24px rgba(15, 23, 42, 0.08);  /* lift morbido, solo chiaro */
}

body {
    background-color: var(--bg-dark);
    color: var(--text-main);
    font-family: 'Inter', sans-serif;
    overflow-x: hidden;
    transition: background-color 0.3s ease, color 0.3s ease;
    background-image:
        radial-gradient(at 0% 0%, rgba(37, 99, 235, 0.05) 0px, transparent 50%),
        radial-gradient(at 100% 0%, rgba(20, 184, 166, 0.05) 0px, transparent 50%);
    background-attachment: fixed;
}

/* Typography (17.3/17.5): titles always Outfit, body/data Inter.
   Theme-independent — Tailwind Preflight makes headings inherit the body
   font (Inter) by default (Preflight sets font-family only on `html`, never
   on h1-h6), so without this rule headings render Inter in BOTH themes
   unless they carry .font-display.
   17.5: the heading selector is scoped under :root to raise its specificity
   to (0,1,1). This makes it beat any Tailwind font-family utility — e.g. a
   stray .font-sans (0,1,0) — that the CDN injects LATER in the cascade,
   without resorting to !important. :root (= <html>) always matches and does
   NOT depend on the JS-set [data-theme] attribute, so it survives JS-off. */
:root h1, :root h2, :root h3, :root h4, :root h5, :root h6 {
    font-family: 'Outfit', sans-serif;
}
.font-display {
    font-family: 'Outfit', sans-serif;
}

/* Glassmorphism */
.glass {
    background: var(--glass-bg);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--glass-border);
    box-shadow: var(--glass-shadow);   /* none nel dark, lift morbido nel chiaro */
}

.glass-panel {
    background: var(--bg-panel);
    backdrop-filter: blur(8px);
    border: 1px solid var(--glass-border);
    border-radius: 1rem;
}

/* Neon Glows */
.neon-text {
    text-shadow: 0 0 10px rgba(37, 99, 235, 0.5);
}

.neon-border {
    border-color: var(--accent-primary);
    box-shadow: 0 0 10px rgba(37, 99, 235, 0.3);
}

.neon-box {
    box-shadow: 0 0 15px rgba(37, 99, 235, 0.2), inset 0 0 10px rgba(37, 99, 235, 0.1);
}

/* Scrollbar */
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: var(--bg-dark);
}

::-webkit-scrollbar-thumb {
    background: var(--text-muted);
    border-radius: 4px;
    opacity: 0.5;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--accent-primary);
}

/* Animations */
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.animate-fade-in {
    animation: fadeIn 0.5s ease-out forwards;
}

/* Dynamic Sport Colors (Will be overridden by inline styles) */
.sport-glow {
    box-shadow: 0 0 15px currentColor;
}

/* ================================
   MOBILE RESPONSIVENESS
   ================================ */

/* Tabelle: sempre scrollabili orizzontalmente su mobile */
.overflow-x-auto {
    -webkit-overflow-scrolling: touch;
}

/* Profilo header: compatto su mobile */
@media (max-width: 640px) {

    /* Header profilo: riduce avatar e testo */
    .profile-header-avatar {
        width: 4rem !important;
        height: 4rem !important;
    }

    /* Main content: padding ridotto */
    main {
        padding: 0.75rem !important;
    }

    /* H1 profilo */
    h1.text-4xl {
        font-size: 1.5rem !important;
    }

    /* Griglia statistiche: mantieni 3 colonne ma riduci padding */
    .grid.grid-cols-3>div {
        padding: 0.75rem !important;
    }

    .grid.grid-cols-3 .text-4xl {
        font-size: 1.5rem !important;
    }

    /* Card partite: font più piccolo */
    .match-row-name {
        font-size: 0.7rem !important;
    }

    /* Tabelle classifiche: font ridotto */
    table {
        font-size: 0.75rem;
    }

    table th,
    table td {
        padding: 0.4rem 0.5rem !important;
    }

    /* Form setup wizard: padding ridotto */
    .bg-slate-900.rounded-xl {
        padding: 1rem !important;
    }

    /* Nasconde elementi decorativi pesanti su mobile */
    .sport-bg-glow {
        box-shadow: none !important;
    }
}

/* header profilo su mobile: layout colonna invece che riga */
@media (max-width: 480px) {

    /* Profilo: stack verticale su schermi molto piccoli */
    .flex.items-start.gap-6.mb-8 {
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 1rem;
    }

    .flex.items-start.gap-6.mb-8 .flex-1 {
        width: 100%;
    }

    /* Avatar circolare: dimensione fissa piccola */
    .w-32.h-32 {
        width: 5rem !important;
        height: 5rem !important;
        font-size: 1.5rem !important;
    }
}

/* PREMIUM ADDITIONS */
.glass-premium {
    background: linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0) 100%);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid rgba(255,255,255,0.1);
    box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
}

.timeline-line {
    position: absolute;
    left: 20px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: linear-gradient(to bottom, transparent, rgba(255,255,255,0.1), transparent);
}

@keyframes pulse-soft {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.7; transform: scale(0.95); }
}

.animate-pulse-soft {
    animation: pulse-soft 2s infinite ease-in-out;
}

.text-glow {
    text-shadow: 0 0 15px currentColor;
}

.hover-lift {
    transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
}

.hover-lift:hover {
    transform: translateY(-4px);
    box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3);
}

/* ================================
   Relocated from base.html inline <style> (17.2 consolidation).
   --sport-color resta inline in base.html (Django-rendered per-sport).
   ================================ */
.sport-text { color: var(--sport-color); }

.sport-bg-glow {
    background-color: var(--sport-color);
    box-shadow: 0 0 25px var(--sport-color);
}

/* Nav hover underline */
.nav-link-premium {
    position: relative;
    transition: all 0.3s ease;
}
.nav-link-premium::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 0;
    width: 0;
    height: 2px;
    background: var(--sport-color);
    transition: width 0.3s ease;
}
.nav-link-premium:hover::after {
    width: 100%;
}

/* Mobile fixes (moved from base.html inline) */
@media (max-width: 768px) {
    html { font-size: 14px; }
    .container { padding-left: 1rem; padding-right: 1rem; }
    h1 { font-size: 1.5rem !important; }
    .p-8 { padding: 1.5rem !important; }
}

/* ================================
   Tema chiaro: contrasto nav header/sidebar (17.5).
   I link nav usano utility Tailwind pensate per fondo scuro
   (text-slate-400 / hover:text-white / text-blue-400): su fondo chiaro
   diventano illeggibili (il bianco sparisce, il ciano-400 ha ~1.5:1).
   Qui le rimappo SOLO nel tema chiaro, scopate a header/aside per non
   toccare bottoni accent (es. "Accedi" bianco su gradiente ciano).
   Le specificità (>= 0,2,x) battono le utility (0,1,0) senza !important.
   Il dark resta intatto. */

/* Header top-nav */
[data-theme="light"] header .nav-link-premium {
    color: #475569;                 /* slate-600, ~7:1 su fondo chiaro */
}
[data-theme="light"] header .nav-link-premium:hover {
    color: #0f172a;                 /* slate-900 invece di white */
}
[data-theme="light"] header .nav-link-premium.text-blue-400 {
    color: #1d4ed8;                 /* 17.F2: blue-700, accent AA su chiaro (era ciano #0e7490) */
}

/* Sidebar nav: link attivi (ciano) e nomi squadra (text-white -> scuro).
   Limitato a `aside nav` per escludere il bottone "Accedi" (fuori da nav). */
[data-theme="light"] aside nav .text-blue-400 {
    color: #1d4ed8;                 /* 17.F2: blue-700 (era ciano #0e7490) */
}
[data-theme="light"] aside nav .text-white {
    color: #0f172a;
}

/* ================================
   Tema chiaro: leggibilità testo del contenuto <main> (17.6).
   Stesso meccanismo della nav (17.5) ma esteso al contenuto: i titoli,
   i nomi squadra, i punteggi, le label del date picker e gli empty-state
   usano utility Tailwind tarate sul fondo scuro (text-white, text-slate-400):
   sul tema chiaro spariscono (bianco-su-chiaro, slate-400 ~2,3:1).
   Qui, SOLO nel chiaro e SOLO dentro <main>, rimappo il testo bianco/muted
   sui token chiari (--text-main / --text-muted). Poi ri-affermo il testo
   chiaro dove l'elemento ha un fondo PIENO accent o scuro (bottoni, badge,
   pill scure): nel chiaro restano colorati/scuri e vogliono testo bianco.
   Il dark resta intatto (tutto scopato a [data-theme="light"]).
   Specificità: base (0,2,1) batte le utility (0,1,0); la ri-afferma
   (0,3,1) batte la base — vince a prescindere dall'ordine, senza !important. */
[data-theme="light"] main .text-white,
[data-theme="light"] main .text-slate-100,
[data-theme="light"] main .text-slate-200 {
    color: var(--text-main);          /* "quasi bianco" usato come testo primario */
}
[data-theme="light"] main .text-slate-300,
[data-theme="light"] main .text-slate-400,
[data-theme="light"] main .text-gray-300,
[data-theme="light"] main .text-gray-400 {
    color: var(--text-muted);         /* muted: tutta la fascia slate/gray chiara */
}

/* Ri-afferma testo bianco sui fondi PIENI accent/scuri (bottoni, badge, pill).
   I fondi traslucidi (bg-white/5, bg-blue-500/10) NON sono qui di proposito:
   nel chiaro restano chiari, quindi il testo va scuro (es. giorno selezionato
   del date picker, bg-white/5). I fondi slate scuri pieni (7/8/9) sì. */
[data-theme="light"] main .text-white[class*="bg-blue-"],
[data-theme="light"] main .text-white[class*="bg-indigo-"],
[data-theme="light"] main .text-white[class*="bg-sky-"],
[data-theme="light"] main .text-white[class*="bg-green-"],
[data-theme="light"] main .text-white[class*="bg-emerald-"],
[data-theme="light"] main .text-white[class*="bg-teal-"],
[data-theme="light"] main .text-white[class*="bg-red-"],
[data-theme="light"] main .text-white[class*="bg-rose-"],
[data-theme="light"] main .text-white[class*="bg-purple-"],
[data-theme="light"] main .text-white[class*="bg-violet-"],
[data-theme="light"] main .text-white[class*="bg-pink-"],
[data-theme="light"] main .text-white[class*="bg-amber-"],
[data-theme="light"] main .text-white[class*="bg-orange-"],
[data-theme="light"] main .text-white[class~="bg-slate-700"],
[data-theme="light"] main .text-white[class~="bg-slate-800"],
[data-theme="light"] main .text-white[class~="bg-slate-900"],
[data-theme="light"] main .text-white[class~="bg-slate-950"],
[data-theme="light"] main .text-white[class*="bg-gradient"] {
    color: #fff;
}

/* Testo muted sullo STESSO elemento di una pill scura piena (es. filtri
   report_queue bg-slate-800; messaggi bg-slate-800 text-slate-200): nel chiaro
   la pill resta scura, quindi il testo resta chiaro.
   17.8: `*=` -> `~=` (token pieno). Prima `[class*="bg-slate-9"]` catturava anche
   i `<select>` glass `bg-slate-900/50` (traslucidi = grigio medio nel chiaro),
   tenendo il testo chiaro su fondo medio = contrasto scarso. Con `~=` i fondi
   /50 cadono nel remap base (testo scuro su glass chiaro, leggibile). */
[data-theme="light"] main .text-slate-200[class~="bg-slate-700"],
[data-theme="light"] main .text-slate-200[class~="bg-slate-800"],
[data-theme="light"] main .text-slate-200[class~="bg-slate-900"],
[data-theme="light"] main .text-slate-200[class~="bg-slate-950"],
[data-theme="light"] main .text-slate-300[class~="bg-slate-700"],
[data-theme="light"] main .text-slate-300[class~="bg-slate-800"],
[data-theme="light"] main .text-slate-300[class~="bg-slate-900"],
[data-theme="light"] main .text-slate-300[class~="bg-slate-950"],
[data-theme="light"] main .text-slate-400[class~="bg-slate-700"],
[data-theme="light"] main .text-slate-400[class~="bg-slate-800"],
[data-theme="light"] main .text-slate-400[class~="bg-slate-900"],
[data-theme="light"] main .text-slate-400[class~="bg-slate-950"] {
    color: #94a3b8;
}

/* ================================
   Tema chiaro: ISOLE SCURE dentro il contenuto (17.7).
   Alcune superfici restano scure ANCHE nel tema chiaro per design (hero card,
   alcune card a fondo slate pieno). Lì la rimappatura del testo sopra renderebbe
   il testo scuro su fondo scuro = illeggibile. Qui ri-affermo il testo chiaro
   per i discendenti (e per gli elementi stessi) di queste isole. Due famiglie:
   - `.dark-surface`: marker esplicito sulle hero card, dove il fondo scuro è un
     <div> gradient figlio assoluto (from-slate-950) e NON una classe bg sul
     contenitore del testo: serve un hook esplicito.
   - `[class~="bg-slate-700|800|900|950"]`: card a fondo slate scuro PIENO. Il
     selettore `~=` matcha SOLO il token esatto, così esclude i fondi traslucidi
     dei glass-panel (bg-slate-900/50, /30) che nel chiaro restano chiari e che
     NON vanno ri-scuriti (pagine già verdi: Risultati, sport, classifiche).
   Il dark resta intatto (tutto scopato a [data-theme="light"]). */
[data-theme="light"] main .dark-surface .text-white,
[data-theme="light"] main .dark-surface.text-white,
[data-theme="light"] main [class~="bg-slate-700"] .text-white,
[data-theme="light"] main [class~="bg-slate-800"] .text-white,
[data-theme="light"] main [class~="bg-slate-900"] .text-white,
[data-theme="light"] main [class~="bg-slate-950"] .text-white {
    color: #fff;
}
[data-theme="light"] main .dark-surface .text-slate-100,
[data-theme="light"] main .dark-surface .text-slate-200,
[data-theme="light"] main .dark-surface .text-slate-300,
[data-theme="light"] main .dark-surface .text-slate-400,
[data-theme="light"] main .dark-surface .text-gray-300,
[data-theme="light"] main .dark-surface .text-gray-400,
[data-theme="light"] main [class~="bg-slate-700"] .text-slate-100,
[data-theme="light"] main [class~="bg-slate-700"] .text-slate-200,
[data-theme="light"] main [class~="bg-slate-700"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-700"] .text-slate-400,
[data-theme="light"] main [class~="bg-slate-800"] .text-slate-100,
[data-theme="light"] main [class~="bg-slate-800"] .text-slate-200,
[data-theme="light"] main [class~="bg-slate-800"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-800"] .text-slate-400,
[data-theme="light"] main [class~="bg-slate-900"] .text-slate-100,
[data-theme="light"] main [class~="bg-slate-900"] .text-slate-200,
[data-theme="light"] main [class~="bg-slate-900"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-900"] .text-slate-400,
[data-theme="light"] main [class~="bg-slate-950"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-950"] .text-slate-400 {
    color: #94a3b8;                   /* muted chiaro come nel dark */
}

/* ================================================================
   TEMA CHIARO 17.8 — chiusura CATEGORIALE della leggibilità.
   Tre mosse strutturali che sostituiscono i fix reattivi per-pagina.
   Tutto scopato a [data-theme="light"]: il dark resta identico.
   ================================================================ */

/* (c) BLANKET CONTAINER-KEYED sulle isole scure.
   Le regole isola di 17.7 ri-chiarivano SOLO il testo con una classe colore
   esplicita (text-white/text-slate-*). Il testo SENZA classe colore eredita
   `color` dal body, che nel chiaro è scuro: scuro-su-scuro dentro le isole
   (nomi rosa/staff team_detail, valori card profilo/athlete_profile, righe
   evento match_detail, card utente bacheca). Qui do un color chiaro all'ISOLA
   stessa: ogni discendente non taggato eredita chiaro; i figli taggati
   (accent/#fff/muted) restano governati dalle regole più specifiche sopra.
   `~=` matcha solo il token pieno -> i glass /50,/30 restano esclusi (nel
   chiaro sono superfici chiare e NON vanno scurite). */
[data-theme="light"] main .dark-surface,
[data-theme="light"] main [class~="bg-slate-700"],
[data-theme="light"] main [class~="bg-slate-800"],
[data-theme="light"] main [class~="bg-slate-900"],
[data-theme="light"] main [class~="bg-slate-950"] {
    color: #f1f5f9;                   /* = testo primario del dark, isola coerente */
}

/* RISCHIO #1 della mossa (c), gestito ESPLICITAMENTE: una superficie chiara
   PIENA (bg-white, bg-*-50/100/200) annidata in un'isola scura erediterebbe il
   testo chiaro del blanket -> chiaro-su-chiaro (es. chip sponsor bg-white in
   society_detail dentro card bg-slate-900). In tema chiaro una superficie chiara
   piena vuole SEMPRE testo scuro, ovunque sia: lo ri-affermo per categoria.
   Stessa specificità del blanket, vince per source-order (viene dopo). I figli
   con classe scura esplicita (text-slate-900/text-black) restano scuri.
   `~=` (non `*=`) per non centrare bg-slate-500 etc. con un substring. */
[data-theme="light"] main [class~="bg-white"],
[data-theme="light"] main [class~="bg-slate-50"],
[data-theme="light"] main [class~="bg-slate-100"],
[data-theme="light"] main [class~="bg-slate-200"],
[data-theme="light"] main [class~="bg-gray-50"],
[data-theme="light"] main [class~="bg-gray-100"],
[data-theme="light"] main [class~="bg-gray-200"],
[data-theme="light"] main [class~="bg-indigo-50"],
[data-theme="light"] main [class~="bg-blue-100"],
[data-theme="light"] main [class~="bg-green-100"],
[data-theme="light"] main [class~="bg-amber-100"],
[data-theme="light"] main [class~="bg-orange-100"],
[data-theme="light"] main [class~="bg-yellow-100"] {
    color: var(--text-main);
}

/* (hover) REMAP PER-SUPERFICIE — sostituisce lo scope troppo stretto .date-strip
   di 17.7. Default: nel chiaro, dentro main, l'hover/group-hover che porterebbe
   il testo a bianco lo porta a scuro (superfici chiare: teaser/dettaglio home,
   nav sport, bacheca, label, calendario date-strip). */
[data-theme="light"] main .hover\:text-white:hover,
[data-theme="light"] main .group:hover .group-hover\:text-white {
    color: var(--text-main);
}

/* ECCEZIONE all'hover: il bianco va PRESERVATO dove l'hover poggia su un'isola
   scura (pill report_queue bg-slate-800; badge rosa match_detail che sono già
   bg-slate-800) o diventa un fondo ACCENT pieno (icona-azione athlete_profile
   hover:bg-blue-600; badge rosa che all'hover diventano blu/purple-500).
   Specificità maggiore del default -> vince. */
[data-theme="light"] main .dark-surface .hover\:text-white:hover,
[data-theme="light"] main [class~="bg-slate-700"].hover\:text-white:hover,
[data-theme="light"] main [class~="bg-slate-800"].hover\:text-white:hover,
[data-theme="light"] main [class~="bg-slate-900"].hover\:text-white:hover,
[data-theme="light"] main [class~="bg-slate-950"].hover\:text-white:hover,
[data-theme="light"] main [class~="bg-slate-700"] .hover\:text-white:hover,
[data-theme="light"] main [class~="bg-slate-800"] .hover\:text-white:hover,
[data-theme="light"] main [class~="bg-slate-900"] .hover\:text-white:hover,
[data-theme="light"] main [class~="bg-slate-950"] .hover\:text-white:hover,
[data-theme="light"] main .hover\:bg-blue-500.hover\:text-white:hover,
[data-theme="light"] main .hover\:bg-blue-600.hover\:text-white:hover,
[data-theme="light"] main .hover\:bg-indigo-600.hover\:text-white:hover,
[data-theme="light"] main .hover\:bg-emerald-600.hover\:text-white:hover,
[data-theme="light"] main .hover\:bg-green-600.hover\:text-white:hover,
[data-theme="light"] main .hover\:bg-purple-600.hover\:text-white:hover,
[data-theme="light"] main [class~="bg-slate-700"] .group:hover .group-hover\:text-white,
[data-theme="light"] main [class~="bg-slate-800"] .group:hover .group-hover\:text-white,
[data-theme="light"] main [class~="bg-slate-900"] .group:hover .group-hover\:text-white,
[data-theme="light"] main [class~="bg-slate-950"] .group:hover .group-hover\:text-white,
[data-theme="light"] main .dark-surface .group:hover .group-hover\:text-white,
[data-theme="light"] main .group:hover .group-hover\:text-white[class~="bg-slate-700"],
[data-theme="light"] main .group:hover .group-hover\:text-white[class~="bg-slate-800"],
[data-theme="light"] main .group:hover .group-hover\:text-white[class~="bg-slate-900"],
[data-theme="light"] main .group:hover .group-hover\:text-white[class~="bg-slate-950"],
[data-theme="light"] main .group:hover .group-hover\:bg-blue-500.group-hover\:text-white,
[data-theme="light"] main .group:hover .group-hover\:bg-purple-500.group-hover\:text-white {
    color: #fff;
}

/* Input di ricerca della navbar/sidebar: vivono in <header>/<aside>, FUORI da
   main, quindi il remap di main non li tocca. Nel chiaro hanno text-white su
   bg-white/5 (chiaro) = chiaro-su-chiaro: il testo digitato spariva. Scuro qui. */
[data-theme="light"] header input[type="text"],
[data-theme="light"] aside input[type="text"] {
    color: var(--text-main);
}

/* ================================================================
   TEMA CHIARO 17.8.1 — <select> glass bg-slate-900/50 (fix mirato).
   Correzione di diagnosi rispetto a 17.8: bg-slate-900/50 NON e' una superficie
   chiara nel tema chiaro (slate-900 al 50% su fondo chiaro = grigio-scuro). Sul
   <select> il rendering nativo lo lascia scuro, e il remap base 17.8 vi forzava
   testo scuro -> scuro-su-scuro illeggibile (confermato a browser: select
   "Stagione" sport_matches/sport_detail, "team"/"role" generate_code).
   Qui, SOLO sui <select> col token ESATTO bg-slate-900/50 (i 4 select), forzo
   una superficie chiara coerente coi glass-panel vicini + testo scuro = alto
   contrasto pieno (niente grigio-medio ambiguo). Il selettore richiede `select`:
   i <div> glass con la stessa classe (profile, report_review, team_detail,
   sport_detail, grouped_match_list) restano intatti = verdi. color-scheme:light
   e' best-effort per rendere chiaro anche il menu nativo aperto.
   Additivo: non riapre nessuna regola categoriale gia' verde. */
[data-theme="light"] main select[class~="bg-slate-900/50"] {
    background-color: var(--glass-bg);   /* superficie chiara, come i glass vicini */
    color: var(--text-main);             /* testo scuro, alto contrasto */
    color-scheme: light;                 /* best-effort sul menu nativo aperto */
}

/* ================================================================
   ACCESSIBILITA' 17.7 — focus visibile da tastiera (keyboard-only).
   :focus-visible scatta solo per navigazione da tastiera, non al click del
   mouse: gli utenti tastiera ottengono sempre un anello di focus netto, anche
   sugli elementi con Tailwind focus:outline-none (input ricerca, theme-toggle,
   <select> stagione, bottoni). Il mouse resta pulito (nessun anello).
   !important per vincere sul reset outline che il runtime Tailwind CDN inietta.
   ================================================================ */
:focus-visible {
    outline: 2px solid var(--sport-color, #2563eb) !important;
    outline-offset: 2px !important;
}
/* Sopprimi l'outline solo quando NON e' focus da tastiera (mouse/touch),
   cosi' il look pulito del design resta intatto al click. */
:focus:not(:focus-visible) {
    outline: none;
}
/* FIX prodotto (2026-06-23): i campi di testo (input testuali, textarea, select,
   inclusi i campi crispy di login/signup) mostrano l'anello di focus su :focus —
   sia da tastiera SIA al click — perche' per un campo di testo e' il comportamento
   nativo atteso (WCAG 2.4.7) e coerente con gli input che gia' usano focus:ring
   inline. Uso un box-shadow ciano (lo stesso "anello" dei ring inline): la maggiore
   specificita' del selettore sovrascrive quei ring -> un solo anello, niente
   doubling. Azzero l'outline con !important cosi' i text field NON mostrano qui
   l'outline keyboard-only della regola globale (i text field matchano :focus-visible
   anche al mouse). Bottoni, link, toggle, checkbox e radio NON sono toccati: restano
   :focus-visible keyboard-only (anello solo da tastiera, mai al click). */
input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus,
input[type="number"]:focus,
input[type="search"]:focus,
input[type="tel"]:focus,
input[type="url"]:focus,
input[type="date"]:focus,
input:not([type]):focus,
textarea:focus,
select:focus {
    outline: none !important;
    box-shadow: 0 0 0 2px var(--sport-color, #2563eb);
}
/* ── LA LAVAGNA DI FIRMA A PIENO SCHERMO (§10.301) ─────────────────────────
   Vestita QUI e non in Tailwind di proposito: `tailwind.build.css` e' un
   artefatto committato che si ricompila in stazione (OPS_RUNBOOK §18.2), e una
   classe nuova aggiunta da una corsia resta un'intenzione senza stile fino al
   merge — con l'aspetto di prima, che e' il modo esatto in cui questa stessa
   superficie e' gia' caduta tre volte (§10.214/§10.235/§10.236). `style.css`
   non lo compila nessuno: quello che c'e' scritto e' quello che arriva.
   Caricato DOPO il build (base.html), quindi vince la cascata a parita' di
   specificita'; i selettori qui sotto ne hanno comunque di piu' (attributo +
   classe = 0,2,0 contro lo 0,1,0 di una utility).

   Chi mette e toglie la classe: static/js/firma_lavagna.js.

   DUE SUPERFICI, UNA VESTE SOLA (§10.330). Il tavolo del referto marca i suoi
   elementi `data-firma-canvas-*`, la distinta del capitano `data-signature-*`:
   i due vocabolari restano quelli delle rispettive pagine — rinominarne uno
   toccherebbe test che ne asseriscono il reso — e qui si aggiungono come
   selettori alla STESSA regola invece di copiarne le dichiarazioni. Una veste
   duplicata sarebbe una veste da riparare due volte, ed e' esattamente il
   difetto che §10.330 ha chiuso sul modulo JavaScript. */
[data-firma-canvas-blocco].lavagna-piena,
[data-signature-canvas-blocco].lavagna-piena {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 100;
    margin: 0;
    display: flex;
    flex-direction: column;
    /* Le tacche del telefono e la barra dei gesti non devono mangiare ne' il
       bordo della tela ne' i comandi: `env()` vale 0 dove non c'e' notch. */
    padding: calc(0.75rem + env(safe-area-inset-top)) calc(0.75rem + env(safe-area-inset-right))
             calc(0.75rem + env(safe-area-inset-bottom)) calc(0.75rem + env(safe-area-inset-left));
    background: #0b1220;
}

/* LA TELA PRENDE TUTTO LO SPAZIO CHE AVANZA. `height: 100%` e' la base flex;
   `min-height: 0` e' cio' che permette di scendere sotto il contenuto quando i
   comandi chiedono il loro posto — senza, in colonna il canvas non si
   restringe e la barra dei comandi finisce fuori dallo schermo, cioe' proprio
   la meta' della condizione di chiusura che parla dei comandi raggiungibili. */
[data-firma-canvas-blocco].lavagna-piena [data-firma-canvas],
[data-signature-canvas-blocco].lavagna-piena [data-signature-canvas] {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    height: 100%;
    border-radius: 0.5rem;
}

/* I COMANDI NON SI RESTRINGONO MAI: `flex: 0 0 auto` e' la garanzia che
   Chiudi / Cancella / Firma restino raggiungibili senza uscire dal pieno
   schermo. Sono la ragione per cui il pannello e' una colonna flex e non un
   canvas a tutto schermo. */
[data-firma-canvas-blocco].lavagna-piena [data-firma-canvas-comandi],
[data-signature-canvas-blocco].lavagna-piena [data-signature-canvas-comandi] {
    flex: 0 0 auto;
    margin-top: 0.75rem;
}

/* BERSAGLI DA DITO BAGNATO, non da mouse: a bordo vasca si tocca con una mano
   sola e con lo schermo umido. In linea i tre comandi erano righe da pochi
   millimetri; a pieno schermo lo spazio c'e' e va usato. */
[data-firma-canvas-blocco].lavagna-piena [data-firma-canvas-comandi] > button,
[data-signature-canvas-blocco].lavagna-piena [data-signature-canvas-comandi] > button {
    min-height: 3rem;
}

/* «Firma sulla lavagna» e' l'etichetta piu' lunga delle tre E l'atto che
   conta: con tre pulsanti a `flex-1` in verticale su un telefono andrebbe a
   capo proprio il comando che si cerca. Prende doppio spazio. */
[data-firma-canvas-blocco].lavagna-piena [data-firma-canvas-conferma],
[data-signature-canvas-blocco].lavagna-piena [data-signature-submit] {
    flex: 2 1 0%;
}

/* La riga «di chi e' questa firma»: in pieno schermo la scheda intorno non si
   vede piu', e al tavolo firmano in tre. */
[data-firma-canvas-blocco].lavagna-piena [data-firma-canvas-titolo],
[data-signature-canvas-blocco].lavagna-piena [data-signature-canvas-titolo] {
    flex: 0 0 auto;
    margin-bottom: 0.5rem;
}

/* Il documento sotto non scorre mentre si firma: il dito che esce dai bordi
   della tela trascinerebbe la pagina invece di finire il tratto — stessa
   classe di difetto del `touch-none` sul canvas (§10.235). */
html.lavagna-aperta,
html.lavagna-aperta body {
    overflow: hidden;
    overscroll-behavior: none;
}

/* L'AVVISO DI ORIENTAMENTO (§10.382). Il nodo lo crea `firma_lavagna.js` —
   una volta sola, per tutte e due le lavagne — e la veste sta qui per la
   stessa ragione di tutto il blocco: `tailwind.build.css` e' un artefatto
   committato che si ricompila in stazione, e una classe nuova nata in una
   corsia resterebbe un'intenzione senza stile fino al merge. `style.css` non
   lo compila nessuno.

   FUORI DAL PIENO SCHERMO NON SI VEDE: senza questa regola l'avviso
   comparirebbe anche nella lavagna in linea (la degradazione di quando il
   modulo non c'e'), dove non c'e' niente da orientare e sarebbe solo una
   riga in piu' in una scheda gia' stretta.

   `flex: 0 0 auto` come il titolo e i comandi: il pannello e' una colonna
   flex, e senza questo l'avviso si lascerebbe schiacciare dalla tela fino a
   diventare illeggibile invece di prendersi la sua riga.

   COLORE FISSO E NON UN TOKEN DI TEMA: il fondo del pieno schermo e' `#0b1220`
   dichiarato qui sopra, sempre, in tema chiaro come in tema scuro. Un colore
   di testo che seguisse il tema qui diventerebbe scuro-su-scuro nel tema
   chiaro — che e' esattamente la classe di §10.350. `#fbbf24` su `#0b1220` da'
   un rapporto di contrasto di circa 10,4:1, ampiamente sopra il 4.5:1 AA. */
[data-lavagna-avviso] {
    display: none;
}

[data-firma-canvas-blocco].lavagna-piena [data-lavagna-avviso],
[data-signature-canvas-blocco].lavagna-piena [data-lavagna-avviso] {
    display: block;
    flex: 0 0 auto;
    margin-bottom: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.3;
    text-align: center;
    color: #fbbf24;
}

/* `hidden` VINCE, ed e' il motivo per cui questa regola esiste: il modulo
   spegne l'avviso al primo tratto aggiungendo `hidden`, e la regola qui sopra
   — piu' specifica di un attributo solo — lo rimetterebbe a `display: block`
   annullando lo spegnimento. Con la stessa specificita' della regola che deve
   battere, piu' l'ordine, il conto torna. */
[data-firma-canvas-blocco].lavagna-piena [data-lavagna-avviso].hidden,
[data-signature-canvas-blocco].lavagna-piena [data-lavagna-avviso].hidden {
    display: none;
}

/* ================================================================
   TEMA CHIARO 18 — CHIUSURA DI CONTRASTO WCAG (§10.268, §10.269)
   ================================================================
   BLOCCO CONTIGUO E AUTOSUFFICIENTE: tutto cio' che questo giro tocca sta qui
   sotto, dall'intestazione alla fine del file, e non modifica una sola riga
   scritta sopra. E' voluto: la corsia lavora in parallelo ad altre che possono
   toccare lo stesso file, e un blocco in coda si UNISCE al merge invece di
   costringere a scegliere fra due versioni della stessa riga.

   CHE COSA MISURA QUESTO BLOCCO. Non l'estetica: il rapporto di contrasto WCAG
   2.1 AA fra il colore COMPOSITO del testo e quello del suo fondo — 4.5:1 per
   il testo normale, 3:1 per il testo grande. Il righello e' `core/contrast_wcag.py`
   e il presidio che lo riesegue e' `core/tests_contrasto_tema_chiaro.py`: senza
   quello, la voce si riapre alla prima regola nuova.

   LA CAUSA, misurata e non stimata. Il tema chiaro non e' un tema: e' il tema
   scuro con alcune famiglie di token ri-mappate (17.5→17.8.1). Le famiglie mai
   ri-mappate sono due, e insieme spiegano tutti i 775 elementi sotto soglia:

     (1) gli ACCENTI `text-<tinta>-200…600` — giallo, blu, rosso, smeraldo,
         ambra, viola — scelti per staccare su un fondo NERO. Sul fondo chiaro
         non staccano: «Admin Management» stava a 1.36, «Mio Spazio» a 1.80.
         Sono 626 elementi su 775.
     (2) le ISOLE SCURE TRASLUCIDE: `bg-slate-900/60`, `/80`, `/90`,
         `bg-slate-800/50`, `bg-gray-700`, `bg-[#0B0F19]`. La lista di isole di
         17.7/17.8 conosce solo i token PIENI (`~="bg-slate-900"`), quindi su
         queste il remap del chiaro scuriva il testo su un fondo che resta
         scuro: scuro-su-scuro. Sono i restanti 149.

   PERCHE' I COLORI E NON LA STRUTTURA. Nessun selettore qui sotto cambia un
   layout, una semantica o una classe nel markup: cambiano SOLO valori di
   `color` e `background-color`, e solo dentro `[data-theme="light"]`. Il tema
   scuro non puo' regredire per costruzione — nessuna di queste regole lo
   matcha — e infatti il righello lo misura invariato prima e dopo.

   PERCHE' QUI E NON IN TAILWIND. `tailwind.build.css` e' un artefatto
   committato che si ricompila in stazione (OPS_RUNBOOK §18.2): una classe
   nuova aggiunta da una corsia resterebbe un'intenzione senza stile fino al
   merge, con l'aspetto di prima — il modo esatto in cui questa stessa
   superficie e' gia' caduta in §10.214/§10.235/§10.236. `style.css` non lo
   compila nessuno: quello che c'e' scritto e' quello che arriva.
   ================================================================ */

/* ── (1a) I GRIGI DI MEZZO: superfici, non testo ───────────────────────────
   Questi token nascono come «nero al 20-60%» su una pagina NERA, dove sono un
   velo appena percettibile. Sulla pagina CHIARA la stessa opacita' compone un
   grigio medio — `bg-slate-900/60` rende rgb(104,111,124) — e un grigio medio
   e' la sola superficie su cui NON esiste un colore di testo che passi:
   misurato, il bianco arriva a 5,07 ma il nero si ferma a 3,52, e appena si
   scende a /50 non passa piu' nessuno dei due (3,73 e 4,78 con soglia 4,5).

   Quindi qui non si sceglie un testo: si sposta la SUPERFICIE. Diventa un velo
   scuro sul chiaro invece che un velo chiaro sul buio — stessa idea di disegno
   («una pastiglia un po' piu' marcata del fondo»), ribaltata come il tema.
   E' la decisione che 17.8.1 aveva gia' preso per i soli `<select>` /50, con la
   stessa motivazione testuale: «niente grigio-medio ambiguo». Qui vale per
   categoria invece che per un selettore.

   Il testo sopra e' gia' governato dal remap di 17.6/17.8 (scuro su chiaro):
   con la superficie chiara arriva a 12-15:1 senza altre regole. */
[data-theme="light"] [class~="bg-black/20"],
[data-theme="light"] [class~="bg-black/30"],
[data-theme="light"] [class~="bg-slate-800/30"],
[data-theme="light"] [class~="bg-slate-900/30"],
[data-theme="light"] [class~="bg-slate-600/40"] {
    background-color: rgba(15, 23, 42, 0.05);
}
[data-theme="light"] [class~="bg-slate-800/50"],
[data-theme="light"] [class~="bg-slate-900/50"],
[data-theme="light"] [class~="bg-slate-900/60"] {
    background-color: rgba(15, 23, 42, 0.08);
}

/* ECCEZIONE alla (1a): dentro un'isola davvero scura questi stessi veli sono
   corretti come sono (scuro su scuro), e schiarirli farebbe una toppa chiara
   in mezzo al nero. Si ripristina il velo originale, con la specificita' che
   vince. Stessa logica del «RISCHIO #1» gestito in 17.8. */
[data-theme="light"] .dark-surface [class~="bg-black/20"],
[data-theme="light"] .dark-surface [class~="bg-black/30"],
[data-theme="light"] .dark-surface [class~="bg-slate-800/30"],
[data-theme="light"] .dark-surface [class~="bg-slate-900/30"],
[data-theme="light"] .dark-surface [class~="bg-slate-800/50"],
[data-theme="light"] .dark-surface [class~="bg-slate-900/50"],
[data-theme="light"] .dark-surface [class~="bg-slate-900/60"],
[data-theme="light"] [class~="bg-slate-950"] [class~="bg-black/20"],
[data-theme="light"] [class~="bg-slate-900"] [class~="bg-black/20"],
[data-theme="light"] [class~="bg-slate-900"] [class~="bg-slate-800/30"],
[data-theme="light"] [class~="bg-slate-800"] [class~="bg-black/20"] {
    background-color: rgba(0, 0, 0, 0.2);
}

/* ── (1b) ISOLE SCURE: completamento della lista ───────────────────────────
   Stesse tre forme di regola di 17.7/17.8 (blanket sull'isola, `.text-white`
   ai discendenti, `.text-slate-*` in muted), per i token che sul fondo chiaro
   compongono una superficie DAVVERO scura e non un grigio ambiguo: /80 rende
   rgb(60,67,83), /90 rende rgb(37,45,62), `bg-[#0B0F19]` rende rgb(11,15,25).
   Li' il testo chiaro passa largamente e quello scuro no: l'intento del
   disegno e' una barra scura, e si rispetta invece di ribaltarlo. */
[data-theme="light"] main [class~="bg-slate-900/80"],
[data-theme="light"] main [class~="bg-slate-900/90"],
[data-theme="light"] main [class~="bg-gray-700"],
[data-theme="light"] main [class~="bg-[#0B0F19]"] {
    color: #f1f5f9;
}
[data-theme="light"] main [class~="bg-slate-900/80"] .text-white,
[data-theme="light"] main [class~="bg-slate-900/90"] .text-white,
[data-theme="light"] main [class~="bg-gray-700"] .text-white,
[data-theme="light"] main [class~="bg-[#0B0F19]"] .text-white,
[data-theme="light"] main [class~="bg-slate-900/80"].text-white,
[data-theme="light"] main [class~="bg-slate-900/90"].text-white {
    color: #fff;
}
[data-theme="light"] main [class~="bg-slate-900/80"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-900/80"] .text-slate-400,
[data-theme="light"] main [class~="bg-slate-900/80"] .text-slate-500,
[data-theme="light"] main [class~="bg-slate-900/90"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-900/90"] .text-slate-400,
[data-theme="light"] main [class~="bg-slate-900/90"] .text-slate-500,
[data-theme="light"] main [class~="bg-[#0B0F19]"] .text-slate-300,
[data-theme="light"] main [class~="bg-[#0B0F19]"] .text-slate-400,
[data-theme="light"] main [class~="bg-[#0B0F19]"] .text-slate-500 {
    color: #cbd5e1;
}

/* ── (2) FAMIGLIE ACCENTO: la tinta resta, la profondita' cambia ───────────
   Ogni tinta va alla sua variante AA sul chiaro (la -700 di Tailwind, la
   stessa scelta gia' fatta in 17.F2 per il blu della nav). Non e' un cambio di
   colore: e' lo STESSO colore alla profondita' che sul bianco si legge. Le
   varianti con alpha (`/70`, `/80`, `/50`) collassano sul colore pieno: l'alpha
   nasceva per ammorbidire su fondo nero e sul chiaro toglie e basta.
   Fuori da `main` di proposito: «Admin Management» e «Mio Spazio» — i due
   peggiori misurati, 1.36 e 1.80 — vivono nella SIDEBAR, ed e' esattamente il
   motivo per cui nessun giro precedente li aveva presi. */
[data-theme="light"] .text-blue-200,
[data-theme="light"] .text-blue-200\/70,
[data-theme="light"] .text-blue-300,
[data-theme="light"] .text-blue-400,
[data-theme="light"] .text-blue-500,
[data-theme="light"] .text-blue-500\/50,
[data-theme="light"] .text-blue-600 {
    color: var(--c-blue, #1e40af);    /* blue-800 */
}
[data-theme="light"] .text-sky-300,
[data-theme="light"] .text-sky-400 {
    color: var(--c-sky, #0369a1);     /* sky-700 */
}

/* ⚠ §10.602 — NEL TEMA CHIARO L'HOVER DI COLORE NON SI ACCENDE MAI, e non su
   una classe: su QUARANTASEI elementi su sessantaquattro. Misurato col
   righello di `core/contrast_wcag` il 2026-08-23, entrambi i temi, tutti i
   template di pagina: nel tema SCURO 0 hover morti su 64; nel CHIARO 46.

   IL MECCANISMO, letto dalle dichiarazioni che il righello vede in stato
   hover su `templates/accounts/dashboard.html:151`:

     .text-slate-500                       specificità (0,1,0)  ordine     183
     .hover\:text-sky-300:hover             specificità (0,2,0)  ordine     894
     [data-theme="light"] .text-slate-500   specificità (0,2,0)  ordine 1000093

   La terza PAREGGIA la seconda in specificità e la batte per ordine, perché
   questo blocco è caricato dopo il compilato Tailwind. Ogni riga di rimappatura
   qui sopra, quindi, non riscrive solo il colore a riposo: **spegne anche
   l'hover** della stessa famiglia. Non è una parità con la classe base — quella
   sarebbe (0,1,0) e perderebbe — è la parità con la riga di questo file.

   LE TREDICI FAMIGLIE COLPITE, per numero di elementi: blue-400 (15),
   blue-300 (10), slate-300 (3), red-400 (3), slate-200 (3), sky-300 (2),
   emerald-300 (2), rose-300 (2), amber-300 (2), blue-900, purple-400,
   blue-800, purple-300 (1 ciascuna).

   NON SI CHIUDE QUI, e non per prudenza: il rimedio meccanico esiste — un
   selettore `[data-theme="light"] .hover\:text-X:hover`, che a (0,3,0) vince
   su tutto — ma pretende di DECIDERE su quale token d'accento va ognuna delle
   tredici famiglie, e cambia a colpo solo l'aspetto di 46 punti mai visti in
   browser nel tema chiaro. È una decisione di disegno, non una pulizia.

   NON È UN DIFETTO DI CONTRASTO: a riposo quei testi stanno sopra soglia
   (6,44:1 e 6,74:1 sui due della dashboard). Ciò che manca è l'AFFORDANCE —
   il segnale che quella cosa si può premere. Dove c'è anche `hover:underline`
   il segnale sopravvive; dove il colore era l'unico, no. */
[data-theme="light"] .text-indigo-300,
[data-theme="light"] .text-indigo-400,
[data-theme="light"] .text-indigo-600 {
    color: var(--c-indigo, #4338ca);  /* indigo-700 */
}
[data-theme="light"] .text-emerald-200,
[data-theme="light"] .text-emerald-300,
[data-theme="light"] .text-emerald-300\/70,
[data-theme="light"] .text-emerald-400,
[data-theme="light"] .text-emerald-500 {
    color: var(--c-emerald, #065f46); /* emerald-800 */
}
[data-theme="light"] .text-green-400,
[data-theme="light"] .text-green-400\/70,
[data-theme="light"] .text-green-500,
[data-theme="light"] .text-green-600 {
    color: var(--c-green, #166534);   /* green-800 */
}
[data-theme="light"] .text-amber-200,
[data-theme="light"] .text-amber-200\/70,
[data-theme="light"] .text-amber-300,
[data-theme="light"] .text-amber-300\/70,
[data-theme="light"] .text-amber-300\/90,
[data-theme="light"] .text-amber-400,
[data-theme="light"] .text-amber-400\/80,
[data-theme="light"] .text-amber-500,
[data-theme="light"] .text-amber-500\/70,
[data-theme="light"] .text-amber-500\/80,
[data-theme="light"] .text-amber-600,
[data-theme="light"] .text-amber-700 {
    color: var(--c-amber, #92400e);   /* amber-800 */
}
[data-theme="light"] .text-yellow-200,
[data-theme="light"] .text-yellow-400,
[data-theme="light"] .text-yellow-500,
[data-theme="light"] .text-yellow-500\/50,
[data-theme="light"] .text-yellow-500\/80,
[data-theme="light"] .text-yellow-600 {
    color: var(--c-yellow, #854d0e);  /* yellow-800 */
}
[data-theme="light"] .text-orange-400,
[data-theme="light"] .text-orange-500,
[data-theme="light"] .text-orange-600 {
    color: var(--c-orange, #9a3412);  /* orange-800 */
}
[data-theme="light"] .text-red-300,
[data-theme="light"] .text-red-400,
[data-theme="light"] .text-red-400\/70,
[data-theme="light"] .text-red-400\/80,
[data-theme="light"] .text-red-500,
[data-theme="light"] .text-red-600 {
    color: var(--c-red, #991b1b);     /* red-800 */
}
[data-theme="light"] .text-rose-300,
[data-theme="light"] .text-rose-400 {
    color: var(--c-rose, #be123c);    /* rose-700 */
}
[data-theme="light"] .text-purple-300,
[data-theme="light"] .text-purple-400 {
    color: var(--c-purple, #7e22ce);  /* purple-700 */
}

/* Il grigio a meta' strada: `-500` non era in nessuna lista (17.6 si ferma a
   `-400`), ed e' da solo la famiglia piu' numerosa dell'audit — 273 elementi.
   Va al muted del tema, lo stesso token del resto del testo secondario. */
[data-theme="light"] .text-slate-500,
[data-theme="light"] .text-gray-500,
[data-theme="light"] .text-gray-600,
/* `-600` non era in questa lista, e non doveva esserci finche' nessuno lo
   toccava: su fondo chiaro si legge da solo. Ci entra col rimedio di §10.351,
   che nel tema SCURO schiarisce anche lui: senza questa riga quella regola —
   che e' (0,1,0) e nel chiaro non ha niente sopra — schiarirebbe il grigio
   anche qui, e trenta punti del tema chiaro andrebbero sotto soglia. Il VALORE
   e' quello che il chiaro rende gia' oggi: la riga non cambia una pagina, la
   protegge. */
[data-theme="light"] .text-slate-600 {
    color: var(--c-muted, var(--text-muted));
}

/* ── (2b) LE VARIANTI CON ALPHA NON SI ENUMERANO ───────────────────────────
   La (2) qui sopra elenca le varianti con alpha una per una (`\/70`, `\/80`,
   `\/50`). Quell'elenco era esatto quando e' stato scritto e ha smesso di
   esserlo in ventiquattro ore: la corsia che ha aggiunto il messaggio «non hai
   un comitato assegnato» (§10.226) ha portato `text-amber-200/80`, che
   nell'elenco non c'era — e sul fondo ambra chiaro misurava 1.03:1, cioe' un
   testo dello stesso colore del suo fondo. Nessuna delle due corsie aveva
   torto: la seconda ha misurato un albero in cui il banner della prima non
   esisteva ancora. Il difetto e' nato nel confine fra le due.

   E' la stessa obiezione che la (3) fa a se stessa — «nessuno terrebbe
   allineate centinaia di combinazioni» — applicata alle alpha invece che alle
   isole. Qui la variante si prende per FORMA, non per valore: qualunque
   `text-<tinta>-<n>/<qualsiasi>` segue il suo token pieno, che e' esattamente
   l'intento gia' scritto nella (2) («le varianti con alpha collassano sul
   colore pieno»). Una corsia che domani scrive `/60` non riapre niente.

   PERCHE' DUE SELETTORI PER TOKEN E NON `[class*="text-amber-200/"]`. Quella
   forma sola prenderebbe anche `hover:text-amber-200/80`, applicando A RIPOSO
   un colore inteso per il passaggio del mouse. La coppia `^=` (in testa
   all'attributo) + `*=" "` (preceduto da spazio) chiede il confine di parola,
   e la variante prefissata non la matcha. Nel repo di varianti-con-alpha oggi
   non ce n'e' nessuna: la coppia serve a che continui a non esserci un modo
   sbagliato di scriverne una.

   Le righe enumerate della (2) restano dove sono: costano nulla, e documentano
   che cosa l'audit aveva effettivamente trovato. Queste sono la garanzia. */
[data-theme="light"] [class^="text-blue-200/"],
[data-theme="light"] [class*=" text-blue-200/"],
[data-theme="light"] [class^="text-blue-300/"],
[data-theme="light"] [class*=" text-blue-300/"],
[data-theme="light"] [class^="text-blue-400/"],
[data-theme="light"] [class*=" text-blue-400/"],
[data-theme="light"] [class^="text-blue-500/"],
[data-theme="light"] [class*=" text-blue-500/"],
[data-theme="light"] [class^="text-blue-600/"],
[data-theme="light"] [class*=" text-blue-600/"] {
    color: var(--c-blue, #1e40af);             /* blue-800 */
}
[data-theme="light"] [class^="text-sky-300/"],
[data-theme="light"] [class*=" text-sky-300/"],
[data-theme="light"] [class^="text-sky-400/"],
[data-theme="light"] [class*=" text-sky-400/"] {
    color: var(--c-sky, #0369a1);             /* sky-700 */
}
[data-theme="light"] [class^="text-indigo-300/"],
[data-theme="light"] [class*=" text-indigo-300/"],
[data-theme="light"] [class^="text-indigo-600/"],
[data-theme="light"] [class*=" text-indigo-600/"] {
    color: var(--c-indigo, #4338ca);             /* indigo-700 */
}
[data-theme="light"] [class^="text-emerald-200/"],
[data-theme="light"] [class*=" text-emerald-200/"],
[data-theme="light"] [class^="text-emerald-300/"],
[data-theme="light"] [class*=" text-emerald-300/"],
[data-theme="light"] [class^="text-emerald-400/"],
[data-theme="light"] [class*=" text-emerald-400/"],
[data-theme="light"] [class^="text-emerald-500/"],
[data-theme="light"] [class*=" text-emerald-500/"] {
    color: var(--c-emerald, #065f46);             /* emerald-800 */
}
[data-theme="light"] [class^="text-green-400/"],
[data-theme="light"] [class*=" text-green-400/"],
[data-theme="light"] [class^="text-green-500/"],
[data-theme="light"] [class*=" text-green-500/"],
[data-theme="light"] [class^="text-green-600/"],
[data-theme="light"] [class*=" text-green-600/"] {
    color: var(--c-green, #166534);             /* green-800 */
}
[data-theme="light"] [class^="text-amber-200/"],
[data-theme="light"] [class*=" text-amber-200/"],
[data-theme="light"] [class^="text-amber-300/"],
[data-theme="light"] [class*=" text-amber-300/"],
[data-theme="light"] [class^="text-amber-400/"],
[data-theme="light"] [class*=" text-amber-400/"],
[data-theme="light"] [class^="text-amber-500/"],
[data-theme="light"] [class*=" text-amber-500/"],
[data-theme="light"] [class^="text-amber-600/"],
[data-theme="light"] [class*=" text-amber-600/"] {
    color: var(--c-amber, #92400e);             /* amber-800 */
}
[data-theme="light"] [class^="text-yellow-200/"],
[data-theme="light"] [class*=" text-yellow-200/"],
[data-theme="light"] [class^="text-yellow-400/"],
[data-theme="light"] [class*=" text-yellow-400/"],
[data-theme="light"] [class^="text-yellow-500/"],
[data-theme="light"] [class*=" text-yellow-500/"],
[data-theme="light"] [class^="text-yellow-600/"],
[data-theme="light"] [class*=" text-yellow-600/"] {
    color: var(--c-yellow, #854d0e);             /* yellow-800 */
}
[data-theme="light"] [class^="text-orange-400/"],
[data-theme="light"] [class*=" text-orange-400/"],
[data-theme="light"] [class^="text-orange-500/"],
[data-theme="light"] [class*=" text-orange-500/"],
[data-theme="light"] [class^="text-orange-600/"],
[data-theme="light"] [class*=" text-orange-600/"] {
    color: var(--c-orange, #9a3412);             /* orange-800 */
}
[data-theme="light"] [class^="text-red-300/"],
[data-theme="light"] [class*=" text-red-300/"],
[data-theme="light"] [class^="text-red-400/"],
[data-theme="light"] [class*=" text-red-400/"],
[data-theme="light"] [class^="text-red-500/"],
[data-theme="light"] [class*=" text-red-500/"],
[data-theme="light"] [class^="text-red-600/"],
[data-theme="light"] [class*=" text-red-600/"] {
    color: var(--c-red, #991b1b);             /* red-800 */
}
[data-theme="light"] [class^="text-rose-300/"],
[data-theme="light"] [class*=" text-rose-300/"],
[data-theme="light"] [class^="text-rose-400/"],
[data-theme="light"] [class*=" text-rose-400/"] {
    color: var(--c-rose, #be123c);             /* rose-700 */
}
[data-theme="light"] [class^="text-purple-300/"],
[data-theme="light"] [class*=" text-purple-300/"],
[data-theme="light"] [class^="text-purple-400/"],
[data-theme="light"] [class*=" text-purple-400/"] {
    color: var(--c-purple, #7e22ce);             /* purple-700 */
}
[data-theme="light"] [class^="text-slate-500/"],
[data-theme="light"] [class*=" text-slate-500/"],
[data-theme="light"] [class^="text-gray-500/"],
[data-theme="light"] [class*=" text-gray-500/"] {
    color: var(--c-muted, var(--text-muted));
}

/* ── (3) DENTRO LE ISOLE SCURE L'ACCENTO TORNA ACCESO ─────────────────────
   La (2) e' volutamente larga — nessuno scope a `main`, perche' i due elementi
   peggiori della misura stanno nella sidebar. Larga com'e', pero', scurirebbe
   anche gli accenti che vivono DENTRO un'isola scura, dove il colore acceso
   era gia' quello giusto: si chiuderebbe un difetto aprendone un altro.

   La soluzione NON e' una regola per ogni combinazione tinta x isola — sono
   centinaia, e nessuno le terrebbe allineate. Le custom property si
   EREDITANO: qui l'isola dichiara una volta, per tutte le tinte, il valore
   «acceso», e ogni discendente lo raccoglie da solo, a qualunque profondita'.
   Fuori dalle isole la variabile non esiste e la (2) usa il suo fallback.
   Aggiungere un'isola nuova domani vuol dire aggiungere UNA riga qui. */
[data-theme="light"] .dark-surface,
[data-theme="light"] [class~="bg-slate-700"],
[data-theme="light"] [class~="bg-slate-800"],
[data-theme="light"] [class~="bg-slate-900"],
[data-theme="light"] [class~="bg-slate-950"],
[data-theme="light"] [class~="bg-gray-700"],
[data-theme="light"] [class~="bg-gray-800"],
[data-theme="light"] [class~="bg-gray-900"],
[data-theme="light"] [class~="bg-slate-900/80"],
[data-theme="light"] [class~="bg-slate-900/90"],
[data-theme="light"] [class~="bg-[#0B0F19]"] {
    --c-blue: #93c5fd;               /* blue-300 */
    --c-sky: #7dd3fc;                /* sky-300 */
    --c-indigo: #a5b4fc;             /* indigo-300 */
    --c-emerald: #6ee7b7;            /* emerald-300 */
    --c-green: #86efac;              /* green-300 */
    --c-amber: #fcd34d;              /* amber-300 */
    --c-yellow: #fde047;             /* yellow-300 */
    --c-orange: #fdba74;             /* orange-300 */
    --c-red: #fca5a5;                /* red-300 */
    --c-rose: #fda4af;               /* rose-300 */
    --c-purple: #d8b4fe;             /* purple-300 */
    --c-muted: #cbd5e1;              /* slate-300 */
    /* E le due variabili di TESTO del tema. Sono la chiave di volta: ogni
       regola gia' scritta in 17.6/17.8 che legge `var(--text-main)` o
       `var(--text-muted)` — il remap di `.text-white`, quello dei muted, il
       colore degli input — dentro un'isola si ri-schiarisce DA SOLA, senza
       che nessuna di quelle regole venga toccata. */
    --text-main: #f1f5f9;
    --text-muted: #cbd5e1;
}

/* ── (4) §10.269 — LA BARRA DI RICERCA PUBBLICA ────────────────────────────
   Il campo sta nell'header di OGNI pagina pubblica ed e' sul percorso della
   demo. Nel chiaro il fondo `bg-slate-900/60` componeva rgb(104,111,124) e il
   placeholder `slate-500` rgb(100,116,139): rapporto 1.01, cioe' lo stesso
   colore — il campo appariva come un blocco grigio rotto finche' non ci si
   scriveva dentro.

   NON lo si tratta come le isole scure di (1), e la ragione e' nel debito
   stesso: il campo AI gemello, nello stesso header, si adatta correttamente
   (`bg-white/5`, testo scuro). Due input gemelli costruiti con assunzioni
   diverse — quello giusto e' il gemello, e questo lo raggiunge.

   `input[type="search"]`: la regola di 17.8 sugli input di header/aside
   nomina `type="text"`, e questo campo e' `type="search"` — per questo il
   remap non lo aveva mai toccato. */
[data-theme="light"] input[type="search"][class~="bg-slate-900/60"],
[data-theme="light"] header input[type="search"],
[data-theme="light"] aside input[type="search"] {
    background-color: var(--glass-bg);
    color: var(--text-main);
}
[data-theme="light"] input[type="search"][class~="bg-slate-900/60"]::placeholder,
[data-theme="light"] header input[type="search"]::placeholder,
[data-theme="light"] aside input[type="search"]::placeholder {
    color: #475569;                  /* slate-600 su glass chiaro: 6,9:1 */
    opacity: 1;                      /* Firefox lo sbiadisce di suo */
}

/* Nel tema SCURO lo stesso placeholder stava a 3,9:1 — sotto soglia anche li',
   solo meno vistosamente. La condizione di chiusura di §10.269 chiede
   entrambi i temi, quindi si corregge anche il buio. Nessun `[data-theme]`:
   vale ovunque, e la regola del chiaro qui sopra la scavalca per specificita'. */
input[type="search"][class~="bg-slate-900/60"]::placeholder {
    color: #94a3b8;                  /* slate-400 sul fondo scuro: 6,9:1 */
    opacity: 1;
}

/* ── (1c) LE ISOLE SCURE ARRIVANO ANCHE FUORI DA `main` E FINO AL `-500` ───
   Due buchi che l'audit ha trovato nella copertura di 17.7/17.8, entrambi
   invisibili finche' non si misura il perimetro INTERO invece del contenuto:

     · gli elenchi di 17.7/17.8 nominano `.text-slate-300` e `.text-slate-400`
       ma non il `-500` ne' il `-600`. Dentro un'isola scura quei due restano
       scuri — e da questo giro la (2) qui sopra li manda al muted del tema,
       che sul nero e' scuro-su-scuro: la (2) va quindi ri-affermata qui, o si
       chiuderebbe un difetto aprendone un altro;
     · tutte le regole isola sono scopate a `main`. La SIDEBAR e' fuori da
       `main`, ed e' esattamente dove stanno i due elementi peggiori dell'intera
       misura — «Admin Management» a 1,36 e «Mio Spazio» a 1,80. E' il motivo
       per cui nessun giro precedente li aveva visti: l'audit di allora
       guardava il contenuto, non la pagina. */
[data-theme="light"] .dark-surface,
[data-theme="light"] [class~="bg-slate-700"],
[data-theme="light"] [class~="bg-slate-800"],
[data-theme="light"] [class~="bg-slate-900"],
[data-theme="light"] [class~="bg-slate-950"],
[data-theme="light"] [class~="bg-gray-700"],
[data-theme="light"] [class~="bg-gray-800"],
[data-theme="light"] [class~="bg-gray-900"] {
    color: #f1f5f9;
}
[data-theme="light"] .dark-surface .text-slate-500,
[data-theme="light"] .dark-surface .text-slate-600,
[data-theme="light"] .dark-surface .text-gray-500,
[data-theme="light"] [class~="bg-slate-700"] .text-slate-500,
[data-theme="light"] [class~="bg-slate-700"] .text-slate-600,
[data-theme="light"] [class~="bg-slate-700"] .text-gray-500,
[data-theme="light"] [class~="bg-slate-800"] .text-slate-500,
[data-theme="light"] [class~="bg-slate-800"] .text-slate-600,
[data-theme="light"] [class~="bg-slate-800"] .text-gray-500,
[data-theme="light"] [class~="bg-slate-900"] .text-slate-500,
[data-theme="light"] [class~="bg-slate-900"] .text-slate-600,
[data-theme="light"] [class~="bg-slate-900"] .text-gray-500,
[data-theme="light"] [class~="bg-slate-950"] .text-slate-500,
[data-theme="light"] [class~="bg-slate-950"] .text-slate-600,
[data-theme="light"] [class~="bg-slate-950"] .text-gray-500,
[data-theme="light"] [class~="bg-gray-800"] .text-gray-500,
[data-theme="light"] [class~="bg-gray-900"] .text-gray-500,
[data-theme="light"] [class~="bg-[#0B0F19]"] .text-gray-500,
[data-theme="light"] [class~="bg-[#0B0F19]"] .text-slate-500 {
    color: #cbd5e1;                  /* slate-300: muted LEGGIBILE sul nero */
}
[data-theme="light"] main .dark-surface .text-slate-300,
[data-theme="light"] main .dark-surface .text-slate-400,
[data-theme="light"] main [class~="bg-slate-700"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-700"] .text-slate-400,
[data-theme="light"] main [class~="bg-slate-800"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-800"] .text-slate-400,
[data-theme="light"] main [class~="bg-slate-900"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-900"] .text-slate-400,
[data-theme="light"] main [class~="bg-slate-950"] .text-slate-300,
[data-theme="light"] main [class~="bg-slate-950"] .text-slate-400 {
    /* 17.7 li mandava a #94a3b8, che sul `bg-slate-700` misura 4,04 — sotto la
       soglia per un soffio. Stessa specificita' (0,3,1), vince l'ordine. */
    color: #cbd5e1;
}

/* ── (1d) L'ISOLA E IL TESTO SULLO STESSO ELEMENTO ─────────────────────────
   La (1c) qui sopra corregge `[class~="bg-slate-700"] .text-slate-300` — con
   lo SPAZIO, cioe' il testo DENTRO l'isola. Un badge pero' e' un elemento
   solo che porta entrambe le classi (`<span class="... bg-slate-700
   text-slate-300">`), e su quello il combinatore di discendenza non matcha:
   resta in piedi la regola compatta di 17.7 (`.text-slate-300[class~=...]`,
   #94a3b8) che la (1c) aveva gia' dichiarato sbagliata a 4,04:1 «sotto la
   soglia per un soffio». Stesso difetto, stesso valore, altra forma.

   Misurato sul badge «B» di `accounts/onboarding/membership.html`: portare il
   testo a `text-slate-300` (§10.350, decisione di Alberto: si cambia il TESTO,
   non lo sfondo, perche' cambiare lo sfondo del badge lo farebbe somigliare a
   un altro stato) rende 6,97:1 nel tema SCURO e restava 4,04:1 nel CHIARO —
   cioe' la correzione arrivava a meta', e il presidio di §10.268 l'ha detto
   nominando l'elemento. Qui il chiaro raggiunge lo scuro.

   Stessa specificita' (0,3,1) della regola di 17.7 che scavalca: vince
   l'ordine, come gia' fa la (1c) con la propria. */
[data-theme="light"] main .dark-surface.text-slate-300,
[data-theme="light"] main .dark-surface.text-slate-400,
[data-theme="light"] main [class~="bg-slate-700"].text-slate-300,
[data-theme="light"] main [class~="bg-slate-700"].text-slate-400,
[data-theme="light"] main [class~="bg-slate-800"].text-slate-300,
[data-theme="light"] main [class~="bg-slate-800"].text-slate-400,
[data-theme="light"] main [class~="bg-slate-900"].text-slate-300,
[data-theme="light"] main [class~="bg-slate-900"].text-slate-400,
[data-theme="light"] main [class~="bg-slate-950"].text-slate-300,
[data-theme="light"] main [class~="bg-slate-950"].text-slate-400 {
    color: #cbd5e1;
}

/* ── (5) FUORI DA `main`: intestazione, sidebar, pie' di pagina ────────────
   Tutto il remap di 17.6/17.8 e' scopato a `main`. Il logo «2salti» della
   testata mobile, la lente della ricerca e le voci del pie' di pagina vivono
   fuori: nel chiaro restavano bianche su vetro chiaro (1,05 e 1,41 misurati).
   Stessa forma di 17.6 — remap di base, poi ri-afferma il bianco dove il
   fondo e' un accent PIENO o scuro (i bottoni «Accedi» e simili). */
[data-theme="light"] header .text-white,
[data-theme="light"] aside .text-white,
[data-theme="light"] footer .text-white,
[data-theme="light"] header .text-slate-100,
[data-theme="light"] aside .text-slate-100,
[data-theme="light"] footer .text-slate-100 {
    color: var(--text-main);
}
[data-theme="light"] header .text-slate-300,
[data-theme="light"] header .text-slate-400,
[data-theme="light"] aside .text-slate-300,
[data-theme="light"] aside .text-slate-400,
[data-theme="light"] footer .text-slate-300,
[data-theme="light"] footer .text-slate-400 {
    color: var(--text-muted);
}
[data-theme="light"] header .text-white[class*="bg-blue-"],
[data-theme="light"] header .text-white[class*="bg-indigo-"],
[data-theme="light"] header .text-white[class*="bg-emerald-"],
[data-theme="light"] header .text-white[class*="bg-green-"],
[data-theme="light"] header .text-white[class*="bg-red-"],
[data-theme="light"] header .text-white[class*="bg-amber-"],
[data-theme="light"] header .text-white[class*="bg-gradient"],
[data-theme="light"] aside .text-white[class*="bg-blue-"],
[data-theme="light"] aside .text-white[class*="bg-indigo-"],
[data-theme="light"] aside .text-white[class*="bg-emerald-"],
[data-theme="light"] aside .text-white[class*="bg-green-"],
[data-theme="light"] aside .text-white[class*="bg-red-"],
[data-theme="light"] aside .text-white[class*="bg-amber-"],
[data-theme="light"] aside .text-white[class*="bg-gradient"],
[data-theme="light"] footer .text-white[class*="bg-gradient"] {
    color: #fff;
}

/* ── (6) I PLACEHOLDER, TUTTI, IN UNA REGOLA SOLA ─────────────────────────
   Il placeholder e' testo a tutti gli effetti e nessuna regola del tema lo
   aveva mai nominato: da `placeholder-slate-500` su vetro chiaro (4,29 e 4,38)
   fino al bianco su bianco del campo AI (1,05). Legge `--c-muted`, quindi
   dentro un'isola scura si schiarisce da solo come tutto il resto.
   `opacity: 1` perche' Firefox sbiadisce i placeholder di suo, e uno sbiadito
   e' un contrasto piu' basso di quello che si e' appena calcolato. */
[data-theme="light"] input::placeholder,
[data-theme="light"] textarea::placeholder {
    color: var(--c-muted, var(--text-muted));
    opacity: 1;
}

/* ── (7) `.text-sport` dentro le isole scure ───────────────────────────────
   `text-sport` e' `color: var(--sport-color)` (tailwind.config.js): su un'isola
   scura il blu pieno del brand misura 2,83. Qui NON si tocca `--sport-color`
   — lo leggono anche `bg-sport` e i bagliori, e schiarirlo li' romperebbe un
   fondo pieno per aggiustare un testo — si veste solo il testo.
   Unico punto del blocco in cui si assume una tinta: il prodotto e'
   monosport (pallanuoto, `--sport-color` #2563eb), quindi la forma chiara di
   quella tinta e' quella giusta oggi. */
[data-theme="light"] .dark-surface .text-sport,
[data-theme="light"] [class~="bg-slate-700"] .text-sport,
[data-theme="light"] [class~="bg-slate-800"] .text-sport,
[data-theme="light"] [class~="bg-slate-900"] .text-sport,
[data-theme="light"] [class~="bg-slate-950"] .text-sport,
[data-theme="light"] [class~="bg-[#0B0F19]"] .text-sport {
    color: #93c5fd;                  /* blue-300 */
}

/* ── (8) L'avviso del terzo fallo (fondo rosso PIENO, 2026-08-16) ──────────
   Il fondo `bg-red-700` sta sul CONTENITORE e il testo bianco sui FIGLI: la
   ri-afferma per stesso-elemento del remap (`.text-white[class*="bg-red-"]`)
   non li copre, e il titolo cadeva a 3,7:1 nel chiaro (testo scuro su rosso).
   Il fondo resta rosso pieno in entrambi i temi — e' un avviso di sicurezza,
   la veste E' il messaggio — quindi il testo resta bianco: su red-700 misura
   6,5:1. `text-red-100` non e' rimappato dal tema chiaro e non serve toccarlo. */
[data-theme="light"] main [data-terzo-fallo] .text-white {
    color: #fff;
}

/* ── (9) Il conto dei falli in distinta, variante ambra (2026-08-16) ───────
   Il remap generale porta `text-amber-300` all'ambra scura, che sulla pill
   traslucida `bg-amber-500/20` composta sul fondo chiaro misura 4,32:1 —
   appena sotto la soglia. Un passo piu' scuro (amber-900) misura 5,5:1.
   Scopata alla sola pill del conteggio: la fascia ambra generale resta come
   il blocco l'ha tarata. */
[data-theme="light"] main [data-rosa-falli-conteggio].text-amber-300 {
    color: #78350f;                  /* amber-900 */
}

/* ── (10) §10.416 — I tre box messaggio di `_messages.html` (2026-08-19) ───
   Il nodo porta quattro rami e il righello pre-§10.371 ne misurava uno solo
   (l'else, 13,35:1, che passa): error/warning/success componevano sul fondo
   chiaro un'isola medio-scura col testo chiaro — 4,01–4,12:1, sotto soglia,
   sul canale con cui l'applicazione dice che qualcosa e' andato storto.

   Stessa mossa della (1a): nel chiaro si sposta la SUPERFICIE — il velo scuro
   della tinta diventa la pastiglia chiara della stessa tinta (le -100 di
   Tailwind) — e il testo va alla profondita' che sul chiaro si legge (le
   -800, la stessa scelta della (2)). Il colore sta sull'ELEMENTO perche' i
   token di testo (`text-red-100`, …) stanno sullo stesso tag del fondo, e le
   famiglie della (2) partono da -200: il -100 non lo rimappa nessuno.
   Scopate per token e non per posizione: i tre token `-950/60` vivono solo in
   `_messages.html` (misurato il 2026-08-19). Il tema scuro non e' toccato. */
[data-theme="light"] [class~="bg-red-950/60"] {
    background-color: #fee2e2;       /* red-100 */
    color: #991b1b;                  /* red-800: 6,8:1 */
}
[data-theme="light"] [class~="bg-amber-950/60"] {
    background-color: #fef3c7;       /* amber-100 */
    color: #92400e;                  /* amber-800: 6,4:1 */
}
[data-theme="light"] [class~="bg-emerald-950/60"] {
    background-color: #d1fae5;       /* emerald-100 */
    color: #065f46;                  /* emerald-800: 6,8:1 */
}

/* ================================================================
   BORDO VASCA 19 — LA SUPERFICIE DEL DESK IN GARA (§10.360, §10.362,
   §10.361-UI, §10.199-UI, ratifiche di Alberto del 2026-08-18)

   PERCHE' QUI E NON IN CLASSI TAILWIND. Il build (`tailwind.build.css`) e'
   un file COMPILATO e committato, e node_modules non e' installato: una
   utility che il build non ha compilato e' INERTE — e' la classe di difetto
   di §10.214/§10.236, dove `gap-x-4` e `basis-full` erano intenzioni e non
   stili. Misurati a mano su questo build risultano inerti, fra gli altri,
   `z-30`, `inset-x-0`, `pb-20`, `min-h-[3.5rem]`, `backdrop-blur`,
   `touch-manipulation` e persino `bg-white/20` nudo (esiste solo la
   variante `hover:`). Queste tre superfici sono COMPONENTI, non composizioni
   di utility, e stanno qui come `.glass` sta qui.

   I BERSAGLI SONO IN PIXEL, NON IN REM, e non e' pedanteria: la radice di
   questo progetto e' a 14px, quindi `min-h-[3rem]` misura 42px e non 48 —
   il pavimento «48px» del desk non e' mai stato 48px (misura del
   2026-08-18, §10.410). Qui il minimo si scrive in pixel, cosi' un giorno
   che la radice cambia i bersagli restano dove il vincolo li vuole.

   NIENTE `glass` SU QUESTE SUPERFICI, TESTATA IN COMPILAZIONE INCLUSA. La
   ratifica del 2026-09-05 (§10.363, ratifica veste opaca) chiude la meta' di
   competenza del codice: sotto la testata fissa, mentre si scorre, il
   contenuto sottostante cambia sfondo — escursione di luminanza 6,0 punti
   nello scuro e 11,9 nel chiaro (misura del 2026-08-18) — e in pieno sole un
   fondo che balla sotto il testo e' piu' difficile di un fondo fermo a parita'
   di rapporto WCAG. La testata di compilazione ha la sua superficie opaca,
   gemella della barra d'azione: `#0f172a` scuro / `#ffffff` chiaro, in tutti
   e due i temi. La meta' di competenza di Alberto — la prova col telefono
   in pieno sole — resta della voce, che non si chiude qui.
   ================================================================ */

/* ── (1) La barra d'azione fissa in basso (§10.360) ───────────────────────
   FIXED e non sticky: lo scroller di questa app e' `<main>`, non la
   finestra (`.flex h-screen overflow-hidden` in base.html), e uno sticky
   dentro un contenitore che scorre si ferma al fondo del CONTENUTO, non
   della vista. Il pollice vuole il fondo dello SCHERMO. */
.desk-barra {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    display: flex;
    gap: 12px;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom, 0px));
    background: #0f172a;                        /* slate-900, OPACO */
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.45);
}
[data-theme="light"] .desk-barra {
    background: #ffffff;
    border-top-color: rgba(15, 23, 42, 0.14);
    box-shadow: 0 -6px 24px rgba(15, 23, 42, 0.18);
}
.desk-barra[hidden] { display: none; }

/* I bersagli della barra: 56px di altezza reale, ben oltre i 48 del
   vincolo, e 12px di distanza fra l'uno e l'altro (§10.364). */
.desk-barra-tasto {
    flex: 1 1 0;
    min-height: 56px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 0 14px;
    border-radius: 14px;
    font-weight: 700;
    font-size: 15px;
    line-height: 1.15;
    text-align: center;
    border: 1px solid rgba(255, 255, 255, 0.35);   /* §10.609 */
    background: rgba(255, 255, 255, 0.10);
    color: #ffffff;
    touch-action: manipulation;
}
[data-theme="light"] .desk-barra-tasto {
    border-color: rgba(15, 23, 42, 0.20);
    background: rgba(15, 23, 42, 0.06);
    color: #0f172a;
}
/* Il primario e' PIENO e con testo scuro: la stessa disciplina di D1
   (§10.213) — un fondo opaco non dipende dal tema e resta leggibile in
   pieno sole, dove il colore e' la prima cosa che se ne va. */
.desk-barra-tasto-primario,
[data-theme="light"] .desk-barra-tasto-primario {
    background: #10b981;                        /* emerald-500 */
    border-color: #10b981;
    color: #0f172a;
    flex-grow: 1.6;
}
.desk-barra-tasto:disabled { opacity: 0.45; }

/* CHE LA BARRA NON COPRA IL CONTENUTO. L'altezza NON e' un numero scritto a
   mano: la misura il JavaScript sulla barra resa e la scrive qui (§10.360,
   condizione di chiusura). A barra assente la variabile vale 0 e questa
   regola non fa niente. */
[data-desk-fondo] { padding-bottom: var(--desk-barra-h, 0px); }

/* ── (1b) La testata fissa in compilazione (§10.363) ──────────────────────
   Gemella opaca della barra d'azione, per la stessa ragione: qui sotto ci
   scorre il contenuto del referto, e a bordo vasca il fondo che cambia
   accende un contrasto instabile proprio dove il testo dice il punteggio.
   Il posizionamento resta `sticky top-0` in Tailwind (linea del template);
   qui vive SOLO la superficie: fondo opaco, bordo inferiore leggero,
   ombra di distacco dal contenuto sottostante. */
.desk-testata {
    background: #0f172a;                        /* slate-900, OPACO */
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}
[data-theme="light"] .desk-testata {
    background: #ffffff;
    border-bottom-color: rgba(15, 23, 42, 0.14);
    box-shadow: 0 6px 24px rgba(15, 23, 42, 0.18);
}

/* ── (2) Il tastierino mm:ss in pagina (§10.362) ──────────────────────────
   Sostituisce la tastiera di SISTEMA, non la digitazione: DEC-25 («il
   compilatore digita il tempo») resta valida — cambia lo strumento. */
.desk-tastierino {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin-top: 8px;
}
.desk-tastierino[hidden] { display: none; }
.desk-tasto {
    min-height: 56px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.35);   /* §10.609 */
    background: rgba(255, 255, 255, 0.10);
    color: #ffffff;
    font-size: 26px;                            /* CIFRE GRANDI (§5) */
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    touch-action: manipulation;
    user-select: none;
}
[data-theme="light"] .desk-tasto {
    border-color: rgba(15, 23, 42, 0.20);
    background: rgba(15, 23, 42, 0.06);
    color: #0f172a;
}
/* I due tasti di servizio si distinguono per FORMA e TESTO, non per il solo
   colore (§5: «niente informazione affidata solo al colore»). */
.desk-tasto-servizio { font-size: 18px; letter-spacing: 0.04em; }

/* Lo specchio del tempo: cifre grandi, sopra il tastierino, cosi' chi batte
   legge quello che ha battuto senza cercare la casella. */
.desk-tempo-specchio {
    font-size: 30px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.06em;
    text-align: center;
    line-height: 1.1;
}

/* ── (3) L'annullo di «partita finita» (§10.199-UI) ───────────────────────
   E' un atto DISTRUTTIVO e si veste come tale: rosso pieno sulla conferma,
   non sull'apertura del pannello. Chi apre non ha ancora fatto niente. */
/* Il comando che APRE il pannello. Porta la sua altezza qui e non con
   `min-h-[3rem]` come i comandi vicini, ed e' §10.410: a radice 14px quella
   utility misura 42px, non 48 — misurato in browser il 2026-08-18. I bersagli
   nuovi di questo giro nascono sopra la soglia vera. */
.desk-annullo-apri { min-height: 52px; touch-action: manipulation; }

.desk-annullo-pannello {
    margin-top: 12px;
    padding: 12px;
    border-radius: 14px;
    border: 1px solid rgba(248, 113, 113, 0.45);
    background: rgba(127, 29, 29, 0.22);
}
[data-theme="light"] .desk-annullo-pannello {
    background: rgba(254, 226, 226, 0.85);
    border-color: rgba(185, 28, 28, 0.40);
}
.desk-annullo-pannello[hidden] { display: none; }
.desk-annullo-ragione {
    width: 100%;
    min-height: 72px;
    margin-top: 6px;
    padding: 10px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.35);   /* §10.609 */
    background: rgba(255, 255, 255, 0.10);
    color: #ffffff;
    font-size: 15px;
}
[data-theme="light"] .desk-annullo-ragione {
    border-color: rgba(15, 23, 42, 0.22);
    background: #ffffff;
    color: #0f172a;
}
.desk-annullo-azioni { display: flex; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.desk-annullo-conferma,
.desk-annullo-desisti {
    min-height: 52px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 16px;
    border-radius: 12px;
    font-weight: 700;
    font-size: 14px;
    touch-action: manipulation;
}
.desk-annullo-conferma,
[data-theme="light"] .desk-annullo-conferma {
    background: #dc2626;                        /* red-600, opaco */
    color: #ffffff;
    border: 1px solid #dc2626;
}
.desk-annullo-conferma:disabled { opacity: 0.45; }
.desk-annullo-desisti {
    background: rgba(255, 255, 255, 0.10);
    color: #ffffff;
    border: 1px solid rgba(255, 255, 255, 0.35);   /* §10.609 */
}
[data-theme="light"] .desk-annullo-desisti {
    background: rgba(15, 23, 42, 0.06);
    color: #0f172a;
    border-color: rgba(15, 23, 42, 0.20);
}

/* ── (4) IL PAVIMENTO DEI BERSAGLI DI TOCCO DEL DESK (§10.410) ────────────
   48 pixel VERI, dichiarati in PIXEL e non in `rem`, ed e' il punto della
   voce: la radice di questa applicazione vale 14px sotto i 768 (riga 302), e
   sopra quel confine il prodotto non ne dichiara nessuna — comanda quella del
   browser dell'utente (misurate 12px col carattere «Piccolo» e 16px di serie,
   19/08). Un pavimento in `rem` vale quindi 42px a bordo vasca e un numero
   ignoto altrove: `min-h-[3rem]` e' stato per settimane un «48» che nessun
   dispositivo ha mai reso. Queste classi stanno qui e non fra le utility
   perche' un numero assoluto non ha bisogno di una scala. */
.desk-bersaglio { min-height: 48px; }

/* «di piu' per le azioni frequenti» (DESIGN §5): il percorso del gol. Stessa
   altezza dei tasti del tastierino, che e' la misura gia' collaudata. */
.desk-bersaglio-largo { min-height: 56px; }

/* I numeri di calottina sono bersagli QUADRATI: il dito chiede entrambe le
   dimensioni, e `w-12 h-12` ne dava 42 su tutte e due. */
.desk-calottina { min-height: 48px; min-width: 48px; }

/* LA SPAZIATURA FRA BERSAGLI FITTI, in pixel assoluti (§5, «e SPAZIATI»,
   2026-08-23). Stessa disciplina delle tre classi qui sopra, applicata alla
   distanza invece che all'altezza: `gap-2` e' `.5rem`, e alla radice di 14px
   del bordo vasca vale SETTE pixel, non otto — misurato, non dedotto. Un
   pixel non salva nessuno da solo, ma e' la stessa dipendenza dalla radice
   che ha reso `min-h-[3rem]` un «48» mai reso da nessun dispositivo
   (§10.410): la distanza fra due bersagli adiacenti e' esattamente cio' che
   §5 chiede di garantire, e una garanzia che si accorcia quando l'utente
   rimpicciolisce il carattere non e' una garanzia.

   8px e non di piu': e' il valore che il tastierino gia' dichiara
   (`.desk-tastierino`, sopra), e le due tastiere del desk — le cifre del
   tempo e i numeri di calottina — devono spaziare uguale, o il dito impara
   due distanze diverse sulla stessa pagina. */
.desk-bersagli-fitti,
.desk-riga-fitta {
    gap: 8px;
}

.desk-bersagli-fitti {
    display: flex;
    flex-wrap: wrap;
    margin-top: 8px;
}

/* `.desk-riga-fitta` E' LA SOLA SPAZIATURA, senza il resto (§10.545,
   2026-08-23). Serve ai tre contenitori del desk che NON sono tastiere e in cui
   pero' i bersagli stanno lo stesso fianco a fianco: i due parziali del tempo
   separati da un trattino, la riga «calottina + atleta + Aggiungi» della
   distinta, la riga «nome + tessera + Salva» dello staff — quest'ultima con un
   bottone che scrive sulla DISTINTA UFFICIALE a sette pixel dal campo accanto.
   Tutti e tre portavano `gap-2`, che alla radice di 14px del bordo vasca vale
   SETTE — misurato, non dedotto (matches/tests_desk_bordo_vasca).

   PERCHE' UNA CLASSE A PARTE e non `.desk-bersagli-fitti` su quelle righe:
   quella porta anche `display:flex`, `flex-wrap:wrap` e `margin-top`, e
   applicarla qui cambierebbe l'IMPAGINAZIONE di tre righe gia' collaudate —
   una riga che va a capo su un telefono stretto e' una decisione da prendere
   guardando il telefono, non un effetto collaterale di una correzione di un
   pixel. Il valore sta scritto UNA volta sola, nel selettore condiviso qui
   sopra: le due classi non possono divergere. */

/* ── (5) IL PAVIMENTO DEI BERSAGLI DEL GUSCIO (§10.508/§10.509) ───────────
   Stessa disciplina di (4), applicata a testata e piede di `base.html`:
   48px VERI in pixel assoluti, non un'utility Tailwind in `rem` che sotto i
   768px varrebbe 42 alla radice di 14px (riga 302) — e che qui, non essendo
   ancora compilata nel build consegnato, sarebbe comunque inerte (§10.214/
   §10.410 raddoppiati: una classe assente dal CSS e' un'intenzione, non uno
   stile). Misura browser 390x844 del 2026-08-20: in testata bottone menu
   35x35, bottone ricerca 33.2x35, logo 79.4x28; nel piede «Partite» 37.5x15.2,
   «Classifiche» 63.6x15.2, «Statistiche» 60.6x15.2, contatto 93.1x15.2, logo
   361.4x28. Il carattere non cambia: cresce solo il margine invisibile
   intorno al contenuto reso. */

/* I due loghi (testata e piede): gia' `flex`/`items-center` di Tailwind, e
   gia' larghi a sufficienza per CONTENUTO (79.4px e 361.4px misurati) — ma il
   contenuto non e' un pavimento (lezione del righello del desk, sopra: «non
   e' timidezza, e' l'unico numero che il browser rispetta comunque»). Senza
   `min-width` dichiarato un domani un logo piu' corto o un'icona diversa
   scenderebbe sotto soglia senza che nessuna regola lo impedisca — qui non
   cambia niente a schermo (il contenuto vince gia' oggi su entrambe le
   classi), cambia solo che la larghezza e' GARANTITA e non subita. */
.guscio-logo-bersaglio { min-height: 48px; min-width: 48px; }

/* I due bottoni icona della testata mobile: il contenuto (emoji o SVG) resta
   centrato come prima, cresce solo la cornice invisibile intorno. */
.guscio-bersaglio-icona {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 48px;
    min-height: 48px;
}

/* I link testuali del piede: allineamento a sinistra preservato — il testo
   resta dove sta oggi, l'area toccabile si allarga verso destra e verticalmente. */
.guscio-bersaglio-link {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    min-width: 48px;
    min-height: 48px;
}

/* ══════════════════════════════════════════════════════════════════════════
   §10.467 — LE CLASSI INDOSSATE CHE NESSUN FOGLIO DEFINIVA
   ─────────────────────────────────────────────────────────────────────────
   Quattordici classi erano scritte nei template e non esistevano in nessun
   foglio: attributi senza effetto, cioe' pagine sbagliate dove le indossano,
   in silenzio. Undici sono state TOLTE o riportate al nome vero (`animate-in`
   / `fade-in` / `slide-in-from-bottom-4` e `animate-fadeIn` erano il plugin
   `tailwindcss-animate` mai installato e un refuso di `animate-fade-in`, che
   questo file definisce da sempre; `scrollbar-thin` e
   `scrollbar-thumb-slate-700` erano il plugin `tailwind-scrollbar`, anch'esso
   mai installato, su un elemento che la barra ce l'ha gia' stilata piu' su;
   `text-uppercase` e `border-f1f5f9` erano un nome Bootstrap e un esadecimale
   scritto come nome di classe, entrambi con un equivalente Tailwind gia' nel
   build — `uppercase` e `border-slate-100`, che di quell'esadecimale e' il
   nome; `kpi-card` e `kpi-dashboard` erano etichette morte su due `<div>` che
   fanno tutto con lo `style` inline).

   Le TRE qui sotto restano perche' sono indossate da elementi che senza di
   loro rendono male, e la definizione mancava — non la classe. */

/* Un nastro che scorre in orizzontale senza barra: due nomi per la stessa cosa
   (`scrollbar-hide` sul team, `no-scrollbar` sul date-picker) sono diventati
   uno. Il selettore composto batte la `::-webkit-scrollbar` globale di sopra. */
.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
.no-scrollbar::-webkit-scrollbar { display: none; }

/* Le sei intestazioni bianche dell'area societa' stanno su fondi vivi: senza
   l'ombra il bianco si siede sul fondo. Ombra scura e stretta — non tocca il
   `color`, quindi non entra nel calcolo del contrasto e non ne e' un rimedio:
   e' leggibilita' di bordo, non rapporto. */
.shadow-text { text-shadow: 0 1px 3px rgba(2, 6, 23, 0.55); }

/* L'accento sportivo del testo. NON e' `var(--sport-color)` nudo: il blu pieno
   del brand (#2563eb) su un pannello scuro misura 3,45:1 e sul chiaro dovrebbe
   essere piu' cupo — e' la stessa ragione per cui il blocco (7) veste
   `.text-sport` invece di schiarire il token, che lo leggono anche `bg-sport`
   e i bagliori. Due profondita' della STESSA tinta, una per tema, come tutto
   il resto di questo file. Come nel blocco (7) si assume la tinta: il prodotto
   e' monosport (pallanuoto), e la forma chiara e quella cupa di quel blu sono
   quelle giuste oggi. */
.sport-accent { color: #60a5fa; }                        /* blue-400 */
[data-theme="light"] .sport-accent { color: var(--c-blue, #1e40af); }

/* ══════════════════════════════════════════════════════════════════════════
   §10.602 + §10.418 — SOTTO IL PUNTATORE IL CONTRASTO SALE
   ─────────────────────────────────────────────────────────────────────────
   Due difetti diversi sulla stessa superficie, e vanno letti separati o si
   corregge l'uno credendo di correggere l'altro:

   §10.602 e' AFFORDANCE: l'hover di colore NON SI ACCENDE. A riposo quei testi
   sono a norma; sotto il puntatore non succede niente, cioe' non dicono di
   essere premibili. Misurato col righello sul colore RESO (composto sul fondo,
   non il token scritto nel markup): tema chiaro **44 punti di sorgente morti
   su 69**, tema scuro **0 su 69**.

   §10.418 e' CONTRASTO: l'hover si accende e PORTA SOTTO SOGLIA. 56 punti nel
   chiaro e 44 nello scuro reggono a riposo e cadono sotto il dito.

   IL MECCANISMO DI §10.602, letto dalle dichiarazioni in stato hover:
       .text-slate-500                       (0,1,0) ordine     183
       .hover\:text-sky-300:hover            (0,2,0) ordine     894
       [data-theme="light"] .text-slate-500  (0,2,0) ordine 1000093
   La terza PAREGGIA la seconda in specificita' e la batte per ORDINE, perche'
   questo file e' caricato dopo il compilato Tailwind. Ogni riga di rimappatura
   del blocco accento non riscrive solo il riposo: SPEGNE anche l'hover della
   sua famiglia. Non e' parita' con la classe base — quella e' (0,1,0) e
   perderebbe — e' parita' con una riga di questo file.

   IL PRINCIPIO UNICO che governa tutto il blocco: **sotto il puntatore il
   contrasto col fondo SALE**. Su fondo chiaro l'accento va piu' a fondo; su
   una superficie scura va verso la luce; su un riempimento pieno e' il FONDO
   a muoversi nel verso che allontana il testo. Cosi' nessuna regola qui puo'
   introdurre un difetto di contrasto: puo' solo toglierne.

   PERCHE' DUE LIVELLI E NON UNO (misurato, non estetico). Il tono profondo va
   bene quando il riposo e' grigio (slate-500 -> blue-950 = 3,01:1 di
   differenza, si vede benissimo) e quando il riposo E' GIA' l'accento
   (blue-800 -> blue-950 = 1,53:1). NON va bene sui quattro punti che a riposo
   portano `text-white`, che nel tema chiaro il remap manda a quasi-nero
   (#0f172a): li' il tono profondo misura 1,13:1 contro il riposo, cioe' e'
   invisibile, e serve l'ACCENTO, che di differenza ne fa 1,74. Quei quattro
   punti sono l'unica eccezione, e si riconoscono da una classe sola. */

[data-theme="light"] {
    /* I toni di hover: il fondo della stessa tinta. Sono `-950` di Tailwind,
       tranne il viola — `purple-950` contro `purple-700` misura 1,19:1, cioe'
       lo stesso colore, e si ferma a `-900` (1,56:1). Il criterio non e' «il
       piu' scuro», e' «il piu' scuro che si DISTINGUE dal riposo». */
    --c-blue-hover:    #172554;   /* blue-950   */
    --c-sky-hover:     #082f49;   /* sky-950    */
    --c-indigo-hover:  #1e1b4b;   /* indigo-950 */
    --c-emerald-hover: #022c22;   /* emerald-950 */
    --c-green-hover:   #052e16;   /* green-950  */
    --c-amber-hover:   #451a03;   /* amber-950  */
    --c-yellow-hover:  #422006;   /* yellow-950 */
    --c-orange-hover:  #431407;   /* orange-950 */
    --c-red-hover:     #450a0a;   /* red-950    */
    --c-rose-hover:    #4c0519;   /* rose-950   */
    --c-purple-hover:  #581c87;   /* purple-900 — v. sopra */
}

/* ── (A) §10.602 livello 1: l'hover di colore va al fondo della sua tinta ──
   (0,3,0): l'attributo del tema + la classe + la pseudo-classe. Vince sulla
   riga di rimappatura del riposo, che e' (0,2,0), e per la stessa ragione per
   cui quella vinceva sull'hover: specificita' prima, ordine dopo. */
[data-theme="light"] .hover\:text-blue-200:hover,
[data-theme="light"] .hover\:text-blue-300:hover,
[data-theme="light"] .hover\:text-blue-400:hover,
[data-theme="light"] .hover\:text-blue-500:hover,
[data-theme="light"] .hover\:text-blue-600:hover,
[data-theme="light"] .hover\:text-blue-800:hover,
[data-theme="light"] .hover\:text-blue-900:hover { color: var(--c-blue-hover, #172554); }

[data-theme="light"] .hover\:text-sky-300:hover,
[data-theme="light"] .hover\:text-sky-400:hover { color: var(--c-sky-hover, #082f49); }

[data-theme="light"] .hover\:text-indigo-300:hover,
[data-theme="light"] .hover\:text-indigo-400:hover,
[data-theme="light"] .hover\:text-indigo-600:hover { color: var(--c-indigo-hover, #1e1b4b); }

[data-theme="light"] .hover\:text-emerald-200:hover,
[data-theme="light"] .hover\:text-emerald-300:hover,
[data-theme="light"] .hover\:text-emerald-400:hover { color: var(--c-emerald-hover, #022c22); }

[data-theme="light"] .hover\:text-green-300:hover,
[data-theme="light"] .hover\:text-green-400:hover { color: var(--c-green-hover, #052e16); }

[data-theme="light"] .hover\:text-amber-200:hover,
[data-theme="light"] .hover\:text-amber-300:hover,
[data-theme="light"] .hover\:text-amber-400:hover { color: var(--c-amber-hover, #451a03); }

[data-theme="light"] .hover\:text-yellow-300:hover,
[data-theme="light"] .hover\:text-yellow-400:hover,
[data-theme="light"] .hover\:text-yellow-500:hover { color: var(--c-yellow-hover, #422006); }

[data-theme="light"] .hover\:text-orange-300:hover,
[data-theme="light"] .hover\:text-orange-400:hover { color: var(--c-orange-hover, #431407); }

[data-theme="light"] .hover\:text-red-300:hover,
[data-theme="light"] .hover\:text-red-400:hover { color: var(--c-red-hover, #450a0a); }

[data-theme="light"] .hover\:text-rose-300:hover,
[data-theme="light"] .hover\:text-rose-400:hover { color: var(--c-rose-hover, #4c0519); }

[data-theme="light"] .hover\:text-purple-300:hover,
[data-theme="light"] .hover\:text-purple-400:hover { color: var(--c-purple-hover, #581c87); }

/* I NEUTRI vanno all'ACCENTO, non al testo piu' scuro, ed e' una misura non
   un gusto: mandarli a `--text-main` lascia morto il punto in cui il riposo E'
   GIA' `--text-main` (`match_detail.html:448`: quasi-nero a riposo, quasi-nero
   in hover — contrasto risolto, affordance ancora zero, cioe' la meta'
   sbagliata del difetto). Il blu del tema si distingue da tutti e due i riposi
   di questa famiglia: 1,96:1 dal grigio slate-500 e 1,74:1 dal quasi-nero, con
   in piu' il salto di TINTA, che il rapporto di contrasto non misura ed e'
   quello che l'occhio vede per primo. Ed e' l'idioma del web: il neutro sotto
   il dito diventa il colore del collegamento.
   `text-white` fuori da `main` non e' coperto dal remap per-superficie di 17.7
   (che e' (0,3,1) e scoped a `main`, quindi dentro main continua a vincere
   lui): sono i due link della testata e del piede, gli unici morti della
   famiglia. */
[data-theme="light"] .hover\:text-white:hover,
[data-theme="light"] .hover\:text-slate-100:hover,
[data-theme="light"] .hover\:text-slate-200:hover,
[data-theme="light"] .hover\:text-slate-300:hover { color: var(--c-blue, #1e40af); }

/* `hover:text-black` era spento dal remap dell'accento come tutti gli altri, e
   qui il caso e' doppio: su `report_queue` il riposo e' `text-blue-400` (che
   nel chiaro diventa blue-800) sopra un fondo che all'hover diventa blue-500
   pieno — 2,37:1, cioe' §10.418 e §10.602 sullo stesso elemento. Lasciando
   vincere il nero si chiudono tutte e due: nero su blue-500 misura 5,71. */
[data-theme="light"] .hover\:text-black:hover { color: #000; }

/* ── (B) §10.602 livello 2: i quattro punti che a riposo sono quasi-neri ───
   `text-white` nel tema chiaro e' rimappato a `--text-main`. Da li' il tono
   profondo non si distingue (1,13:1): serve l'ACCENTO. (0,4,0) > (0,3,0). */
[data-theme="light"] [class~="text-white"].hover\:text-blue-300:hover,
[data-theme="light"] [class~="text-white"].hover\:text-blue-400:hover { color: var(--c-blue, #1e40af); }
[data-theme="light"] [class~="text-white"].hover\:text-purple-300:hover,
[data-theme="light"] [class~="text-white"].hover\:text-purple-400:hover { color: var(--c-purple, #7e22ce); }
[data-theme="light"] [class~="text-white"].hover\:text-sky-300:hover,
[data-theme="light"] [class~="text-white"].hover\:text-sky-400:hover { color: var(--c-sky, #0369a1); }
[data-theme="light"] [class~="text-white"].hover\:text-red-300:hover,
[data-theme="light"] [class~="text-white"].hover\:text-red-400:hover { color: var(--c-red, #991b1b); }

/* ── (C) §10.602 livello 3: dentro le isole scure si va verso la LUCE ──────
   Sei punti vivono su una superficie scura anche nel tema chiaro (le isole che
   il blocco 17.8 dichiara). Li' il verso e' rovesciato: il tono profondo
   sparirebbe nel fondo. Le stesse superfici che il file elenca gia' per
   `hover:text-white`, e la stessa specificita' che le fa vincere sulle regole
   di riposo dell'isola, che sono (0,3,1). */
[data-theme="light"] .dark-surface .hover\:text-slate-100:hover,
[data-theme="light"] .dark-surface .hover\:text-slate-200:hover,
[data-theme="light"] .dark-surface .hover\:text-slate-300:hover,
[data-theme="light"] [class~="bg-slate-700"] .hover\:text-slate-100:hover,
[data-theme="light"] [class~="bg-slate-700"] .hover\:text-slate-200:hover,
[data-theme="light"] [class~="bg-slate-700"] .hover\:text-slate-300:hover,
[data-theme="light"] [class~="bg-slate-800"] .hover\:text-slate-100:hover,
[data-theme="light"] [class~="bg-slate-800"] .hover\:text-slate-200:hover,
[data-theme="light"] [class~="bg-slate-800"] .hover\:text-slate-300:hover,
[data-theme="light"] [class~="bg-slate-900"] .hover\:text-slate-100:hover,
[data-theme="light"] [class~="bg-slate-900"] .hover\:text-slate-200:hover,
[data-theme="light"] [class~="bg-slate-900"] .hover\:text-slate-300:hover,
[data-theme="light"] [class~="bg-slate-950"] .hover\:text-slate-100:hover,
[data-theme="light"] [class~="bg-slate-950"] .hover\:text-slate-200:hover,
[data-theme="light"] [class~="bg-slate-950"] .hover\:text-slate-300:hover { color: #fff; }

[data-theme="light"] .dark-surface .hover\:text-blue-300:hover,
[data-theme="light"] .dark-surface .hover\:text-blue-400:hover,
[data-theme="light"] [class~="bg-slate-700"] .hover\:text-blue-300:hover,
[data-theme="light"] [class~="bg-slate-700"] .hover\:text-blue-400:hover,
[data-theme="light"] [class~="bg-slate-800"] .hover\:text-blue-300:hover,
[data-theme="light"] [class~="bg-slate-800"] .hover\:text-blue-400:hover,
[data-theme="light"] [class~="bg-slate-900"] .hover\:text-blue-300:hover,
[data-theme="light"] [class~="bg-slate-900"] .hover\:text-blue-400:hover,
[data-theme="light"] [class~="bg-slate-950"] .hover\:text-blue-300:hover,
[data-theme="light"] [class~="bg-slate-950"] .hover\:text-blue-400:hover { color: #bfdbfe; }  /* blue-200 */

[data-theme="light"] .dark-surface .hover\:text-red-300:hover,
[data-theme="light"] .dark-surface .hover\:text-red-400:hover,
[data-theme="light"] [class~="bg-slate-700"] .hover\:text-red-300:hover,
[data-theme="light"] [class~="bg-slate-700"] .hover\:text-red-400:hover,
[data-theme="light"] [class~="bg-slate-800"] .hover\:text-red-300:hover,
[data-theme="light"] [class~="bg-slate-800"] .hover\:text-red-400:hover,
[data-theme="light"] [class~="bg-slate-900"] .hover\:text-red-300:hover,
[data-theme="light"] [class~="bg-slate-900"] .hover\:text-red-400:hover,
[data-theme="light"] [class~="bg-slate-950"] .hover\:text-red-300:hover,
[data-theme="light"] [class~="bg-slate-950"] .hover\:text-red-400:hover { color: #fca5a5; }  /* red-300 */

/* ── (D) §10.418: i RIEMPIMENTI PIENI, dove a muoversi e' il fondo ─────────
   La famiglia piu' numerosa del difetto, e vale nei DUE temi perche' non c'e'
   nessuna rimappatura di mezzo: e' la tavolozza del prodotto.

     `bg-blue-600 hover:bg-blue-500 text-white`   28 punti, 5,12 -> 3,68
     `bg-blue-500 hover:bg-blue-600 text-black`    7 punti, 5,71 -> 4,06
     `bg-red-600  hover:bg-red-500  text-white`    1 punto,  4,83 -> 3,76
     `group-hover:bg-blue-500   + group-hover:text-white`   1 punto, 3,68
     `group-hover:bg-purple-500 + group-hover:text-white`   1 punto, 3,96

   Tutti lo stesso errore: **l'hover SCHIARISCE il riempimento**, e schiarire
   un fondo sotto un testo bianco toglie contrasto. Il verso giusto dipende dal
   testo, e il principio resta uno: il fondo si allontana dal testo. Testo
   bianco -> il riempimento SCURISCE; testo nero -> il riempimento SCHIARISCE.

   Perche' qui e non nel markup: sono 28 template, e il rimedio e' lo stesso in
   tutti e ventotto. Una riga per famiglia in questo file dice la regola una
   volta; ventotto modifiche di markup la ripetono ventotto volte e la
   ventinovesima pagina nasce sbagliata. Non serve ricompilare niente: sono
   selettori su classi che il build ha gia'.
   (0,3,0) — due classi e la pseudo-classe — contro (0,2,0) dell'utility. */
.text-white.hover\:bg-blue-500:hover  { background-color: #1d4ed8; }   /* blue-700  -> 6,66:1 */
.text-white.hover\:bg-blue-600:hover  { background-color: #1e40af; }   /* blue-800  -> 8,58:1 */
.text-white.hover\:bg-red-500:hover   { background-color: #b91c1c; }   /* red-700   -> 7,00:1 */
.text-white.hover\:bg-green-500:hover { background-color: #15803d; }   /* green-700 */
.text-white.hover\:bg-emerald-500:hover { background-color: #047857; } /* emerald-700 */
.text-white.hover\:bg-purple-500:hover { background-color: #6b21a8; }  /* purple-800 */
.text-white.hover\:bg-indigo-500:hover { background-color: #3730a3; }  /* indigo-800 */

/* Testo nero: il riempimento va nell'altro verso. */
.text-black.hover\:bg-blue-600:hover  { background-color: #60a5fa; }   /* blue-400  -> 8,26:1 */
.text-black.hover\:bg-blue-500:hover  { background-color: #93c5fd; }   /* blue-300 */

/* Le due varianti `group-hover`: stesso principio, altra leva. Il `:hover` sta
   sul gruppo, non sull'elemento, quindi la pseudo-classe si conta li'. */
.group:hover .group-hover\:text-white.group-hover\:bg-blue-500   { background-color: #1d4ed8; }
.group:hover .group-hover\:text-white.group-hover\:bg-purple-500 { background-color: #6b21a8; }
.group:hover .group-hover\:text-white.group-hover\:bg-red-500    { background-color: #b91c1c; }

/* ── (E) §10.418: `text-sport` sotto il dito, sulle superfici scure ────────
   Quattro punti nei due temi (2,83 e 3,45): `hover:text-sport` e
   `group-hover:text-sport` portano il blu PIENO del marchio (#2563eb) su un
   pannello scuro. Il blocco (7) piu' sopra veste gia' `.text-sport` a riposo
   dentro le isole, per la ragione scritta li' — il token lo leggono anche
   `bg-sport` e i bagliori, e schiarirlo romperebbe un fondo per aggiustare un
   testo — ma non ne vestiva le due varianti di stato, che sono esattamente il
   caso in cui il blu arriva dove a riposo non c'era. Stesso valore del blocco
   (7) e per la stessa ragione, e senza scoping di tema: sul pannello scuro il
   difetto e' identico nei due, ed e' il fondo a decidere, non il tema. */
.dark-surface .hover\:text-sport:hover,
[class~="bg-slate-700"] .hover\:text-sport:hover,
[class~="bg-slate-800"] .hover\:text-sport:hover,
[class~="bg-slate-900"] .hover\:text-sport:hover,
[class~="bg-slate-950"] .hover\:text-sport:hover,
.dark-surface .group:hover .group-hover\:text-sport,
[class~="bg-slate-700"] .group:hover .group-hover\:text-sport,
[class~="bg-slate-800"] .group:hover .group-hover\:text-sport,
[class~="bg-slate-900"] .group:hover .group-hover\:text-sport,
[class~="bg-slate-950"] .group:hover .group-hover\:text-sport { color: #93c5fd; }  /* blue-300 */

/* ── (F) §10.602/§10.418: le varianti `group-hover` degli accenti ──────────
   Stessa famiglia di (A), altra leva: il `:hover` sta sul GRUPPO e il colore
   arriva al figlio. Sei punti del tema chiaro cadevano qui (1,94–2,65): il
   titolo di una scheda a riposo e' `text-white` — quasi-nero nel chiaro — e
   sotto il dito prendeva l'accento CHIARO della tinta (blue-400 su fondo
   chiaro = 1,94:1). Il verso e' quello di sempre: sul chiaro si va a fondo.
   Qui pero' l'accento basta e il tono profondo sarebbe di troppo, perche' il
   riposo di questi sei e' quasi-nero — e' il caso (B), da questa parte. */
[data-theme="light"] .group:hover .group-hover\:text-blue-300,
[data-theme="light"] .group:hover .group-hover\:text-blue-400 { color: var(--c-blue, #1e40af); }
[data-theme="light"] .group:hover .group-hover\:text-sky-300,
[data-theme="light"] .group:hover .group-hover\:text-sky-400 { color: var(--c-sky, #0369a1); }
[data-theme="light"] .group:hover .group-hover\:text-red-300,
[data-theme="light"] .group:hover .group-hover\:text-red-400 { color: var(--c-red, #991b1b); }
[data-theme="light"] .group:hover .group-hover\:text-rose-300,
[data-theme="light"] .group:hover .group-hover\:text-rose-400 { color: var(--c-rose, #be123c); }
[data-theme="light"] .group:hover .group-hover\:text-amber-300,
[data-theme="light"] .group:hover .group-hover\:text-amber-400 { color: var(--c-amber, #92400e); }
[data-theme="light"] .group:hover .group-hover\:text-orange-300,
[data-theme="light"] .group:hover .group-hover\:text-orange-400 { color: var(--c-orange, #9a3412); }
[data-theme="light"] .group:hover .group-hover\:text-emerald-300,
[data-theme="light"] .group:hover .group-hover\:text-emerald-400 { color: var(--c-emerald, #065f46); }
[data-theme="light"] .group:hover .group-hover\:text-green-300,
[data-theme="light"] .group:hover .group-hover\:text-green-400 { color: var(--c-green, #166534); }
[data-theme="light"] .group:hover .group-hover\:text-purple-300,
[data-theme="light"] .group:hover .group-hover\:text-purple-400 { color: var(--c-purple, #7e22ce); }

/* Il gruppo puo' ESSERE la superficie scura, non solo contenerla: su
   `team_detail` la scheda e' un `<a class="bg-slate-900 ... group">`, quindi
   `[class~="bg-slate-900"] .group` non la trova — il pannello e il gruppo sono
   lo STESSO elemento. Senza queste righe (E) sembrava applicata e non lo era:
   il punto restava a 2,83:1 nei due temi. */
.dark-surface.group:hover .group-hover\:text-sport,
[class~="bg-slate-700"].group:hover .group-hover\:text-sport,
[class~="bg-slate-800"].group:hover .group-hover\:text-sport,
[class~="bg-slate-900"].group:hover .group-hover\:text-sport,
[class~="bg-slate-950"].group:hover .group-hover\:text-sport,
.dark-surface.hover\:text-sport:hover,
[class~="bg-slate-700"].hover\:text-sport:hover,
[class~="bg-slate-800"].hover\:text-sport:hover,
[class~="bg-slate-900"].hover\:text-sport:hover,
[class~="bg-slate-950"].hover\:text-sport:hover { color: #93c5fd; }  /* blue-300 */

/* ══════════════════════════════════════════════════════════════════════════
   §10.609 — IL FILO VETRO SI VEDE (WCAG 1.4.11, solo TEMA SCURO)
   ─────────────────────────────────────────────────────────────────────────
   §10.601 ha aperto l'asse dei bordi e ha trovato una famiglia dominante e
   sola: il filo bianco traslucido delle superfici vetro. Su fondo scuro
   `border-white/20` misura 1,3:1 e `border-white/5` 1,09:1 — e quei fili
   delimitano BERSAGLI TATTILI (schede-link, tasti del desk), che il criterio
   ratificato dichiara informativi. Alzare l'alpha a 0,35 li porta TUTTI sopra
   3:1: misurato 190 su 190, peggiore 3,09.

   PERCHE' SOLO NEL TEMA SCURO, ed e' una misura non una prudenza: nel tema
   chiaro lo stesso rimedio NON MUOVE NIENTE — 8 su 189. Un filo BIANCO su una
   pagina CHIARA, piu' lo si rende opaco, piu' si avvicina al fondo: da 1,01
   passa a 1,02. Il tema chiaro non ha bisogno di piu' alpha, ha bisogno di un
   altro COLORE (navy al 50%, misurato), e quello e' un cambio d'aspetto
   diverso da «alzare l'alpha» — decisione, non esecuzione. Resta in §10.609.

   NON SI SCOPA CON `:root:not([data-theme="light"])`, ed e' un pezzo di
   metodo che vale piu' della regola: quel selettore e' stato scritto, e il
   righello lo ha letto come `html[data-theme="light"]` — cioe' l'ESATTO
   CONTRARIO, perche' il parser dei compound buttava la pseudo-classe e
   teneva il suo argomento (§10.612, chiusa insieme a questa: ora
   `_compound` si FERMA su `:not()`). Il rimedio sembrava applicato e non lo
   era, e a dirlo non e' stato lo strumento — e' stato il TETTO che non
   scendeva come previsto.

   Resta quindi senza scope, e va bene per misura e non per rassegnazione: un
   filo bianco piu' opaco su una pagina chiara passa da 1,01 a 1,02, cioe' non
   si vede ne' prima ne' dopo e non puo' peggiorare niente; e sulle poche isole
   scure che vivono DENTRO il tema chiaro migliora, come nello scuro.
   (0,1,0) come l'utility Tailwind, ma questo foglio e' caricato dopo. */
[class~="border-white/5"],
[class~="border-white/10"],
[class~="border-white/20"] {
    border-color: rgba(255, 255, 255, 0.35);
}

/* ══════════════════════════════════════════════════════════════════════════
   §10.351 — IL GRIGIO DEL TESTO SECONDARIO NEL TEMA SCURO
   ─────────────────────────────────────────────────────────────────────────
   Il tema scuro non era mai stato misurato: 407 punti sotto soglia a riposo.
   Non erano sparsi — TRE famiglie ne spiegavano l'87,7%:

       text-slate-500   280 punti   peggiore 2,97
       text-gray-500     48 punti   peggiore 2,94
       text-slate-600    31 punti   peggiore 2,15

   Sono lo stesso grigio scritto in tre modi, su pannelli scuri. Il rimedio e'
   sulla TAVOLOZZA e non sui 359 punti: `slate-400` porta il peggiore a 5,52.

   PERCHE' C'E' LA SECONDA REGOLA, ed e' l'unica ragione per cui questa voce non
   si e' chiusa con una riga: il tema scuro NON e' fatto solo di pannelli scuri.
   `ops_cockpit.html` e `staff_dashboard.html` hanno pannelli `bg-white` e
   `bg-slate-50` ANCHE a tema scuro, e li' quel grigio sta su fondo chiaro e
   passa gia' (4,55). Schiarirlo senza guardare avrebbe rotto 38 misure —
   misurato prima di applicare, non scoperto dopo. E' esattamente la regola di
   CLAUDE.md sull'allargare un insieme atteso senza misurare il bersaglio.

   Il tema CHIARO non e' toccato per costruzione: le sue righe sono (0,2,0) e
   queste (0,1,0). Misurato: 4 punti prima e 4 dopo. */
.text-slate-500,
.text-gray-500,
.text-slate-600 {
    color: #94a3b8;                              /* slate-400 */
}

/* I pannelli CHIARI che vivono dentro il tema scuro: li' il grigio resta cupo.
   Sia sull'elemento stesso sia sui discendenti — un pannello puo' portare la
   classe di fondo e quella di testo insieme. */
[class~="bg-white"] .text-slate-500,
[class~="bg-white"] .text-gray-500,
[class~="bg-white"] .text-slate-600,
[class~="bg-slate-50"] .text-slate-500,
[class~="bg-slate-50"] .text-gray-500,
[class~="bg-slate-50"] .text-slate-600,
[class~="bg-slate-100"] .text-slate-500,
[class~="bg-slate-100"] .text-gray-500,
[class~="bg-slate-100"] .text-slate-600,
[class~="bg-slate-200"] .text-slate-500,
[class~="bg-slate-200"] .text-gray-500,
[class~="bg-slate-200"] .text-slate-600,
[class~="bg-gray-50"] .text-slate-500,
[class~="bg-gray-50"] .text-gray-500,
[class~="bg-gray-50"] .text-slate-600,
[class~="bg-gray-100"] .text-slate-500,
[class~="bg-gray-100"] .text-gray-500,
[class~="bg-gray-100"] .text-slate-600,
[class~="bg-gray-200"] .text-slate-500,
[class~="bg-gray-200"] .text-gray-500,
[class~="bg-gray-200"] .text-slate-600 {
    color: #475569;                              /* slate-600 */
}

/* Il PLACEHOLDER e' testo a tutti gli effetti, e le tre famiglie di §10.351
   hanno la loro forma anche li': otto punti del tema scuro restavano fra 2,56 e
   3,84 dopo il rimedio sopra, e non perche' la regola non li raggiungesse —
   perche' vivono su un altro pseudo-elemento. Stesso grigio, stesso rimedio.
   Il tema chiaro non serve guardarlo: `[data-theme="light"] input::placeholder`
   e' (0,2,1) e vince gia' su queste. */
.placeholder-slate-500::placeholder,
.placeholder-gray-500::placeholder,
.placeholder-slate-600::placeholder {
    color: #94a3b8;                              /* slate-400 */
}
[class~="bg-white"] .placeholder-slate-500::placeholder,
[class~="bg-white"] .placeholder-gray-500::placeholder,
[class~="bg-white"] .placeholder-slate-600::placeholder,
[class~="bg-slate-50"] .placeholder-slate-500::placeholder,
[class~="bg-slate-50"] .placeholder-gray-500::placeholder,
[class~="bg-slate-50"] .placeholder-slate-600::placeholder {
    color: #475569;                              /* slate-600 */
}

/* ── §10.351, i 48 residui (1): I PANNELLI CHIARI DENTRO IL TEMA SCURO ─────
   Ventitré dei quarantotto stanno in due sole pagine — `ops_cockpit.html` e
   `staff_dashboard.html` — e per una ragione sola: sono scritte CHIARO-PRIMA
   (pannelli `bg-white`/`bg-slate-50`) mentre il tema di serie è scuro. Dieci
   di quei punti non portano nessuna classe di colore: ereditano `--text-main`,
   che nello scuro è chiaro, e finiscono chiari SU BIANCO — 1,10:1, cioè
   invisibili. È §10.354 su un'altra superficie.

   Il blocco 17.8 fa già ESATTAMENTE questo per il verso opposto (isole scure
   dentro il tema chiaro) e per la stessa ragione. Qui il mirror, senza scope
   di tema: nel tema chiaro le righe di 17.8 sono più specifiche
   (`[data-theme="light"] main …`) e rendono lo stesso valore, quindi non
   cambia niente lì — misurato.

   Non è una toppa per due pagine: è la regola che dice che una superficie
   chiara porta la tavolozza chiara, in qualunque tema la si guardi. */
[class~="bg-white"],
[class~="bg-slate-50"],
[class~="bg-slate-100"],
[class~="bg-slate-200"],
[class~="bg-gray-50"],
[class~="bg-gray-100"],
[class~="bg-gray-200"],
[class~="bg-green-100"],
[class~="bg-amber-100"],
[class~="bg-blue-100"] {
    color: #0f172a;
}

/* E dentro un pannello chiaro gli ACCENTI vanno alla loro profondità da fondo
   chiaro: sono gli stessi valori che il blocco accento del tema chiaro sceglie
   già, applicati per SUPERFICIE invece che per tema. `green-600` su bianco
   misura 3,30, `orange-600` 3,41, `yellow-600` 2,94, `slate-400` 2,56. */
[class~="bg-white"] .text-slate-400,
[class~="bg-slate-50"] .text-slate-400,
[class~="bg-gray-50"] .text-slate-400,
[class~="bg-white"] .text-slate-300,
[class~="bg-slate-50"] .text-slate-300 { color: #475569; }          /* slate-600 */

[class~="bg-white"] .text-green-600,
[class~="bg-slate-50"] .text-green-600,
[class~="bg-green-100"] .text-green-600,
[class~="bg-white"] .text-green-500,
[class~="bg-slate-50"] .text-green-500 { color: var(--c-green, #166534); }

[class~="bg-white"] .text-orange-600,
[class~="bg-slate-50"] .text-orange-600,
[class~="bg-gray-50"] .text-orange-600,
[class~="bg-orange-100"] .text-orange-600 { color: var(--c-orange, #9a3412); }

[class~="bg-white"] .text-yellow-600,
[class~="bg-slate-50"] .text-yellow-600,
[class~="bg-yellow-100"] .text-yellow-600 { color: var(--c-yellow, #854d0e); }

[class~="bg-white"] .text-amber-600,
[class~="bg-slate-50"] .text-amber-600,
[class~="bg-amber-100"] .text-amber-600 { color: var(--c-amber, #92400e); }

/* ── §10.351, i 48 residui (2): LE VARIANTI CON ALPHA SUL FONDO SCURO ──────
   Il blocco accento del tema chiaro dice già la stessa cosa per il suo verso:
   «l'alpha nasceva per ammorbidire su fondo nero e sul chiaro toglie e basta».
   Sul fondo scuro l'alpha non toglie: AFFONDA. `text-blue-500/50` misura 2,10
   su un pannello blu scuro, `text-red-400/70` 3,76, `text-amber-500/70` 4,50.
   Le varianti collassano quindi sul colore pieno — tranne il blu, che pieno si
   ferma a 4,41 (misurato) e va a `-400`. Il criterio è il numero, non la
   simmetria. Il tema chiaro non è toccato: le sue righe sono (0,2,0). */
.text-blue-500\/50 { color: #60a5fa; }                /* blue-400  — pieno = 4,41, non basta */
.text-yellow-500\/50 { color: #eab308; }              /* yellow-500 pieno */
.text-red-400\/70,
.text-red-400\/80 { color: #f87171; }                 /* red-400 pieno */
.text-amber-500\/70,
.text-amber-500\/80 { color: #f59e0b; }               /* amber-500 pieno */

/* ── §10.351, i 48 residui (3): I TOKEN PROFONDI SUL FONDO SCURO ───────────
   Tinte scelte per un fondo chiaro, finite su uno scuro. `text-gray-600` è la
   quarta forma dello stesso grigio delle tre famiglie principali (2,67);
   `text-amber-700` è ambra da fondo bianco (3,65); `text-blue-500` sul pannello
   blu scuro di `profile.html` si ferma a 4,31.
   Le guardie del tema chiaro per `gray-600` e `amber-700` sono state aggiunte
   al blocco accento qui sopra: senza, queste righe — che sono (0,1,0) e nel
   chiaro non avrebbero avuto niente sopra — avrebbero schiarito il testo anche
   là. È lo stesso inciampo di `text-slate-600`, preso una volta e presidiato. */
.text-gray-600 { color: #94a3b8; }                    /* slate-400, come le altre tre */
.text-amber-700 { color: #fbbf24; }                   /* amber-400 */
.text-blue-500 { color: #60a5fa; }                    /* blue-400 */

[class~="bg-white"] .text-gray-600,
[class~="bg-slate-50"] .text-gray-600,
[class~="bg-gray-50"] .text-gray-600 { color: #475569; }
[class~="bg-white"] .text-blue-500,
[class~="bg-slate-50"] .text-blue-500,
[class~="bg-blue-100"] .text-blue-500 { color: var(--c-blue, #1e40af); }
[class~="bg-white"] .text-amber-700,
[class~="bg-amber-100"] .text-amber-700 { color: var(--c-amber, #92400e); }

/* ── §10.351, i 48 residui (4): `text-sport` A RIPOSO SULLE SUPERFICI SCURE ─
   Il blocco (7) veste già `.text-sport` dentro le isole scure, ma SOLO nel tema
   chiaro: nello scuro il blu pieno del marchio (#2563eb) sul pannello misura
   2,83. Stesso valore e stessa ragione del blocco (7) — il token lo leggono
   anche `bg-sport` e i bagliori, quindi si veste il testo e non si tocca la
   variabile. Le due varianti di stato erano già state chiuse con §10.418. */
.dark-surface .text-sport,
[class~="bg-slate-700"] .text-sport,
[class~="bg-slate-800"] .text-sport,
[class~="bg-slate-900"] .text-sport,
[class~="bg-slate-950"] .text-sport,
[class~="bg-[#0B0F19]"] .text-sport { color: #93c5fd; }   /* blue-300 */

/* ── §10.351, i 48 residui (5): LA SECONDA FAMIGLIA DI PLACEHOLDER ─────────
   `placeholder:text-X` è una variante distinta da `placeholder-X` e nessuna
   regola l'aveva mai nominata: `placeholder:text-slate-700` misura 1,67 sul
   campo scuro dell'onboarding, cioè un suggerimento che non si legge.
   Nel chiaro vince `[data-theme="light"] input::placeholder`, che è (0,2,1). */
.placeholder\:text-slate-700::placeholder,
.placeholder\:text-slate-600::placeholder,
.placeholder\:text-gray-600::placeholder,
.placeholder\:text-gray-500::placeholder { color: #94a3b8; }   /* slate-400 */
