/* ============================================================
   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, site-palette; juratul: 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 ============================================= */

/* ═══ LINIA DE DECIZIE a lățimii paginilor publice (B68) ═══
   `.page-wide` stă pe <body>, iar bara, wrapperul și subsolul sunt toate DESCENDENȚII lui — deci
   remapul de aici urcă toate trei deodată, prin moștenire, dintr-un singur loc. Înainte erau trei
   `max-width: 1200px` copiate, iar `.page-wide` ridica DOAR wrapperul: pe fiecare pagină publică
   conținutul ieșea cu 400px în afara barei și a subsolului.

   Nicio coliziune de cascadă: `:root` declară pe <html>, regula asta pe <body> — elemente diferite,
   deci nu contează nici layerul, nici ordinea <link>-urilor.

   Ca să coborâm conținutul la 1200 în loc să urcăm chromeul la 1600: ȘTERGE regula. Ca să fie lat
   peste tot: mută declarația în `:root` din tokens.css. Nu există a treia variantă, și e intenționat
   — starea de dinainte (doar wrapperul lat) nu mai e exprimabilă. */
body.page-wide { --container-max: var(--container-max-wide); }

/* Bara de navigație = o BANDĂ opacă, cu suprafața ei (B188, direcția B — cerneală pe tema deschisă, tonul s3 pe cea
   închisă). Aici stă doar GEOMETRIA: fundalul, umbra, culorile textului și inelul de focus al benzii sunt valori de SITE
   (`--nav-*`, site-palette.css) și se aplică în components.css, blocul „VALORI DE SITE" — foaia asta e încărcată și de
   ecranul juratului, unde tokenii benzii nu există. ⚠️ components.css se încarcă ÎNAINTEA acestei foi: o declarație de
   culoare lăsată aici pe aceleași selectoare ar câștiga. */
.app-nav {
    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: var(--container-max);
    margin: 0 auto;
    padding: 0 1rem;
    display: flex;
    align-items: center;
    gap: clamp(0.5rem, 2vw, 1.25rem);
    height: var(--nav-h);
}
/* Brandul din bară e o imagine, nu text: wordmarkul e desenat în logo. De-asta n-au mai rămas
   reguli de tipografie aici — dimensiunea vine din --brand-logo-h (vezi components.css „Semnul de
   brand"). Opacitatea la hover ține loc de virajul de culoare de dinainte: un logo nu se recolorează. */
.app-nav__brand {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    text-decoration: none;
    --brand-logo-h: 30px;
    /* Podea de tinta (WCAG 2.2 SC 2.5.8 AA): sub 420px lockup-ul colapseaza la wordmark si logoul
       ajunge la 22px inaltime — sub cele 24 sub care nu se coboara. Bara are deja 52px pe telefon,
       iar brandul e `display: flex`, deci cutia creste fara sa miste nimic. Masurat: 48x22 → 48x24. */
    min-height: var(--tap-aa);
    transition: opacity .1s;
}
@media (hover: hover) { .app-nav__brand:hover { opacity: .75; } }

/* Navigația principală = listă semantică (nav > ul > li), resetată vizual. */
.app-nav__primary {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: stretch;
    align-self: stretch;
    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; display: flex; }

/* 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;
}
/* B234 (Arena): linkul = o cutie de control (34px pe lat, podeaua de atingere pe telefon), cu colț de control, 14px; indicatorul
   stă pe marginea de JOS a cutiei. Pe telefon (≤ 540px) regulile de jos îl fac tab pe toată treimea, la 44px. */
.app-nav__link {
    --nav-link-px: clamp(0.5rem, 1.4vw, 0.75rem);
    position: relative; height: var(--nav-ctl-h); align-self: center;
    font-size: var(--font-base);
    font-weight: 600;
    text-decoration: none;
    padding: 0 var(--nav-link-px);
    border-radius: var(--radius-control, 0);
    white-space: nowrap;
    transition: color .1s, background .1s;
}
.app-nav__link--active { font-weight: 700; }
/* „Ești aici" (NN/g „Tabs, Used Right": cel puțin DOUĂ semnale): textul plin și gras + linia de 2px pe marginea de JOS a
   cutiei linkului, pe toată lățimea ei (B234, macheta Arena). Grafic de stare → ≥3:1 față de bandă (WCAG 1.4.11). BORDURĂ, nu
   fundal / umbră: în modul de contrast ridicat (forced-colors) fundalul și umbra dispar, bordura nu.
   Longhand-uri, nu prescurtarea: aceea ar reseta și CULOAREA, care vine din components.css (încărcat înaintea foii). */
.app-nav__link--active::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0;
    height: 0; border-top-width: 2px; border-top-style: solid; border-radius: 0;
}

.app-nav__btn {
    font-size: var(--font-base);
    font-weight: 700;
    padding: 0 0.9rem;
    border: var(--kf-border);
    border-radius: var(--radius-control, 0);
    background: transparent;
    color: var(--kf-text);
    text-decoration: none;
    transition: background .1s, color .1s, border-color .1s;
}
@media (hover: hover) { .app-nav__btn:hover { background: var(--kf-text); color: var(--kf-surface-bright); } }
/* „Login" (`.app-nav__btn--flash`): B234 (Arena) = buton CONTURAT pe bandă, inversat la hover — culorile, din rolurile benzii, în
   components.css (blocul „VALORI DE SITE"). */
.app-nav__theme {
    justify-content: center;
    width: var(--nav-ctl-h); padding: 0; line-height: 1;
    background: transparent; border-width: 1px; border-style: solid;
    border-radius: var(--sm-r-pill);
    cursor: pointer; transition: background .1s, color .1s, border-color .1s;
}

/* 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(--sm-r-card);
    box-shadow: var(--sm-elev-float);
    background: var(--kf-surface-bright);
}
.app-nav__login { min-width: 16rem; padding: .75rem; }
/* „Vrei cont de organizator?" sub formular (ADR 0053, it. 2): orice login are dedesubt „nu ai cont?". */
.app-nav__login-help { margin: .7rem 0 0; font-size: var(--font-xs); color: var(--kf-text-variant); }
.app-nav__login-help a { color: var(--kf-text); }
.app-nav__login-lbl {
    display: block; margin-bottom: .4rem;
    font-family: var(--kf-font-display); font-weight: var(--type-label-weight, 900); font-size: var(--font-2xs);
    text-transform: var(--type-label-case, uppercase); letter-spacing: var(--type-label-tracking, .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;
    gap: 6px;
    padding: 0 0.5rem;
    background: transparent;
    border-width: 1px; border-style: solid;
    border-radius: var(--sm-r-pill);
    cursor: pointer;
    white-space: nowrap;
    transition: color .1s, background .1s, border-color .1s;
}
.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;
}
/* `:focus` rămâne în afara gărzii de hover: tastatura trebuie să vadă itemul curent și pe touch. */
.app-nav__menu .dropdown-item:focus { background: var(--kf-tint); color: var(--kf-text); }
@media (hover: hover) { .app-nav__menu .dropdown-item:hover { background: var(--kf-tint); color: var(--kf-text); } }
/* Acțiunea care PORNEȘTE ceva (owner, 2026-09-28: „de acolo se fac concursurile noi"). Accentul e
   doar greutate + o iconiță — NU o umplere: un item plin într-un meniu de text ar citi ca un buton
   lipit înăuntru, iar meniul are deja un singur nivel de suprafață. Iconița face treaba grea,
   fiindcă e SINGURA din meniu; greutatea doar o susține.
   ⚠️ Culoarea iconiței NU se scrie aici: fișierul ăsta e partajat cu ecranul juratului, unde tokenii
   `--sm-*` nu există — de aia regulile din jur folosesc `--kf-*`. Valoarea de site stă în
   `components.css`, în secțiunea „VALORI DE SITE pentru reguli care traiesc in foi PARTAJATE". */
