/* ============================================================
   Split din app.css pe layer/audienta (audit 2026-08-06 SF, ADR 0023).
   Precedenta layerelor (ultimul castiga): vendor < app < kf (tokens..utilities).
   Ordinea @layer e declarata IDENTIC in capul fiecarui fisier -
   prima declaratie stabileste ordinea, repetarea e no-op.
   ATENTIE: ordinea <link>-urilor e CONTRACT de cascada (intra-layer
   castiga ultimul incarcat): tokens, scoreboard, components, admin,
   base-layout, kf-skin; pagina juratului: tokens, judge, base-layout.
   NU adauga/reordona <link>-uri fara audit de coliziuni (ADR 0023).
   base-layout.css - S2 LAYOUT/nav + chrome partajat (theme-ico, flash toasts)
   + S13 UTILITIES + S16 MOBILE/touch + S17 HOME/page-heads
   + :focus-visible global (@layer base). Se incarca pe TOATE paginile,
   DUPA components/admin (S13/S16/S17 bat componentele la egalitate).
   ============================================================ */
@layer vendor, app, tokens, base, layout, components, utilities;

@layer app {
/* === 2. LAYOUT ============================================= */

/* Navbar — Kinetic Sharp (light × brutalist: flat, hairline 1px, accent lime) */
.app-nav {
    background: var(--kf-surface-bright);
    border-bottom: var(--kf-border);
    box-shadow: none;
    position: sticky;
    top: 0;
    z-index: 1020;
}
/* Trei grupuri, nu o listă plată: brand | navigație principală | utilitare (dreapta).
   Gap FLUID (clamp) → bara se mulează, nu cade brusc la un prag. */
.app-nav__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1rem;
    display: flex;
    align-items: center;
    gap: clamp(0.5rem, 2vw, 1.25rem);
    height: var(--nav-h);
}
.app-nav__brand {
    font-family: var(--kf-font-display);
    font-weight: 900;
    font-size: var(--font-3xl);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--kf-text);
    text-decoration: none;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 0 auto;
    transition: color .1s;
}
.app-nav__mark { color: var(--kf-accent); }
.app-nav__brand:hover { color: var(--kf-accent); }

/* Navigația principală = listă semantică (nav > ul > li), resetată vizual. */
.app-nav__primary {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;                    /* plasă de siguranță, nu mecanismul principal */
    gap: clamp(0.15rem, 1.2vw, 0.6rem);
    min-width: 0;                       /* altfel minimul flex e min-content → nu se strânge deloc */
}
.app-nav__primary > li { min-width: 0; }

/* Utilitarele (cont / login / temă) — dreapta-sus, unde le caută oamenii. */
.app-nav__utility {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-left: auto;
    flex: 0 0 auto;
}

/* --nav-ctl-h = înălțimea COMUNĂ a oricărui control din bară. Fără ea, linkul, butonul și
   comutatorul de temă au trei înălțimi diferite și bara se citește nealiniată. */
.app-nav__link,
.app-nav__btn,
.app-nav__user,
.app-nav__theme {
    height: var(--nav-ctl-h);
    display: inline-flex;
    align-items: center;
}
.app-nav__link {
    font-size: var(--font-md);
    font-weight: 600;
    color: var(--kf-text-variant);
    text-decoration: none;
    padding: 0 clamp(0.35rem, 1.4vw, 0.7rem);
    border-radius: var(--kf-r-sm);
    white-space: nowrap;
    transition: color .1s, background .1s;
}
.app-nav__link:hover { color: var(--kf-text); background: var(--kf-tint); }
.app-nav__link--active {
    color: var(--kf-accent);
    box-shadow: inset 0 -2px var(--kf-marker);
}

.app-nav__btn {
    font-size: var(--font-sm);
    font-weight: 700;
    padding: 0 0.75rem;
    border: var(--kf-border);
    border-radius: var(--kf-r-sm);
    background: transparent;
    color: var(--kf-text);
    text-decoration: none;
    transition: background .1s, color .1s, border-color .1s;
}
.app-nav__btn:hover { background: var(--kf-text); color: var(--kf-surface-bright); }
.app-nav__btn--flash {
    background: var(--kf-primary);
    border-color: var(--kf-primary);
    color: var(--kf-on-primary);
}
.app-nav__btn--flash:hover {
    background: var(--kf-primary-solid);
    border-color: var(--kf-primary-solid);
    color: var(--kf-on-solid);
}
.app-nav__theme {
    justify-content: center;
    width: var(--nav-ctl-h); padding: 0; line-height: 1;
    background: transparent; border: var(--kf-border);
    border-radius: var(--kf-r-sm); color: var(--kf-text);
    cursor: pointer; transition: background .1s, color .1s, border-color .1s;
}
.app-nav__theme:hover { background: var(--kf-text); border-color: var(--kf-text); color: var(--kf-surface-bright); }