.app-nav__menu .app-nav__menu-cta { font-weight: 700; }
.app-nav__menu .dropdown-divider { margin: 0; border-top: var(--kf-border); opacity: 1; }
/* Ultimul element din meniu e „Iesire”, care picteaza la hover si acoperea coltul de jos.
   ⚠️ El sta intr-un `<form>`, iar `<form>`-ul nu picteaza — deci raza trebuie sa treaca PRIN el:
   `inherit` se inlantuie (formularul o ia de la meniu, butonul de la formular). Fara al doilea
   selector, raza ar ajunge pe un element invizibil si n-ar repara nimic.
   Ca si la `.panel-acc`: se vede doar la hover, pe un meniu deschis — sonda nu-l poate masura. */
.app-nav__menu > :last-child,
.app-nav__menu > :last-child > .dropdown-item {
    border-end-start-radius: inherit; border-end-end-radius: inherit;
}
.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: var(--type-label-tracking, .05em);
}

/* Wrapper principal */
.app-wrap {
    max-width: var(--container-max);
    margin: 0 auto;
    /* Gutter fluid: sub 640px scade spre ~9.5px (aliniat cu .app-nav__inner de la ≤640px),
       de la 640px în sus e exact 1rem ca înainte. */
    padding: 0 clamp(.5rem, 2.5vw, 1rem);
}
/* Rândul Bootstrap din base.html.twig are margini negative = jumătate de gutter (-12px). Sub 480px padding-ul
   de mai sus e mai mic de 12px, deci pagina derula lateral 2-4px (măsurat: 2.25px la 390, 4px la 320).
   Gutterul urmează padding-ul wrapperului: la ≥480px rămâne 24px (desktop neschimbat), sub el scade odată
   cu padding-ul. `--bs-gutter-x` pe `.app-wrap` NU ajunge — `.row` și-l redeclară; `>` lasă neatinse
   rândurile imbricate `g-2` / `g-3`. */
.app-wrap > .row { --bs-gutter-x: min(1.5rem, 2 * clamp(.5rem, 2.5vw, 1rem)); }

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


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

/* --- Subsol (B234, macheta Arena) -------------------------------------------------------------
   Brandul, MARE și centrat: semnul desenat uriaș (wordmarkul — numele nu se retipărește ca text, ADR 0031), tagline-ul pe rândul
   lui, cele patru sensuri condensate și stinse dedesubt; jos, sub un fir, rândul de informații obligatorii (domeniul, linkurile
   legale, operatorul) — trei grupuri care stau unul lângă altul și pică pe rând, unul câte unul. Pe suprafața paginii, fără ramă:
   banda marquee de deasupra (pe paginile publice) îl desparte de conținut. */
.app-footer {
    margin-top: clamp(2rem, 6vw, 4rem);
}
.app-footer__inner {
    max-width: var(--container-max);
    margin: 0 auto;
    padding: clamp(2rem, 4cqi, 4rem) clamp(1rem, 4cqi, 2.5rem) 1.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow: hidden;
}
.app-footer__brand { --brand-logo-h: clamp(4.5rem, 2rem + 17cqi, 18rem); display: flex; max-inline-size: 100%; }
.app-footer__brand .brand-logo__img { max-inline-size: 100%; block-size: auto; max-block-size: var(--brand-logo-h); }
.app-footer__tagline, .app-footer__senses {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 900;
    font-stretch: var(--ar-wdth, 100%);
    font-size: clamp(1.4rem, 1rem + 1.6cqi, 2.6rem);
    line-height: 1;
    text-transform: uppercase;
    text-align: center;
}
.app-footer__tagline { margin-top: 1rem; color: var(--text); }
/* Sensurile: cuvinte despărțite de aer, nu de semne (la rupere un separator ar rămâne agățat la capăt de rând). */
.app-footer__senses {
    margin-top: .25rem;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .25rem 1.25rem;
    color: var(--ui-quiet);
}
.app-footer__row {
    align-self: stretch;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem 1.5rem;
    margin-top: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--sm-hair);
    font-size: var(--font-md);
    color: var(--text-muted);
}
.app-footer__domain {
    margin: 0;
}
/* Linkuri legale (B68): informație obligatorie, nu navigație — nu concurează cu bara, dar se citește (cerneala, 600). */
.app-footer__legal {
    display: flex;
    flex-wrap: wrap;
    gap: .2rem 1rem;
}
/* Podea de țintă (B170, WCAG 2.2 SC 2.5.8 AA): linkurile măsurau 18px înălțime pe 390px — sub cele
   24px sub care nu se coboară. Cutia crește, TEXTUL nu: `--font-2xs` e alegerea de densitate a
   subsolului, nu un defect. `inline-flex` + centrare verticală ține glifa pe linia ei, iar surplusul
   se împarte egal sus/jos. Pe un rând cu `gap`, lățimea nu se atinge: linkurile au deja 49-133px. */
.app-footer__legal a { color: var(--text); font-weight: 600; text-decoration: none; }
.app-footer__legal a { display: inline-flex; align-items: center; min-height: var(--tap-aa); }

.app-footer__legal a:hover { color: var(--accent); text-decoration: underline; }
/* Identificarea operatorului (L. 365/2002 art. 5): ultimul grup al rândului; adresa de contact pe cerneală. */
.app-footer__operator {
    margin: 0;
}
.app-footer__operator a { color: var(--text); font-weight: 600; text-decoration: none; }

/* Container formular ingust */


/* === 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(--sm-elev-float); text-wrap: pretty; }
/* Propozițiile unui mesaj, fiecare pe rândul ei (B245): filtrul Twig `sentences` le înfășoară în `.msg__s`, iar
   `text-wrap: pretty` nu lasă un cuvânt singur pe ultimul rând. Aici (comun site + jurat) fiindcă flash stack-ul e partajat. */
.msg__s { display: block; text-wrap: pretty; }

/* Butonul ink + chrome-ul de modal brand-uit — MUTATE din components.css (amendament ADR 0023):
   modalul de confirmare 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 {
    /* Contopita cu regula kf la B159 L10 (F1): valorile de mai jos sunt cele kf, care bateau
       oricum prin layer. Contopita, NU pusa mai jos: ca regula separata, scurtatura `border: 0`
       de aici ar fi omorat `border-color` din `.btn-ink--danger` de dedesubt (aceeasi
       specificitate, shorthand peste longhand) — exact ce a prins `css-structure`. */
    background: var(--sm-btn-fill); color: var(--sm-on-btn-fill);
    border: 0; border-radius: var(--radius-control, 0);
    font-family: var(--kf-font-mono); font-weight: 700; font-size: var(--font-sm);
    text-transform: var(--type-control-case, uppercase); letter-spacing: var(--type-control-tracking, .05em);
    /* `justify-content: center` CONTEAZA doar cand butonul are latime FORTATA (`.w-100`,
       `.manage-act > .btn-ink`): la latime auto nu exista spatiu liber de impartit. Fara el,
       butonul lat isi lipea continutul la stanga — `inline-flex` nu citeste `text-align`, pe care
       `<button>` il are `center` din foaia browserului, deci trecerea `inline-block` -> `inline-flex`
       l-a pierdut tacut. Prins de sonda pe „Concurs nou" (2026-09-24): iconita „+" sarise 325px, de
       la mijlocul butonului la marginea lui. Pe telefon centrarea exista deja, din regula de tap
       (§16, `@media (max-width: 640px)`) — deci desktopul era singurul care nu se potrivea. */
    padding: .5rem 1.1rem; display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
    text-decoration: none; transition: none;