/* Dropdown-urile din bară (login + cont) împart aceeași ramă flat — o regulă, două consumatoare. */
.app-nav__login,
.app-nav__menu {
    border: var(--kf-border); border-radius: var(--kf-r-sm);
    box-shadow: none;
    background: var(--kf-surface-bright);
}
.app-nav__login { min-width: 16rem; padding: .75rem; }
.app-nav__login-lbl {
    display: block; margin-bottom: .4rem;
    font-family: var(--kf-font-display); font-weight: 900; font-size: var(--font-2xs);
    text-transform: uppercase; letter-spacing: .08em; color: var(--kf-accent);
}

/* Meniul de cont — UN singur punct pentru identitate + navigarea proprie + ieșire. */
.app-nav__user {
    font-size: var(--font-md);
    font-weight: 600;
    color: var(--kf-text-variant);
    gap: 6px;
    padding: 0 0.5rem;
    background: transparent;
    border: var(--kf-border);
    border-radius: var(--kf-r-sm);
    cursor: pointer;
    white-space: nowrap;
    transition: color .1s, background .1s, border-color .1s;
}
.app-nav__user:hover { color: var(--kf-text); background: var(--kf-tint); }
.app-nav__menu { min-width: 14rem; padding: 0; }
.app-nav__menu-id {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    padding: .6rem .75rem;
}
.app-nav__menu-name { font-weight: 700; font-size: var(--font-md); color: var(--kf-text); }
.app-nav__menu-mail { font-size: var(--font-xs); color: var(--kf-text-variant); word-break: break-word; }
/* app.css n-avea NICIO regulă `dropdown-item` → fără asta meniul ar rămâne Bootstrap-default,
   în afara skin-ului. Butonul de logout e tot `.dropdown-item`, deci reset de buton inclus. */
.app-nav__menu .dropdown-item {
    font-size: var(--font-md);
    color: var(--kf-text);
    padding: .45rem .75rem;
    width: 100%;
    text-align: left;
    background: none;
    border: 0;
    cursor: pointer;
}
.app-nav__menu .dropdown-item:hover,
.app-nav__menu .dropdown-item:focus { background: var(--kf-tint); color: var(--kf-text); }
.app-nav__menu .dropdown-divider { margin: 0; border-top: var(--kf-border); opacity: 1; }
.app-nav__role {
    font-family: var(--kf-font-mono);
    font-size: var(--font-2xs);
    background: var(--kf-surface-2);
    border: 1px solid var(--kf-line);
    padding: 0 5px;
    border-radius: var(--kf-r-sm);
    color: var(--kf-text-variant);
    letter-spacing: .05em;
}

/* Wrapper principal */
.app-wrap {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1rem;
}

/* Pagina judecatorului — fara sidebar, full screen */


/* Container login — latime fixa centrata */
.login-container { max-width: 420px; }

/* Container formular ingust */


/* Header de pagina compact */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.75rem;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.page-header__title {
    font-family: var(--font-display);
    font-size: var(--font-base);
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 0;
}



/* === CHROME PARTAJAT (toate paginile) - mutat din S10/S11b la split === */
/* Iconita temei = derivata din <html data-theme>, NU pusa din JS: butonul are ambele glife si
   CSS arata una. Sursa unica de adevar = atributul, deci starea corecta supravietuieste oricarei
   re-randari de markup (swap de polling, Turbo). Se arata ce OBTII la click. */
.theme-ico--sun { display: none; }
[data-theme="dark"] .theme-ico--sun { display: inline-block; }
[data-theme="dark"] .theme-ico--moon { display: none; }

/* Flash = toast fix, vizibil indiferent de scroll (sub navbar, centrat). Auto-dispar prin flash-toast.js. */
.flash-stack {
    position: fixed; top: 64px; left: 50%; transform: translateX(-50%);
    z-index: 1080; width: min(560px, 92vw);
    display: flex; flex-direction: column; gap: .4rem; pointer-events: none;
}
.flash-stack:empty { display: none; }
.flash-toast { pointer-events: auto; margin: 0; box-shadow: var(--shadow-hard-sm); }

/* Butonul ink + modalul de confirmare brand-uit — MUTATE din components.css (amendament ADR 0023):
   modalul e construit în JS (confirm-action.js + form-dirty.js) și apare pe TOATE audiențele,
   inclusiv pe pagina juratului (rezolvă calificarea / generează bracket / finalizează battle),
   care NU încarcă components.css. Stau ÎNAINTE de §13/§16 ca touch-target-ul mobil pe .btn-ink
   (min-height + inline-flex, mai jos) să câștige la egalitate — exact ordinea din fișierul unic. */
.btn-ink { background: var(--surface-inverse); color: var(--text-on-inverse); border: 2px solid var(--border-strong); border-radius: var(--radius-sm); padding: .4rem 1rem; font-weight: 700; text-transform: uppercase; font-size: var(--font-sm); letter-spacing: .06em; text-decoration: none; transition: background .1s; display: inline-block; }
.btn-ink:hover { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
/* Blocat după trimitere (garda de dublu-submit din category-builder.js) — semnal vizibil, altfel
   butonul arată identic și omul apasă din nou exact ce voiam să prevenim. */
.btn-ink:disabled { opacity: .55; cursor: progress; }
.btn-ink--ghost { background: transparent; color: var(--text); }
.btn-ink--danger { background: var(--danger); border-color: var(--danger); color: var(--on-danger); }
.btn-ink--danger:hover { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }

/* Modal de confirmare brand-uit (SSOT) — folosit de confirm-action.js + form-dirty.js.
   Ramă 2px ink + offset shadow, titlu Archivo uppercase, în loc de cardul soft Bootstrap. */
.confirm-modal .modal-content {
    border: 2px solid var(--border-strong);
    border-radius: var(--radius-sm);
    box-shadow: 6px 6px 0 var(--shadow-color);
    background: var(--surface);
    color: var(--text);
}
.confirm-modal .modal-header { border-bottom: 2px solid var(--border-strong); padding: .6rem .9rem; }
.confirm-modal .modal-title { font-family: var(--font-display, inherit); font-weight: 900; text-transform: uppercase; letter-spacing: .04em; font-size: var(--font-lg); }
.confirm-modal .modal-body { padding: .9rem; }
.confirm-modal .modal-footer { border-top: 0; padding: .6rem .9rem; gap: .5rem; }

/* === 13. UTILITIES ========================================= */


/* Familia UNICĂ de utilitare font-size = .fs-* (§16). Perechea veche .text-xs/.text-sm (cu
   !important) a fost migrată și ștearsă la auditul 2026-08-06 — două familii pentru aceiași
   tokeni însemnau două moduri de a pierde cascada. */


.action-group { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }

/* Buton ultra-compact */
.btn-xs {
    font-family: var(--font-display);
    font-size: var(--font-xs);
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 0.15rem 0.45rem;
    line-height: 1.4;
    border-radius: var(--radius-sm);
}



/* === 16. MOBILE / RESPONSIVE =============================== */
/* Mobile-first dense data. Vezi skill: references/mobile-first-dense-data.md.
   Bază = stiluri care merg pe telefon; @media(min-width) ar adăuga desktop unde e cazul.
   Aici: utilitare ca să scoatem style="" inline + nav + touch. (Pattern-ul card-reflow a fost
   scos din CSS și din reguli la auditul 2026-08-06 — se reintroduce doar când o pagină o cere.) */

/* --- Utilitare font/opacity (înlocuiesc style="font-size:var(--font-*)") --- */
.fs-2xs  { font-size: var(--font-2xs); }
.fs-xs   { font-size: var(--font-xs); }
.fs-sm   { font-size: var(--font-sm); }


/* O singură variantă folosită în markup (`.empty-ico--lg`); baza `.empty-ico` a fost ștearsă
   2026-08-14 — nu era modificator peste ea, ci o a doua mărime pe care n-o mai cerea nimeni. */
.empty-ico--lg { font-size: var(--font-8xl); opacity: .25; }

/* --- Navbar pe telefon: cele 3 destinații rămân VIZIBILE (fără hamburger) ---------------------
   Navigația ascunsă costă ~20% descoperire și ~15% timp pe telefon (studiul NN/g vizibil vs ascuns),
   iar trei etichete scurte încap la 360px dacă bugetul de lățime e respectat:
     marcă 34 + linkuri ~190 + cont 44 + temă 44 + gap-uri ≈ 330px din 341 disponibili.
   De-asta dispar, în ordine: eticheta „Contul meu" (≤640px) și wordmarkul (≤420px) — nu linkurile.
   `flex-wrap` rămâne ca plasă: dacă un font de sistem e mai lat, bara se rupe în loc să iasă din ecran,
   iar elementele lipicioase ancorate în --nav-h se suprapun cu câțiva px, cosmetic. */
@media (max-width: 640px) {
    :root { --nav-h: 52px; --nav-ctl-h: var(--tap-min); }
    .app-nav__inner { height: auto; min-height: var(--nav-h); flex-wrap: wrap; gap: 0.35rem; padding: 0.25rem 0.6rem; }
    .app-nav__brand { font-size: var(--font-xl); gap: 0.35rem; }
    .app-nav__primary { gap: 0.1rem; }
    .app-nav__link { font-size: var(--font-sm); padding: 0 0.4rem; }
    /* Triggerul devine doar iconiță — numele accesibil vine din `aria-label`, identic cu textul
       vizibil de pe desktop (WCAG 2.5.3 „Label in Name" cere să se potrivească, nu să lipsească). */
    .app-nav__user-lbl { display: none; }
    .app-nav__user { width: var(--nav-ctl-h); justify-content: center; padding: 0; }
    .app-nav__utility { gap: 0.3rem; }
}
/* Sub 420px logo-ul colapsează la marcă — pattern standard, și e ultimul lucru sacrificat
   înainte ca bara să se rupă pe două rânduri. */
@media (max-width: 420px) {
    .app-nav__wordmark { display: none; }
}

/* --- Touch targets + forms fluide pe telefon --- */
@media (max-width: 640px) {
    /* `.adj-btn` a IEȘIT din listă intenționat: regula asta îl readucea la 44px exact pe telefon,
       adică exact unde s-a cerut jumătatea de înălțime. Minimul lui e --tap-aa, declarat la componentă. */
    /* `.btn-ink` NU e `.btn` — fără el, „Creează concursul" (acțiunea principală) rămânea la ~35px,
       adică mai MIC decât „Anulează" de lângă el, care e `.btn`. */
    .btn, .btn-ink, .judge-chip__del, .filter-pill, .badge-category { min-height: var(--tap-min); }
    .btn, .btn-ink { display: inline-flex; align-items: center; justify-content: center; }
    /* × de închidere a categoriei: Bootstrap îi dă 16px, prea mic pentru deget. Rezerva de
       padding a rândului (components.css) se lărgește la fel — altfel ținta de 44px acoperea
       câmpul din colț (Vârstă) și tap-ul pe el ștergea categoria. */
    .category-row > .btn-close { min-width: var(--tap-min); min-height: var(--tap-min); }
    .category-row { padding-right: calc(var(--tap-min) + 8px); }
    /* Chip organizator: prezență/invitat/șterge = ținte cât tot chipul (44px), acțiuni late și distanțate. */
    .e-chip-del { --chip-act-h: var(--tap-min); font-size: var(--font-sm); }
    .e-chip-del__x, .e-chip-del__act { min-width: 44px; }
    .e-chip-del__act { font-size: var(--font-md); }
    /* Inputuri/select cu lățime fixă (admin) → fluide pe telefon */
    .w-in-lg, .w-in-md, .w-in-sm { width: 100%; }
    /* Formularul de înscriere rămâne FLUID pe telefon (flex-wrap în .enf-row) — câmpurile se
       împachetează 1–2 pe linie după lățime, aliniate la stânga. NU stivuire dură pe coloană
       (dădea spații mari + aliniere pe mijloc). Anti-overflow = min-width:0 pe .enf-opt/.ac-wrap
       (globale mai jos) → câmpurile pot micșora și rup natural, fără casete ieșite din div. */
}

/* --- Clase semantice care înlocuiesc style="" repetat în template-uri --- */


.tbl-th { font-size: var(--font-xs); color: var(--fg4); text-transform: uppercase; letter-spacing: .05em; padding: .2rem .6rem; }
.col-rank-narrow { width: 1.8rem; font-weight: 700; }

.bk-col-count { font-size: var(--font-3xs); font-weight: 400; opacity: .6; }
.admin-edit-cell { background: var(--paper-2); padding: 0.5rem 0.6rem; }
.w-in-lg { width: 200px; }   /* input lat (email)   — devine 100% pe mobil */
.w-in-md { width: 140px; }   /* input mediu (parolă)— devine 100% pe mobil */
.w-in-sm { width: 120px; }   /* select (rol)        — devine 100% pe mobil */

/* Warning fuzzy „ești tu?" la înscriere (near-duplicate nudge) — bloc full-width SUB rând */
.dup-warn { width: 100%; margin: 0 0 .5rem; padding: .35rem .5rem; background: var(--warning-soft); border: 1px solid var(--warning-border); border-radius: var(--radius-md); font-size: var(--font-xs); }
.dup-warn__head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .25rem; }
.dup-warn__q { color: var(--warning); font-weight: 600; }
.dup-warn__close { flex-shrink: 0; border: 1px solid var(--border-hair); background: var(--card); border-radius: var(--radius-sm); padding: .05rem .5rem; font-size: var(--font-xs); cursor: pointer; white-space: nowrap; color: var(--fg2); }
.dup-warn__close:hover { background: var(--surface-inverse); color: var(--text-on-inverse); border-color: var(--border-strong); }
.dup-warn__pick { display: inline-block; margin: .12rem .2rem .12rem 0; padding: .12rem .5rem; background: var(--card); border: 1px solid var(--border-hair); border-radius: var(--radius-sm); font-size: var(--font-xs); cursor: pointer; }
.dup-warn__pick:hover { background: var(--volt); color: var(--volt-ink); border-color: var(--volt-ink); }