box-shadow: none; border-color: var(--sm-btn-fill); }
.btn-ink:hover { background: var(--sm-btn-fill-hover); border-color: var(--sm-btn-fill-hover); color: var(--sm-on-btn-fill); }
/* 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 { background: var(--btn-disabled-bg); color: var(--btn-disabled-fg); border-color: var(--btn-disabled-bg); cursor: progress; }
.btn-ink--ghost { background: var(--sm-quiet-fill); color: var(--sm-text-hi); }
.btn-ink--danger { background: var(--sm-danger); border-color: var(--sm-danger); color: var(--sm-on-danger); box-shadow: none; }
.btn-ink--danger:hover { background: var(--sm-danger-hover); border-color: var(--sm-danger-hover); color: var(--sm-on-danger); }

/* ---- BUTOANELE INK: venite din `kf-skin.css` la B159 L10 (F1; fișierul a fost șters la F4) ----
   Neprefixat, aceeasi specificitate ca regulile de baza → decide ordinea in text, exact
   precedenta pe care o dadea layerul inainte. */
  /* btn-ink (page/acct primary) → olive solid plat, hover invert instant */
  /* Regula `.btn-ink` a fost CONTOPITA cu cea de baza, mai sus — vezi motivul acolo. */
  /* `:hover` sters: skinul da si umplerea si cerneala starii. */
  .btn-ink.btn-xs { padding: .35rem .8rem; font-size: var(--font-xs); }
  /* Variantele semantice ale lui .btn-ink SUB skin (iter. 2d, feedback user: „culorile din modal
     sunt exact la fel"): .btn-ink (0,2,0) bătea .btn-ink--ghost/--danger (0,1,0), deci
     ghost-ul și danger-ul deveneau olive plin identic — inclusiv perechea OK/Anulează de pe
     paginile de confirmare. Regula casei: modifierul se scopează tot sub body.kf, același layer. */
  /* Starea dezactivata: `@layer app` n-o mai face din opacitate (o pata translucida peste umplere), dar regula
     de acolo e UMBRITA de `.btn-ink` din @layer components - deci fiecare lume isi scrie starea. */
  /* `:disabled` sters: skinul da toate trei (umplere, cerneala, culoarea ramei). */
  .btn-ink--ghost { border: 1px solid var(--kf-outline); box-shadow: inset 0 0 0 1px var(--sm-line); border-color: transparent; }
/* Coborata din `@layer skin` la B159 L10 (F2). */
.btn-ink--ghost:hover { background: color-mix(in srgb, var(--sm-text-hi) 12%, var(--sm-quiet-fill)); border-color: transparent; color: var(--sm-text-hi); box-shadow: inset 0 0 0 1px var(--sm-line); }
/* Coborata din `@layer skin` la B159 L10 (F2). */
.btn-ink--ghost:active { background: var(--sm-btn-press); border-color: transparent; color: var(--sm-on-btn-press); box-shadow: inset 0 0 0 1px var(--sm-btn-press-edge); }
  /* ⛔ ȘTERSE la B159 L10 (F2/F3): perechea INVERSĂ a butonului de pe banda finală a paginii de start.
     Erau ale paletei kf, acoperite de skin prin layer — nu se randau de mult. După coborârea skinului
     ar fi câștigat înapoi (aceeași specificitate ca `.btn-ink`, dar mai jos în fișier). */


/* ⚠️ CROM PARTAJAT CU ECRANUL JURATULUI. `confirm-action.js` CONSTRUIESTE modalul de confirmare din
   JS, deci `.brand-modal` + `.btn-ink` apar si la jurat, desi nu-s in niciun template de-al lui —
   verificat in `assets/js/confirm-action.js`, nu prin grep pe `templates/judge/`.
   Regulile de aici citesc tokeni de ROL (`--sm-btn-fill`, `--sm-on-btn-fill`, `--sm-line`…), iar
   fiecare lume si-i declara pe blocul ei: `tokens.css` da valorile JURATULUI pe `:root` (ambele lumi
   il incarca), `site-palette.css` le suprascrie pentru SITE (juratul nu-l incarca). Asa componenta
   are o SINGURA regula, neprefixata, corecta in amandoua.
   NU muta familia asta intr-o foaie de site si nu-i scrie valori literale: juratul ar ramane fie
   fara chrome, fie cu tokeni inexistenti — adica `unset`, nu valoarea veche. Greseala a fost facuta
   o data (B159 L10 F2, comitul 9631e89) si prinsa de auditul de contrast, trecerea `judge-rules`;
   de la F4 o pazeste si `StylesheetChainScopeTest`, care numara foile din `<head>`-ul juratului. */
/* Chrome de modal brand-uit (SSOT) — ramă 2px ink + offset shadow, titlu Archivo uppercase, în loc
   de cardul soft Bootstrap. Scopat pe `.brand-modal`, NU pe `.confirm-modal`: același chrome îl
   poartă și modalul de înscriere (`.enroll-modal`, components.css §12). Clasa de identitate rămâne
   pe fiecare modal în parte — `.confirm-modal` e și santinela pe care o citește judge-panel.js.
   Consumatori: confirm-action.js + form-dirty.js (confirmare), _enroll_modal.html.twig (înscriere). */
.brand-modal .modal-content {
    border: 1px solid var(--sm-line);
    border-radius: var(--radius-card, var(--radius-sm));
    box-shadow: var(--sm-elev-float);
    background: var(--sm-s1);
    color: var(--sm-text-hi);
}
.brand-modal .modal-header { border-bottom: 1px solid var(--sm-hair); padding: .6rem .9rem; }
.brand-modal .modal-title { font-family: var(--font-display, inherit); font-weight: var(--type-title-weight, 900); text-transform: var(--type-title-case, uppercase); letter-spacing: var(--type-title-tracking, .04em); font-size: var(--font-lg); }
.brand-modal .modal-body { padding: .9rem; }
.brand-modal .modal-footer { border-top: 0; padding: .6rem .9rem; gap: .5rem; }

/* Câmpurile MARI din modalul de confirmare (iter. 2g, confirm-action.js data-confirm-fields):
   cifrele-cheie (Runde/Cronometru) RE-apar editabile, cu stepper −/+ la mărime de deget
   (ținte ≥44px — ghidul touch), ca un organizator solo să vadă și să corecteze setările chiar
   în confirmare. Containerul e gol/ascuns (`hidden`) pentru toate celelalte confirmări. */
.cf-fields {
    display: flex;
    flex-wrap: wrap;                       /* aranjament fluid: pică unul câte unul */
    align-items: flex-start;               /* un câmp cu glosă e mai înalt — nu întinde vecinii */
    gap: clamp(.5rem, 3cqi, 1rem);
    padding: .9rem .9rem 0;
}
.cf-field { display: flex; flex-direction: column; align-items: flex-start; gap: .25rem; }
.cf-lbl {
    font-family: var(--font-display, inherit);
    font-weight: var(--type-label-weight, 900);
    text-transform: var(--type-label-case, uppercase);
    letter-spacing: var(--type-label-tracking, .06em);
    font-size: var(--font-xs);
    color: var(--fg2);
}
.cf-step { display: flex; border: 2px solid var(--border-strong); border-radius: var(--radius-sm); overflow: hidden; border-color: var(--sm-line); }
/* Glosa cifrei (data-echo-hint): ce ÎNSEAMNĂ numărul, sub stepperul lui. `max-width` în `ch` ca
   fraza să se rupă pe 2-3 rânduri scurte lângă cutie, nu să lățească modalul. */
.cf-hint { font-size: var(--font-xs); color: var(--text-secondary); line-height: 1.3; max-width: 26ch; }
.cf-btn {
    min-width: var(--tap-min);
    min-height: var(--tap-min);
    border: 0;
    background: var(--surface-2, var(--surface));
    color: var(--text);
    font-family: var(--font-mono);
    font-size: var(--font-xl);
    font-weight: 700;
    line-height: 1;
}
.cf-btn:active { background: var(--sm-btn-hover); color: var(--sm-on-btn-hover); }
.cf-in {
    width: 4.5em;
    min-height: var(--tap-min);
    border: 0;
    border-inline: 2px solid var(--border-strong);
    background: var(--surface);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: var(--font-xl);
    font-weight: 700;
    text-align: center;
    -moz-appearance: textfield;            /* săgețile native-s inutile lângă −/+ */
    appearance: textfield;
border-inline-color: var(--sm-line); }
.cf-in::-webkit-outer-spin-button,
.cf-in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cf-in:focus { outline: 2px solid var(--volt); outline-offset: -2px; outline-color: var(--sm-text-hi); }
/* CE urmează să pornească — identitatea categoriei, deasupra cifrelor (iter. 2m). Rundele n-au
   înțeles fără format: „2 runde" înseamnă altceva la 1v1 și altceva la 2v2, iar organizatorul are
   mai multe categorii deschise în aceeași seară. `hidden` îl ascunde reboot-ul Bootstrap (`!important`, @layer vendor):
   o regulă `.cf-ctx[hidden]` aici n-ar avea efect (ștearsă în B159 L0b 0.7). */
.cf-ctx {
    margin: 0;
    padding: .6rem .9rem 0;
    font-family: var(--font-display, inherit);
    font-weight: var(--type-label-weight, 900);
    text-transform: var(--type-label-case, uppercase);
    letter-spacing: var(--type-label-tracking, .06em);
    font-size: var(--font-sm);
    line-height: 1.2;
    color: var(--text);
}
/* Consecințele, la o PRIVIRE: puncte scurte sub o linie, nu proză (cerința userului, iter. 2m). */
.cf-points {
    margin: 0;
    padding: .55rem 0 0;
    border-top: 2px solid var(--border-strong);
    list-style: none;
    display: grid;
    gap: .3rem;
border-top-color: var(--sm-hair); }
.cf-points li { position: relative; padding-left: .85rem; font-size: var(--font-sm); line-height: 1.35; }
/* Pătrat, nu bulină: marcajul e din același vocabular brutalist ca restul chrome-ului. `currentColor`
   ține contrastul pe ambele teme fără o a doua definiție. */
.cf-points li::before {
    content: "";
    position: absolute;
    left: 0;
    top: .5em;
    width: 6px;
    height: 6px;
    background: currentColor;
    opacity: .55;
}

/* === 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: var(--type-control-weight, 900);
    text-transform: var(--type-control-case, uppercase);
    letter-spacing: var(--type-control-tracking, 0.06em);
    padding: 0.15rem 0.45rem;
    line-height: 1.4;
    border-radius: var(--radius-control, 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); }



/* --- Navbar pe telefon: cele 3 destinații rămân VIZIBILE (fără hamburger) ---------------------
   Navigația ascunsă taie descoperirea cu >20% și e cu ~15% mai lentă (NN/g; pe telefon: 57% folosire la cea ascunsă, 86%
   la cea combinată). Între 541 și 640px încape încă UN rând la 16px (eticheta „Contul meu" devine iconiță). */