/* Input oraș îngust în rândul de membru (echipă) — încape pe o linie */


/* Formular înscriere: TOATE câmpurile pe UN rând care se împachetează fluid (nu 2 rânduri rigide).
   Câmpurile „text lat" (nume/crew/email/oraș) cresc (flex-grow) ca să umple linia fără gol la capăt;
   gen + dată = fixe. La lățimi mici rup natural pe 2+ linii, fiecare justificată de câmpurile care cresc. */
/* BAZELE sunt intenționat sub lățimea „confortabilă", nu egale cu ea: `flex-basis` decide DOAR unde
   se rupe rândul, iar `flex-grow` umflă câmpurile înapoi pe rândul pe care au încăput. Baze mari =
   rupturi premature și rânduri pe jumătate goale; baze mici + grow = aceeași lățime finală, dar cu mai
   multe câmpuri pe rând. Suma bazelor era ~48rem, adică peste cele ~40rem ale formularului dintr-un
   card la două coloane — de aici rândul 2 cu emailul singur, întins pe toată lățimea (raport user).
   Acum grupul obligatoriu (nume·crew·oraș·țară·email) încape la ~31rem, deci ține un singur rând până
   pe telefon; gen+dată, fixe și mutate la coadă în DOM, formează al doilea.
   `max-width` NU e acolo ca să constrângă împachetarea, ci ca să nu iasă un input de 40rem pe un
   formular lat — o lățime peste care câmpul nu mai e mai ușor de citit, doar mai mare. */
.enf-row    { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; }
.enf-name   { flex: 2 1 7rem;   min-width: 7rem;   max-width: 20rem; }
.enf-crew   { flex: 2 1 6.5rem; min-width: 6rem;   max-width: 20rem; }
.enf-city   { flex: 1 1 5rem;   min-width: 4.5rem; max-width: 14rem; }
.enf-country{ flex: 0 0 auto; }   /* lățime fixă cât un steag (.cs--flag) — ca gen/dată, nu crește */
/* Grow mai mare: adresele sunt cel mai lung text din rând, deci primesc partea leului din spațiul rămas. */
.enf-email  { flex: 3 1 8.5rem; min-width: 7rem;   max-width: 22rem; }
.enf-gender { flex: 0 0 auto; }
.enf-gender > select { width: 3.6rem; }
.enf-dob    { flex: 0 0 auto; }
/* Dată naștere = 3 selecturi (zi · lună · an). Font mic + padding redus ca să încapă cuvântul/anul întreg. */
.dob-row { display: inline-flex; gap: 3px; }
.dob-row select { font-size: var(--font-xs); padding: .2rem .15rem .2rem .3rem; background-position: right .2rem center; background-size: 8px 8px; }
.dob-row .dob-d { flex: 0 0 2.6rem; }   /* Zi  — 2 cifre */
.dob-row .dob-m { flex: 0 0 3.2rem; }   /* Lună — 2 cifre */
.dob-row .dob-y { flex: 0 0 3.6rem; }   /* An  — 4 cifre */

/* Câmp opțional (email/gen/dată/crew/oraș) cu comutare input↔readout „pe profil" (B22). Dansator
   existent care ARE câmpul completat → inputul DISPARE, apare readout-ul (email = mascat, crew/oraș =
   valoarea, gen/dată = doar bifă). Lipsă → rămâne input editabil (backfillProfile salvează la înscriere).
   Crew/oraș needitabile: crew-ul de bază NU se schimbă la reînscriere (ar muta dansatorul în alt crew ELO). */