@media (max-width: 640px) {
    :root { --nav-h: 52px; --nav-ctl-h: var(--tap-min); }
    .app-nav__inner { gap: 0.35rem; padding: 0 0.6rem; }
    .app-nav__brand { --brand-logo-h: 26px; }
    .app-nav__primary { gap: 0; }
    .app-nav__link { --nav-link-px: 0.5rem; }
    /* 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 540px un rând la 16px nu mai încape (cele trei etichete au 209px; măsurat: un rând ține până la ~532px anonim,
   ~509px logat) → DOUĂ rânduri CONSTANTE, tiparul BBC Sport / ESPN: rândul 1 = marca + contul, rândul 2 = trei taburi
   egale pe toată lățimea, cu indicatorul pe marginea de jos. Aceeași înălțime pentru toți → `--nav-h` e adevărat (înainte
   bara se rupea pe două rânduri doar la unele lățimi și doar pentru unii, iar lipicioasele intrau sub ea — B205).
   ⚠️ `44px` scris în proprietatea custom, nu `var(--tap-min)`: un `--nav-h` derivat din podeaua de atingere ar face din
   el un token de țintă, iar garda podelelor (`SitePaletteCssScopeTest`) l-ar acuza la fiecare consumator (top-ul lipicios). */
@media (max-width: 540px) {
    :root { --nav-row-h: 52px; --nav-h: calc(var(--nav-row-h) + 44px); }
    .app-nav__inner { height: auto; flex-wrap: wrap; gap: 0 0.35rem; }
    .app-nav__brand { min-height: var(--nav-row-h); }
    .app-nav__primary { order: 3; flex: 1 0 100%; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-inline: -0.6rem; }
    /* Eticheta centrată în treimea ei; cu fontul mărit de om (125%) nu iese din coloană — se termină în „…", nu e tăiată
       tăcut (fără `min-width: 0` pagina derula lateral). Bloc, nu flex: `text-overflow` nu prinde textul unui container flex. */
    .app-nav__primary > li { justify-content: center; }
    .app-nav__primary > li > .app-nav__link { --nav-link-px: 0.75rem; display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; text-align: center; height: var(--tap-min); line-height: var(--tap-min); }
}
/* Sub 420px lockup-ul colapsează la wordmark — pattern standard (marca împarte rândul 1 al barei cu contul și tema).
   Comutarea imaginii se face în components.css („Semnul de brand"), pe `.brand-logo--responsive`; aici rămâne doar înălțimea. */
@media (max-width: 420px) {
    .app-nav__brand { --brand-logo-h: 22px; }
}

/* --- 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`. */
    /* `.role-tab`: banda de tab-uri (admin + clasament) e RAIL pe telefon, deci tab-urile se apasă
       cu degetul, nu se citesc doar. Fără asta rămâneau la ~30px, sub pragul WCAG 2.5.5. */
    .btn, .btn-ink, .filter-pill, .badge-category, .role-tab { min-height: var(--tap-min); }
    /* Marcaj STERS la B159 L10 F1 ca ORFAN: justifica o umbra data de `body.kf`, iar regulile
       de buton si de tab au coborat in acelasi layer. Pe cele trei pagini fara clasa
       (Concurs nou, editare, confirmare) butoanele primesc de acum acelasi aspect ca in rest —
       decizia ownerului din 2026-09-23. */
    .btn, .btn-ink, .role-tab { display: inline-flex; align-items: center; justify-content: center; }
    /* Linia de comandă a organizatorului (iter. 2n, cererea userului: „extrem de mari pe mobil").
       Pastile de 44px cu literă de 8px arătau absurd și împingeau rândul pe 3-4 linii. Pragul se
       alege pe criteriul VERIFICABIL din „Ținte touch", nu pe cât de „importantă" pare acțiunea:
       a treia condiție cere ca apăsarea greșită să se anuleze dintr-un tap — iar un buton cu
       `data-confirm` o îndeplinește prin construcție (tapul greșit deschide doar un dialog).
       Deci: coboară la podeaua AA tot ce e ajutător (Recalculează, Anulează, Cheamă, Ecran,
       cronometru — conturate sau neutre, fiecare ori confirmat, ori fără consecință)… */
    .tab-actions .btn { min-height: var(--tap-aa); }
    /* …și rămâne la 44px ce SCHIMBĂ starea concursului: butoanele COLORATE (Start, Decizie, Rezolvă,
       Bracket, Pregătește, Închide). Criteriul e clasa de rol, nu prezența confirmării, ca butonul
       să nu-și schimbe înălțimea de la un start la altul (`data-confirm` pe Start apare doar la
       primul din fază). În practică e cel mult UNUL pe ecran deodată, deci rândul nu se umflă. */
    .tab-actions .btn-warning,
    .tab-actions .btn-success,
    .tab-actions .btn-danger { min-height: var(--tap-min); }
    /* × de ștergere a unui rând de jurat / staff: podeaua de mai sus e doar pe ÎNĂLȚIME, iar butonul e cât o
       singură glifă, deci LĂȚIMEA decide. Măsurat în B159 L6b: 24.5px înainte de skin, 23.5px după (skinul scoate
       majusculele și tracking-ul de pe controale, deci glifa ocupă mai puțin) — adică sub pragul AA de 24×24.
       Ștergerea unui rând NEsalvat e reversibilă dintr-un tap (îl adaugi la loc), deci podeaua e --tap-aa. */
    .judge-inline-row .btn-xs,
    .staff-inline-row .btn-xs { min-width: var(--tap-aa); }
    /* × de închidere a categoriei: Bootstrap îi dă 16px, prea mic pentru deget. Nu mai are nevoie
       de rezervă de padding pe rând — de la B144 stă în antet, nu absolut peste câmpuri. */
    .category-row__hdr > .btn-close { min-width: var(--tap-min); min-height: var(--tap-min); }
    /* Roster-ul organizatorului (B225): ✓ / ★ / × = ținte de 44px pe telefon. Podeaua stă DOAR pe cele trei controale
       (SitePaletteCssScopeTest); coloanele rândului sunt `auto`, deci urmează controalele — tot fixe, fiindcă și ele sunt. Căsuța ✓
       rămâne desenată mică în celula ei (ținta e celula). */
    .roster__row { grid-template-columns: auto minmax(0, 1fr) auto auto; gap: 0; }
    .roster__present, .roster__inv, .roster__del { min-width: var(--tap-min); min-height: var(--tap-min); }
    /* 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(--sm-text-mid); text-transform: var(--type-label-case, uppercase); letter-spacing: var(--type-label-tracking, .05em); padding: .2rem .6rem; font-weight: 600; }
.col-rank-narrow { width: 1.8rem; font-weight: 700; }

/* Numărul de runde de sub eticheta fazei — urmează scala bracketului (`--bk-u`, scoreboard.css). */
.bk-col-count { font-size: clamp(var(--font-4xs), calc(var(--bk-u, 12rem) * .052), var(--font-3xs)); font-weight: 400; opacity: 1; color: var(--sm-text-mid); }
.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 */

/* Familia `.dup-warn*` a PLECAT in components.css la B159 L10 (F2): e construita din JS de
   `entry_autocomplete_controller.js`, deci apare DOAR pe formularul de inscriere de pe site.
   Fisierul asta e incarcat si de ecranul juratului, unde tokenii `--sm-*` nu exista — iar
   auditul de contrast masoara pe FISIER, nu pe ce se randeaza acolo. */

/* 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(--sm-hair); border-radius: var(--radius-sm);
    background: transparent;
}
.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; }

/* Informarea art. 13 + clickwrapul, deasupra butonului de înscriere (doar formularul PUBLIC).
   Stă lângă familia `.enf-*` deși e text, nu câmp: coeziunea de familie bate euristica pe audiență
   de fișier — următorul om o caută unde stau frații ei.
   Discret, dar NU sub --font-xs: e informare obligatorie, nu subsol de amănunte. Linia hairline de
   sus o separă de câmpuri fără să adauge un card. */
.enf-legal {
    margin: .75rem 0 .25rem; padding-top: .6rem;
    border-top: 1px solid var(--border-hair);
    font-size: var(--font-xs); line-height: 1.5; color: var(--text-muted);
}
.enf-legal p { margin: 0 0 .35rem; }
.enf-legal p:last-child { margin-bottom: 0; }
.enf-legal__wrap { font-weight: 600; color: var(--fg3); }
.enf-legal a { color: var(--accent); }

/* 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 {
    /* Gutterele laterale fluide pe telefon; min stânga 1rem ține cifra __num (absolut la .3rem,
       o cifră — formatele merg până la 4-8 membri) fără suprapunere. */
    position: relative; border-radius: var(--radius-sm);
    padding: .3rem clamp(.4rem, 8vw - 1.5rem, 1.6rem) .3rem clamp(1rem, 6vw - .5rem, 1.5rem);
    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); }
/* Blocul care ARE buton de retragere (doar membrii opționali) își păstrează tot gutterul drept:
   ×-ul e țintă de atingere pe o acțiune destructivă — nu-l micșorăm și nu lăsăm inputurile sub el. */
.member-block:has(> .member-block__del) { padding-right: 1.6rem; }

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


/* === 17. HOME (landing) + page heads — Battle-Broadcast ===== */

/* ---- LANDING / HERO: venit din `kf-skin.css` la B159 L10 (F1; fișierul a fost șters la F4) ----
   Neprefixat, aceeasi specificitate ca regulile de baza → decide ordinea in text, exact
   precedenta pe care o dadea layerul inainte. */
  /* === LANDING `/` — Kinetic Sharp (flat, hairline, display Black) ============ */
  /* B214: hero-ul stă pe suprafața paginii, fără ramă și fără fundal de card — ușile sunt cardurile. B234 (Arena): imaginea în
     fundal (`.home-hero__bg` + degradeul `::after`, în `components.css`, foaie doar de site). Eroul stă în COLOANA paginii, nu pe
     toată lățimea ferestrei (runda 2, ownerul: la zoom mic eroul ieșea pe 7680px și ușile ieșeau din vedere — conținutul era tăiat
     la marginea containerului). `overflow: hidden` + colțul de card taie imaginea; `isolation` ține fundalul sub conținut. */
  .home-hero {
    position: relative; isolation: isolate; overflow: hidden; border-radius: var(--radius-card, 0);
    padding: clamp(5rem, 3rem + 8cqi, 9.5rem) clamp(1rem, 4cqi, 2.5rem) clamp(2.5rem, 2rem + 2cqi, 4rem);
    text-align: left; margin: 0 0 var(--kf-4);
  }
  .home-hero__title {
    font-family: var(--kf-font-display); font-weight: var(--type-display-weight, 900);
    text-transform: var(--type-display-case, uppercase); letter-spacing: var(--type-display-tracking, .01em);
    color: var(--kf-text);
  }
  .home-hero__tag { color: var(--kf-text-variant); }