.enf-opt { display: inline-flex; align-items: center; min-width: 0; }
.enf-opt > .ac-wrap { flex: 1 1 auto; min-width: 0; }
.enf-opt > input { flex: 1 1 auto; min-width: 0; }
.enf-opt > .enf-onfile { display: none; }
.enf-opt.is-onfile > select,
.enf-opt.is-onfile > input,
.enf-opt.is-onfile > .dob-row,
.enf-opt.is-onfile > .ac-wrap { display: none; }
.enf-opt.is-onfile > .enf-onfile {
    display: inline-flex; align-items: center; gap: .3rem;
    font-size: var(--font-xs); font-weight: 600; color: var(--text); white-space: nowrap;
    padding: .18rem .45rem; border: 1px solid var(--success); border-radius: var(--radius-sm);
    background: var(--success-soft);
}
.enf-opt.is-onfile > .enf-onfile .bi { color: var(--success); }
.enf-onfile-val { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* On-file (readout): pilula = content-size + shrink-friendly, NU dimensiunea inputului. Elimină golul
   de flex-grow (crew→oraș) + suprapunerea de nowrap (oraș sub email). Împachetare naturală în .enf-row. */
.enf-opt.is-onfile { flex: 0 1 auto; min-width: 0; max-width: 100%; }
.enf-opt.is-onfile > .enf-onfile { max-width: 100%; min-width: 0; }

/* Membru de echipă = bloc distinct: cele 2 rânduri (person_rows) + număr mic în gutter + zebra discret,
   ca să deosebești concurent 1/2/3/4 fără să aglomerezi. #num tăiat din spațiu la ecrane mici prin padding. */
.member-rows { display: flex; flex-direction: column; gap: .15rem; }
/* `<fieldset>`, nu `<div>`: `disabled` scoate blocul opțional din validare ȘI din payload (vezi
   _entry_form.html.twig). Costul e că trebuie stinse trei implicite de user-agent — `min-inline-size:
   min-content` ar rupe împachetarea fluidă a `.enf-row` exact pe ecranele înguste, iar rama și
   marginile ar dubla zebra. */
.member-block {
    position: relative; padding: .3rem 1.6rem .3rem 1.5rem; border-radius: var(--radius-sm);
    min-inline-size: 0; border: 0; margin: 0;
}
.member-block:nth-child(even) { background: var(--paper-2); }
.member-block__num {
    position: absolute; left: .3rem; top: .5rem;
    font-size: var(--font-xs); font-weight: 700; line-height: 1; color: var(--text-muted);
}
/* Retragerea unui membru opțional. Stă în gutterul din dreapta (paddingul de mai sus îi face loc),
   ca să nu intre în rândul fluid de câmpuri. */
.member-block__del {
    position: absolute; right: .25rem; top: .35rem;
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.35rem; height: 1.35rem; padding: 0;
    border: 0; background: transparent; cursor: pointer; line-height: 1;
    font-size: var(--font-xs); color: var(--text-muted);
}
.member-block__del:hover { color: var(--danger); }

/* Anti-overflow orizontal: media nu depășește lățimea ecranului */
img, svg, table { max-width: 100%; }


/* === 17. HOME (landing) + page heads — Battle-Broadcast ===== */
.page-head { font-family: var(--font-display); font-weight: 900; text-transform: uppercase; letter-spacing: .02em; font-size: var(--font-3xl); line-height: 1.1; color: var(--text); margin: 0; display: inline-flex; align-items: center; }

/* --- Breadcrumbs (SSOT) + marcaj de context (LIVE / REZULTATE / ARHIVĂ) --- */
.breadcrumbs {
    display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
    margin: 0 0 var(--kf-5); font-family: var(--kf-font-mono);
    font-size: var(--font-sm); color: var(--text-muted);
}
.breadcrumbs a { color: var(--text-muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--accent); }
.breadcrumbs__sep { color: var(--text-faint); }
.breadcrumbs__current { color: var(--text); font-weight: 700; }

.page-state {
    display: inline-flex; align-items: center; gap: .4rem; vertical-align: middle;
    font-family: var(--font-display); font-weight: 900; font-size: var(--font-sm);
    text-transform: uppercase; letter-spacing: .08em;
    padding: .2rem .65rem; border-radius: var(--radius-md);
}
.page-state--live            { background: var(--status-active-bg); color: var(--status-active-fg); }
.page-state--results,
.page-state--archive-results { background: var(--surface-inverse);  color: var(--text-on-inverse); }
.page-state--archive         { background: var(--status-done-bg);   color: var(--status-done-fg); }
.page-state__dot {
    width: .5rem; height: .5rem; border-radius: 50%; background: currentColor;
    animation: page-state-pulse 1.2s ease-in-out infinite;
}
@keyframes page-state-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

/* Proiector: ascunde chrome-ul (nav + breadcrumbs). Clasa pe <body> vine din `?proiector=1` (server),
   nu dintr-un buton de comutare — ăla a fost șters 2026-08-14 (ecranul de sală, ADR 0019, e calea). */
.live-projector .app-nav,
.live-projector .breadcrumbs { display: none; }

/* --- Arhivă publică (/arhiva) -------------------------------------------------------------
   Rândul = afiș PORTRET 3:4 în stânga, cu înălțime EGALĂ pe toate rândurile, + o coloană de
   text care se mulează. Înălțimea fixă e decizia de design, nu o scăpare: dacă afișul ar crește
   odată cu conținutul, un concurs cu 12 categorii ar primi un afiș de 2× față de unul cu 2 →
   grilă zimțată, imposibil de scanat pe verticală.

   Dimensionarea internă vine din LĂȚIMEA CARDULUI (container query pe .arch-card), nu din
   viewport: două carduri pe rând și unul singur au același ecran dar cutii diferite, deci un
   @media ar minți. Aceeași motivație ca .judge-col.
   ⚠️ CAPCANĂ: unitățile `cq*` NU se rezolvă pe elementul care DECLARĂ containerul → toate
   clamp-urile stau în COPII (.arch-row/.arch-poster/.arch-title/.arch-body), niciodată pe
   .arch-card. Și `inline-size`, NICIODATĂ `size` (ăla adaugă containment pe bloc → card prăbușit). */
.arch-toolbar { display: flex; flex-wrap: wrap; gap: .5rem clamp(.5rem, 2vw, 1.25rem); align-items: center; margin-bottom: var(--kf-4); }
.arch-toolbar__filters { display: flex; flex-wrap: wrap; gap: .35rem; }
.arch-toolbar__status { display: flex; align-items: center; gap: .5rem; margin-left: auto; }

/* Bară de salt la an — refolosește .filter-pill (deci și bump-ul de touch 44px de pe mobil). */
.arch-jump { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; margin-bottom: var(--kf-5); }

/* Antet de an LIPICIOS: reperul cronologic nu mai dispare la derulare. `top` = înălțimea
   navbarului (el însuși sticky, z-index 1020) → anul se oprește SUB el, nu peste.
   Fundal OPAC obligatoriu, altfel cardurile se văd prin el. z-index explicit: itemii de grilă
   creează contexte de stivuire și ar picta peste antet. */
.arch-year {
    position: sticky; top: var(--nav-h); z-index: 5;
    display: flex; align-items: baseline; gap: .6rem;
    background: var(--bg); padding: .3rem 0; margin: 1.4rem 0 .6rem;
    font-family: var(--font-display); font-weight: 900; font-size: var(--font-3xl);
    text-transform: uppercase; letter-spacing: .02em; color: var(--text);
}
.arch-year__n { font-size: var(--font-sm); font-weight: 400; color: var(--text-muted); }
.arch-year-block { scroll-margin-top: calc(var(--nav-h) + var(--kf-3)); }

/* Coloane INTRINSECI, fără @media: --arch-col-min > 1600/3 ⇒ maximum 2 coloane pe .page-wide
   (max-width 1600px); trecerea la o coloană se face singură pe la ~1100px. `min(100%, …)` =
   plasa anti-overflow când viewportul e sub lățimea minimă de coloană. */
.arch-list {
    --arch-col-min: 34rem;
    display: grid; gap: clamp(.5rem, 1.2vw, var(--kf-4));
    grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--arch-col-min)), 1fr));
}
.arch-card { container-type: inline-size; }   /* SINGURA declarație de containment */