/* Marcaj STERS la B159 L10 F1 ca ORFAN: apara o diferenta care are acum nume propriu —
   `.page-head--form` de mai jos. */
/* Contopita cu regula kf la B159 L10 (F1). B234 (Arena): titlul de AFIȘ — condensat (`--ar-wdth`, doar pe site; juratul n-are
   tokenul și rămâne la 100%), fluid din container (`cqi`; fără container = ecranul), rânduri strânse. */
.page-head {
    font-family: var(--font-display); font-weight: var(--type-display-weight, 900); font-stretch: var(--ar-wdth, 100%);
    text-transform: var(--type-display-case, uppercase); letter-spacing: var(--type-display-tracking, .01em);
    font-size: clamp(2.5rem, 1rem + 5cqi, 5.5rem); line-height: .9; color: var(--text); margin: 0;
    display: inline-flex; align-items: center;
}
/* Capul MIC, pentru ecranele de LUCRU: „Concurs nou", editarea concursului si pagina de confirmare.
   Pana la B159 L10 diferenta exista din ACCIDENT — paginile alea nu primeau clasa `kf`, deci luau
   regula de baza (3xl). Decizia ownerului (2026-09-23): diferenta ramane, dar DECLARATA, nu
   accidentala — un formular lung n-are de ce sa piarda inaltime utila pe un titlu de 40px. */
.page-head--form { font-size: var(--font-3xl); line-height: 1.1; letter-spacing: var(--type-display-tracking, .02em); }

/* --- 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 { display: inline-flex; align-items: center; min-height: var(--tap-aa); color: var(--text-muted); text-decoration: none; }  /* B212.3: 18px → podeaua WCAG 2.5.8 */
.breadcrumbs a:hover { color: var(--accent); }
.breadcrumbs__sep { color: var(--text-faint); }
.breadcrumbs__current { color: var(--text); font-weight: var(--type-label-weight, 700); }

.page-state {
    display: inline-flex; align-items: center; gap: .4rem; vertical-align: middle;
    font-family: var(--font-display); font-weight: var(--type-status-weight, 900); font-size: var(--font-sm);
    text-transform: var(--type-status-case, uppercase); letter-spacing: var(--type-status-tracking, .08em);
    padding: .2rem .65rem; border-radius: var(--sm-r-pill);
}
.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 3;
}
@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 .app-footer,
.live-projector .breadcrumbs { display: none; }

/* --- Arhivă publică (/arhiva) -------------------------------------------------------------
   Lista = RÂNDUL DE CONCURS de pe /concursuri (`_contest_list_item`, modul `archive`, B204 / ADR 0058): regulile lui stau în
   components.css (`.cl*`, `.crow__*`). Aici rămân doar piesele ARHIVEI: toolbar-ul, saltul la an, titlul de an lipicios, golul. */
.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. */
/* B234 (Arena): tipografia titlului de an = a lunii de pe /concursuri — o regulă comună (`.cl-section__h, .arch-year`) în
   `components.css`, foaie doar de site; aici rămâne lipirea + fundalul opac. Înălțimea fixă (offsetul șinei lipicioase a datei) a
   plecat odată cu șina. */
.arch-year {
    position: sticky; top: var(--nav-h); z-index: 5;
    /* Venit din kf la B159 L10 (F1). `--bg` nu e in blocul de remap al skinului (doar `--kf-bg` e
       fundalul paginii), deci fara linia asta antetul lipicios ar avea alta nuanta decat pagina si
       s-ar vedea o dunga la derulare. */
    background: var(--kf-bg);
}
.arch-year-block { scroll-margin-top: calc(var(--nav-h) + var(--kf-3)); }

/* „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; }
/* --- Pagina de start (ADR 0053; it. 6 = B214, 2026-10-02 — aranjarea B aprobată pe datele reale,
   https://claude.ai/artifact/UJrRYxZWGFeS6J8XmGjH27). `.home` = CONTAINERUL paginii: hero-ul și ușile își iau coloanele din el
   (`@container`, nu `@media`); lista de concursuri are containerul ei, `.cl` (blocul de dată și miniaturile, ca pe /concursuri).
   Modalele de înscriere stau în AFARA lui (containment-ul ar captura `position: fixed`).
   REUSE-FIRST: rândurile de concurs = `_contest_list_item` (compact), mini-cărțile = `.cl-cat`, data = `.crow__date`, avatarul =
   `.avatar` (+ `.avatar-stack`), butoanele `.btn-ink`, contorul din capete `.filter-pill__n`. Aici stau DOAR blocurile paginii.
   Culoarea vine din CONȚINUT (afișe, nuanțele stilurilor, avatare) — fără benzi gri, fără rame decorative (cast-ui §3).
   ⚠️ Foaia asta e împărțită cu JURATUL: suprafețele cardurilor (fundal + umbră + cerneală) stau în blocul „VALORI DE SITE" din
   components.css — aici doar geometria (o regulă de aici le-ar bate: base-layout se încarcă DUPĂ components).
   Tipografia de etichetă NU se scrie aici: `.home-stats__l` e în lista rolului ETICHETĂ (components.css §18b). `.home-door__lbl` a ieșit
   din ea la B234 (Arena): numele ușii e titlu de afiș, scris mai jos, lângă geometria ușii. --- */
.home { container-type: inline-size; }

/* h1 = SEMNUL (alt = numele) + restul tagline-ului („your move."): textul accesibil e tagline-ul întreg, pe ecran numele e semnul.
   Slotul semnului ia mărimea din --brand-logo-h. B214 (ownerul): aliniat la STÂNGA, ca restul paginii și /concursuri — centrarea din
   it. 5 a plecat. `gap: 0`: PNG-ul e tăiat exact pe cerneală, spațiul vizibil vine din jumătatea de leading a lui `line-height: 1`. */
.home-hero__title { display: flex; flex-direction: column; align-items: flex-start; gap: 0; margin: 0 0 .6rem; }
.home-hero__mark { --brand-logo-h: clamp(64px, 11vw, 124px); line-height: 1; }
.home-hero__words {
    font-family: var(--font-display); font-weight: var(--type-display-weight, 900); text-transform: var(--type-display-case, uppercase); letter-spacing: var(--type-display-tracking, .015em);
    /* B234 (Arena): „YOUR MOVE." = afișul paginii — condensat, uriaș, rânduri lipite. */
    font-stretch: var(--ar-wdth, 100%); font-size: clamp(3.5rem, 1rem + 11cqi, 12rem); line-height: .84; color: var(--text);
}
.home-hero__tag { font-size: var(--font-md); max-width: 38rem; margin: 0; }

/* Hero pe DOUĂ coloane: promisiunea stânga, ușile dreapta; sub 52rem o coloană, ușile sub text. Pe SUPRAFAȚA PAGINII — ușile
   sunt cardurile (un card în card ar fi ramă decorativă). */
.home-hero { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: clamp(1rem, 4vw, 2.5rem); align-items: center; }
.home-hero__text { min-width: 0; }
@container (max-width: 52rem) {
    .home-hero { grid-template-columns: minmax(0, 1fr); }
}