.arch-row { display: flex; align-items: stretch; gap: clamp(.5rem, 2.5cqi, 1rem); flex: 1 1 auto; }
.arch-poster {
    flex: 0 0 auto; aspect-ratio: 3 / 4; height: clamp(9.5rem, 30cqi, 13.75rem);
    border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-inverse);
}
.arch-poster[data-lightbox] { cursor: zoom-in; }
.arch-poster img { display: block; width: 100%; height: 100%; object-fit: cover; }
.arch-poster--empty { display: flex; align-items: center; justify-content: center; color: var(--text-faint); font-size: var(--font-2xl); }

.arch-body {
    flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: .35rem;
    padding: clamp(.5rem, 2cqi, .75rem) clamp(.6rem, 2.5cqi, 1rem) clamp(.5rem, 2cqi, .75rem) 0;
}
.arch-title {
    font-family: var(--font-display); font-weight: 900; text-transform: uppercase;
    letter-spacing: -.01em; line-height: 1.03; margin: 0;
    font-size: clamp(var(--font-xl), 6cqi, var(--font-4xl));
    color: var(--text); overflow-wrap: anywhere;
}
.arch-meta {
    display: flex; flex-wrap: wrap; align-items: center; gap: .2rem clamp(.35rem, 2cqi, .8rem);
    font-size: var(--font-sm); color: var(--text-secondary);
}
.arch-meta i { opacity: .75; }
.arch-month { text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); }

/* margin-top:auto împinge chipurile la baza coloanei → se aliniază între cardurile de pe același rând. */
.arch-cats { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: auto; padding-top: .55rem; }
.arch-cat { display: inline-flex; align-items: center; gap: .3rem; padding: .15rem .4rem; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); text-decoration: none; color: var(--text-muted); }
.arch-cat:hover { border-color: var(--accent); color: var(--text); }
.arch-cat__fmt { font-family: var(--kf-font-mono); font-size: var(--font-xs); }
.arch-cat--more { font-weight: 700; }
/* „Niciun rezultat" — ASCUNS din CSS by default. Altfel e vizibil la primul paint, sub lista
   completă, până rulează JS-ul (și rămâne vizibil dacă JS-ul cade). JS-ul comută clasa .is-on,
   NU style.display: cardurile folosesc deja axa aia, iar două mecanisme pe aceeași axă se bat. */
.arch-empty { display: none; }
.arch-empty.is-on { display: block; }
.home-hero {
    border: var(--border-dark); border-radius: var(--radius-lg); background: var(--card);
    box-shadow: var(--shadow-hard); padding: 2.2rem 1.4rem; text-align: center; margin: 1rem 0 1.4rem;
}
.home-hero__mark { font-size: var(--font-6xl); color: var(--text); line-height: 1; }
.home-hero__title {
    font-family: var(--font-display); font-weight: 900; text-transform: uppercase; letter-spacing: .015em;
    font-size: clamp(2.2rem, 6vw, 3.4rem); line-height: 1; margin: .3rem 0 .45rem; color: var(--text);
}
.home-hero__flash { color: var(--primary); }
.home-hero__tag { font-size: var(--font-md); color: var(--fg2); max-width: 38rem; margin: 0 auto 1.1rem; }
.home-hero__cta { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; }
.home-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1rem; }
.home-card__body { padding: .8rem .9rem; display: flex; flex-direction: column; gap: .65rem; align-items: flex-start; }
.home-card__body p { margin: 0; font-size: var(--font-sm); color: var(--fg2); }

/* Leaderboard (clasament) — panou înrămat scoreboard, rânduri dense pe o linie */
.lb-panel { border: var(--border-dark); border-radius: var(--radius-lg); background: var(--card); overflow: hidden; }
.lb-panel__head {
    display: flex; align-items: center; gap: .4rem; padding: .4rem .65rem;
    background: var(--surface-inverse); color: var(--text-on-inverse);
    font-family: var(--font-display); font-weight: 900; font-size: var(--font-sm);
    text-transform: uppercase; letter-spacing: .08em;
}
/* `--primary` (marcaj care urmează tema), NU `--volt`: lime ca TEXT pe suprafața light dă ~1.1:1 —
   contorul era invizibil pe tema implicită. Vezi UI_RULES, blocul de contrast, punctul 8. */
.lb-panel__head .lb-panel__count { margin-left: auto; font-family: var(--font-mono); font-size: var(--font-xs); color: var(--primary); }
.lb-panel .tier-table { margin: 0; }
.lb-panel .tier-table td { padding: .3rem .55rem; }
.lb-panel .tier-table tbody tr:nth-child(even) td { background: var(--paper-2); }
.lb-panel .tier-table tbody tr:hover td { background: var(--volt); color: var(--volt-ink); }
/* ELO = numărul-vedetă, font display (Archivo) */
.lb-elo { font-family: var(--font-display); font-weight: 900; font-size: var(--font-lg); color: var(--text); line-height: 1; }
/* meta inline pe ACEEAȘI linie cu numele (crew · oraș · țară) — nu pe rând nou */
.lb-meta { font-size: var(--font-xs); color: var(--fg3); white-space: nowrap; }
/* a doua linie meta (N concursuri · ultima participare) — pe rând propriu sub nume */
.lb-meta--sub { display: block; }
.lb-meta__cc { font-family: var(--font-mono); color: var(--fg2); }
.lb-empty { padding: 1rem .65rem; font-size: var(--font-sm); color: var(--fg3); }


} /* END @layer app */

@layer base {
  /* FOCUS VIZIBIL — SSOT unic (WCAG 2.4.7 nivel A + 2.4.11 Focus Appearance).
     Trei reguli de formular kf ștergeau `outline` și lăsau ca semnal doar culoarea unei borduri;
     pe `.entry-form` (înscrierea publică) nu mai rămânea NIMIC — cine navighează cu Tab nu vedea
     unde e. `:focus-visible`, NU `:focus`: inelul apare la tastatură, nu la click de mouse.
     `outline`, NU box-shadow: nu e tăiat de `overflow: hidden` și nu intră în coliziune cu
     shorthand-urile de box-shadow deja folosite pe câmpuri. `--focus-ring` era token MORT. */
  :focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
  }
}