/* CELE TREI UȘI (`home/_doors`): conținut real în fiecare, acțiunea JOS, la aceeași înălțime (rândul grilei le întinde egal, iar
   `margin-top: auto` coboară butonul). TREI pe un rând lângă text, UNA sub alta când hero-ul e pe o coloană (prototipul aprobat;
   `auto-fit` lăsa 2 + 1 — Organizezi singură pe jumătate de rând — pe telefoanele de 390-480px și la 864-1066px: la un set FIX de
   elemente egale, orfanul e defectul, nu curgerea — decizia ownerului 2026-10-02, UI_RULES „Aranjament FLUID"). Dansezi + Urmărești =
   link întins peste casetă (`.home-door__go::after`, regula din components.css); Organizezi are două acțiuni, deci nu.
   ⚠️ Blocul `@container` care le pune pe o coloană stă DUPĂ `.home-two` (același layer, aceeași specificitate: ordinea decide). */
.home-doors { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem; min-width: 0; }
/* B234 (Arena): ușa e CONTAINER — numele ei (DANSEZI / URMĂREȘTI / ORGANIZEZI) e titlu de afiș cât îl lasă ușa (`cqi`), cu iconița
   deasupra, nu alături: lângă iconiță numele încăpea doar pe ecran lat. */
.home-door {
    position: relative; container-type: inline-size; display: flex; flex-direction: column; gap: .6rem; min-width: 0; padding: .9rem;
    border-radius: var(--radius-card, 0);
}
.home-door__lbl {
    display: inline-flex; flex-direction: column; align-items: flex-start; gap: .4rem; min-inline-size: 0; max-inline-size: 100%;
    font-family: var(--font-display); font-weight: 900; font-stretch: var(--ar-wdth, 100%); text-transform: uppercase; letter-spacing: -.005em;
    font-size: clamp(1.3rem, 14.5cqi, 3rem); line-height: .9; color: var(--text-secondary);
}
.home-door__ico { display: inline-grid; place-items: center; flex: none; width: 2rem; height: 2rem; border-radius: var(--radius-sm); font-size: var(--font-md); }
.home-door__h { margin: 0; font-size: var(--font-lg); font-weight: 900; font-stretch: var(--ar-wdth, 100%); text-transform: uppercase; letter-spacing: -.005em; line-height: 1.2; color: var(--text); }
.home-door__row { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .55rem; margin: 0; }
.home-door__body { margin: 0; font-size: var(--font-sm); color: var(--text-secondary); }
.home-door > .home-door__btn, .home-door__actions { margin-top: auto; }
.home-door__btn { justify-content: center; }
.home-door__actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.home-door__actions .home-door__btn { flex: 1 1 auto; }
@media (hover: hover) {
    .home-door:has(.home-door__go):hover .home-door__h { text-decoration: underline; text-underline-offset: .16em; }
}

/* Capul de secțiune: TITLU (ADR 0054 decizia 7 — secțiunea ESTE conținutul căutat) + „mai mult" pe aceeași riglă; pe îngust cad
   unul sub altul. Rețeta de text stă AICI, ca la `.home-cta-band__t`. „Toate … →" = LINK TEXT (convenția „View all": nu stă într-un
   paragraf, deci sublinierea apare doar la hover — WCAG 1.4.1 privește linkurile din text), cu ținta de 24px (WCAG 2.5.8). */
.home-sec { margin: clamp(1.2rem, 4vw, 2rem) 0 0; min-width: 0; }
/* Fără linie sub cap (ownerul, 2026-10-03: „la celelalte pagini e scoasă" — titlul violet + aerul de sub el despart deja secțiunile;
   era singurul consumator al tokenului `--border-dark`, șters odată cu ea). */
.home-sec__head {
    display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: .5rem 1rem;
    margin-bottom: .8rem;
}
/* B234 (Arena): capul de secțiune = titlu de afiș, condensat, pe identitate; contorul curge în rând (bloc, nu flex). */
.home-sec__h {
    font-family: var(--font-display); font-weight: var(--type-title-weight, 900); text-transform: var(--type-title-case, uppercase); letter-spacing: var(--type-title-tracking, .02em);
    font-stretch: var(--ar-wdth, 100%); font-size: clamp(1.9rem, 1rem + 2.6cqi, 2.9rem); line-height: .95;
    /* G1 (ADR 0057): titlul de zonă pe identitate. Fallback-ul e pentru lumea JURATULUI, care încarcă și foaia asta, dar nu paleta
       site-ului (fără `--title-accent`). */
    margin: 0; color: var(--title-accent, var(--text-secondary)); display: block;
}
.home-sec__sub { color: var(--text); }
/* Contorul din cap NU-și scrie fontul nicăieri (components.css îi dă doar cifre tabulare + stingere): rămâne o cifră de context. */
.home-sec__h .filter-pill__n { font-family: var(--font-mono); font-weight: 700; font-size: var(--font-sm); }
.home-sec__more { display: inline-flex; align-items: center; gap: .35rem; min-height: var(--tap-aa); font-size: var(--font-sm); font-weight: 700; color: var(--text); text-decoration: none; }
@media (hover: hover) {
    .home-sec__more:hover { text-decoration: underline; text-underline-offset: .2em; }
}
.home-sec__empty { margin: 0; font-size: var(--font-sm); color: var(--text-secondary); }
.home-sec__empty a { color: var(--text); }

/* CONCURSUL SCOS ÎN FAȚĂ (`home/_featured_contest`): afișul întreg stânga, textul dreapta; pe îngust afișul sus. Mini-cărțile sunt
   `.cl-cat` (treapta tonală cardul concursului → cartea categoriei, ca pe /concursuri). */
.home-feat {
    display: grid; gap: var(--kf-4); padding: clamp(.75rem, 2.5cqi, 1.1rem);
    border-radius: var(--radius-card, 0);
}
@container (min-width: 46rem) {
    .home-feat { grid-template-columns: minmax(12rem, 16rem) minmax(0, 1fr); align-items: start; }
}
.home-feat__body { display: flex; flex-direction: column; gap: var(--kf-4); min-width: 0; }
.home-feat__head { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .25rem .9rem; align-items: start; }
/* Mini-cărțile: piste de 14rem cu `auto-fill` și 10px între ele — EXACT grila prototipului (`.feat__cats`); cu 13rem la 1024px apărea o
   a treia pistă goală, iar la 768 cărțile stăteau două pe rând unde prototipul le pune una sub alta. */
.home-feat__cats { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr)); gap: .625rem; }
.home-feat__cat { gap: .6rem; }
.home-feat__jury { margin: 0; }
/* Rândul contorului: „Înscriși N" (+ „Niciun înscris încă") într-o coloană a lui (`.home-feat__n`), butonul COMPACT la dreapta —
   prototipul aprobat (azi butonul umplea cardul: 226px pe telefon). `margin-inline-start: auto` îl ține la dreapta și când rândul se
   frânge; fără învelitoare, textul de gol ar fi al 3-lea copil al unui `space-between` și ar pluti la mijloc. */
.home-feat__foot { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; }
.home-feat__n { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.home-feat__foot .cl-cat__btn { width: auto; flex: 0 0 auto; margin-inline-start: auto; }
/* Pe /concursuri TOT `.cl-cat__foot` stă deasupra linkului întins al cărții (ține lista de înscriși + butoane). Aici rândul are doar
   contorul și butonul compact: ridicat întreg, ar lăsa 25% din card ZONĂ MOARTĂ (măsurat la 360) — se ridică DOAR butonul. Specificitate
   (0,2,0) peste `.cl-cat__foot` din components.css, nu ordinea fișierelor. */
.home-feat .home-feat__foot { position: static; z-index: auto; }
.home-feat__foot .cl-cat__btn { position: relative; z-index: 1; }

/* CONTOARELE — pe suprafața paginii, între fire (B214: banda gri / inversă a plecat). GRILĂ de 4 egale, 2 × 2 sub 30rem, cifra și
   eticheta centrate (prototipul aprobat). Curgerea fluidă lăsa al patrulea contor singur pe rândul doi pe ORICE telefon 320-480px:
   la un set FIX de cifre egale, grila echilibrată bate regula „pică unul câte unul" (decizia ownerului 2026-10-02, UI_RULES
   „Aranjament FLUID"). Eticheta se poate frânge pe 2 rânduri (la 320 și în banda 560-680 — ca în prototip). Cifra în mono tabular;
   eticheta = rolul ETICHETĂ (components.css §18b). */
.home-stats {
    list-style: none; margin: clamp(1.2rem, 4vw, 2rem) 0 0; padding: clamp(.8rem, 2.5vw, 1.2rem) 0;
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem .75rem;
    border-block: 1px solid var(--border-hair); color: var(--text);
}
.home-stats__it { display: flex; flex-direction: column; align-items: center; text-align: center; min-width: 0; }
/* B234 (Arena): cifrele = afiș — condensate, 900, uriașe. */
.home-stats__v {
    font-family: var(--font-display); font-weight: 900; font-stretch: var(--ar-wdth, 100%); text-transform: uppercase; letter-spacing: -.005em; font-variant-numeric: tabular-nums;
    font-size: clamp(3rem, 1.5rem + 5cqi, 6.5rem); line-height: .85; color: inherit;
}
.home-stats__l { color: var(--text-secondary); margin-top: .3rem; }
@container (max-width: 30rem) {
    .home-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 1.1rem; }
}

/* ARHIVA: rândurile au blocul de dată de pe /concursuri (cu ANUL), apoi numele + orașul · nivelul. Fiecare rând e un CARD separat
   (suprafața + umbra în components.css, lista „PRIMA PAGINĂ"), de aceeași înălțime minimă ca rândul top 3 de alături — în prototip
   cele două liste stau una lângă alta cu rânduri egale. Mărimea zilei din token: blocul stă în afara `.cl`, iar `cqi` s-ar măsura
   pe toată pagina. */
.home-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.home-list__row {
    position: relative; display: flex; align-items: center; gap: .9rem; padding: .6rem .85rem;
    min-block-size: var(--home-row-min, 0); border-radius: var(--radius-card, 0);
}
.home-list .crow__date { min-width: 3.25rem; }
.home-list .crow__day { font-size: var(--font-xl); }
.home-list__txt { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.home-list__cat { display: inline-flex; align-items: center; min-height: var(--tap-aa); min-width: 0; color: inherit; text-decoration: none; }
/* TOT rândul e ținta (link întins, ca ușile / cardurile de categorie): numele singur avea 20px — sub minimul WCAG 2.5.8 (24px). */
.home-list__cat::after { content: ""; position: absolute; inset: 0; }
.home-list__cat:hover .home-list__name, .home-list__cat.home-list__name:hover { text-decoration: underline; }
.home-list__name { font-weight: 700; font-size: var(--font-md); color: var(--text); overflow-wrap: anywhere; }
.home-list__sub { font-family: var(--font-mono); font-size: var(--font-xs); color: var(--text-secondary); }

/* Clasament | arhivă: 1.3 : 1 peste 52rem (prototipul aprobat), una sub alta dedesubt — același prag ca hero-ul. Când există doar
   una din ele (fără clasament la pornire), ocupă tot rândul (`:only-child`), nu 56% cu o coloană goală. `--home-row-min` = înălțimea
   comună a rândului de top 3 (components.css § clasament) și a rândului arhivei: o valoare, un loc. */
.home-two { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 0 1.5rem; --home-row-min: 4.25rem; }
.home-two > :only-child { grid-column: 1 / -1; }
/* ⚠️ DUPĂ `.home-doors` și `.home-two`: aceeași specificitate, același layer — ordinea în text decide (blocul de la hero e ÎNAINTEA
   lor și n-ar avea niciun efect aici). */
@container (max-width: 52rem) {
    .home-doors, .home-two { grid-template-columns: minmax(0, 1fr); }
}

/* Banda finală (Serial Position: ultimul lucru citit) — pe suprafața de CARD (B214: nu mai e inversă / gri), cu singurul buton
   plin al zonei ei. */
.home-cta-band {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem 1.5rem;
    margin: clamp(1.5rem, 5vw, 2.5rem) 0 1rem; padding: clamp(1rem, 3vw, 1.6rem) clamp(1rem, 4vw, 2rem);
    border-radius: var(--radius-card, 0);
}
.home-cta-band__t {
    font-family: var(--font-display); font-weight: var(--type-title-weight, 900); font-stretch: var(--ar-wdth, 100%); text-transform: var(--type-title-case, uppercase); letter-spacing: var(--type-title-tracking, .02em);
    font-size: clamp(var(--font-lg), 3vw, var(--font-2xl)); line-height: 1.1; margin: 0;
}
.home-cta-band__s { margin: .2rem 0 0; font-size: var(--font-sm); color: var(--text-secondary); }
/* ⛔ ȘTERSE la B159 L10 (F3), din același motiv: culoarea ramei vine de la `.btn-ink`. */



} /* 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 intră în coliziune cu shorthand-urile de box-shadow deja folosite pe
     câmpuri. ⚠️ Inelul E tăiat de `overflow: hidden` al unui STRĂMOȘ (offsetul de 2px iese din cutie) — un
     control lipit de marginea unui panou cu `overflow: hidden` cere aer (ex. `.smoke-log__summary`). `--focus-ring` era token MORT. */
  :focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
  }

  /* Sticla barei (ADR 0054, Decizia 5) a PLECAT la B188: barele translucide dau „low contrast ratios" (NN/g „Sticky
     Headers"; violetul pe sticlă coborâse la 4.36:1). Linkurile din bară au toată înălțimea ei: inelul de 2px cu offset
     de 2px ar ieși din bară (sus, sub marginea ecranului) → ÎNĂUNTRU. Stă aici, în `base`, lângă inelul global — din
     `app` ar pierde în fața lui. */
  .app-nav__link:focus-visible { outline-offset: -4px; }
  /* B216.2: linkurile ÎNTINSE își poartă inelul pe tot cardul (`components.css`, `:has(…:focus-visible)`); aici se stinge cel de pe
     controlul din interior, ca să nu fie două. Tot în `base`: din `app` ar pierde în fața inelului global. */
  .cl-cat__stretch:focus-visible, .home-door__go:focus-visible,
  .cl-contest--compact .crow__title a:focus-visible, .home-list__cat:focus-visible { outline: none; }

  /* Partea din garda de miscare a carei regula de baza traieste in fisierul asta: punctul de stare al
     paginii. Coborata din `@layer skin` la B159 L10 (F2). */
  @media (prefers-reduced-motion: reduce) {
    .page-state__dot { animation: none; }
  }

/* Coborata din `@layer skin` la B159 L10 (F2). */
.form-check-input:focus { border-color: var(--sm-text-hi); box-shadow: 0 0 0 .25rem color-mix(in srgb, var(--sm-text-hi) 22%, transparent); }
/* Coborata din `@layer skin` la B159 L10 (F2). */
.form-check-input:checked { background-color: var(--sm-switch-on); border-color: var(--sm-text-hi); }}
