/* ============================================================
   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).
   admin.css - S11 ADMIN + S11b CONTEST EDIT (/cont/{id}/edit).
   (Flash toasts au fost mutate in base-layout.css - chrome partajat.)
   ============================================================ */
@layer vendor, app, tokens, base, layout, components, utilities;

@layer app {
/* === 11. ADMIN ============================================= */

.admin-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 0.75rem; align-items: start;
}
/* Dashboardul pe taburi folosește doar c3/c12 + o1..o3 (c6/o4/o5 șterse la auditul 2026-08-06). */
.admin-section--c3  { grid-column: span 3; }
.admin-section--c12 { grid-column: span 12; }
.admin-section--o1 { order: 1; }
.admin-section--o2 { order: 2; }
.admin-section--o3 { order: 3; }
@media (max-width: 992px) {
    .admin-section--c3, .admin-section--c12 { grid-column: 1 / -1; }
}
/* FOST `overflow: hidden`. Justificarea („taie colțurile la rază") murise: remapul global
   nelayered din tokens.css pune `--radius-lg: 0` pe ORICE pagină. Ce mai făcea regula era să
   ÎNGHITĂ tăcut orice depășea secțiunea, fără bară de scroll și fără nicio cale de a ajunge la
   conținut — mecanismul din spatele raportului „pe mobil lipsesc părți de informații" (tabelul de
   dansatori pierdea coloanele 5-8, cardul de sistem își pierdea butoanele de acțiune).
   Depășirea se rezolvă acum la SURSĂ (grila de sisteme cu `min()`, tabelele cu container propriu
   de derulare); dacă mai reapare vreodată, trebuie să se VADĂ, nu să dispară.
   ⚠️ `min-width: 0` e OBLIGATORIU odată cu ștergerea: secțiunea e item de grilă în `.admin-grid`,
   iar minimul automat al unui item de grilă e min-content. `overflow` îl ținea la 0 ca efect
   secundar; fără el, un copil lat ar lăți pista și ar da scroll orizontal pe TOATĂ pagina. */
.admin-section {
    border: 2px solid var(--border-strong);
    border-radius: var(--radius-lg);
    min-width: 0;
background: var(--sm-card-surface); border-color: var(--sm-card-edge); border-width: 1px; }
.admin-section__header {
    font-family: var(--font-display);
    font-size: var(--font-xs); font-weight: var(--type-label-weight, 900); text-transform: var(--type-label-case, uppercase);
    letter-spacing: var(--type-label-tracking, 0.1em);
    padding: 0.4rem 0.6rem;
    /* `color: var(--fg1)` era scris AICI si nu s-a randat niciodata: randul de mai jos il rescrie.
       Sters la B179 (gasit de `css-hygiene.php`, preexistent rollout-ului de skin). */
    background: var(--sm-strip-surface); color: var(--sm-text-hi);
    border-bottom: var(--border);
border-bottom-color: var(--sm-hair); }
/* Coltul unui container rotunjit fara `overflow: hidden`: copilul care PICTEAZA acopera curba
   parintelui, deci rama pare rupta la capat. `overflow: hidden` NU e o optiune aici — a fost
   sters dinadins, cu motive masurate. Raza se da COPILULUI, pe latura pe care o atinge;
   `inherit` ia chiar raza parintelui, deci merge in orice lume (0 la jurat, raza cardului pe
   site) si nu trebuie rescrisa cand se schimba un token. Acelasi tipar ca `.form-panel__head`
   (components.css), aplicat prima oara la B159 L6b. Garda: `probe.py corners`. */
.admin-section > :first-child { border-start-start-radius: inherit; border-start-end-radius: inherit; }
/* Ultimul copil poate fi un rand (`.admin-item`, pictat) sau `.table-responsive`, care nu picteaza
   dar CLIPEAZA (`overflow-x: auto`) — raza pe el rotunjeste clipul, deci acelasi selector acopera
   ambele cazuri. Pe light coltul de jos e invizibil (`--card` = fundalul cardului); pe dark se vede. */
.admin-section > :last-child { border-end-start-radius: inherit; border-end-end-radius: inherit; }
/* `opacity` pe TEXT a ieșit peste tot în B159 (ea stinge și contrastul, și nu se poate tematiza):
   explicația de pe bara de antet citește rolul „mid pe suprafață inversă", cu perechea plină ca fallback. */
.admin-section__hint { font-size: var(--font-xs); font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--text-on-inverse-mid, var(--text-on-inverse)); margin-left: 0.4rem; }

/* `flex-wrap` + `min-width: 0`: un nume lung (stil de dans, format, rol) împingea clusterul de
   acțiuni în afara rândului, iar pe telefon butonul de ștergere ajungea în afara ecranului. Wrapul
   e progresiv — rândul se rupe DOAR când chiar nu încape, nu la un prag fix. */
.admin-item {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 0.35rem;
    padding: 0.3rem 0.6rem; font-size: var(--font-md);
    border-bottom: 1px solid var(--border-hair);
    background: var(--card);
}
.admin-item > * { min-width: 0; }

/* ── Rând de CONTOPIRE (dansatori, crew-uri): etichetă · sursă → țintă · buton ──────────────────
   Înainte cele două selecturi purtau `.w-in-md`, care la ≤640px devine `width: 100%` → fiecare
   lua un rând întreg, iar săgeata rămânea singură pe al ei: cinci rânduri pentru un formular de
   trei câmpuri (raport user).
   Cheia e că perechea sursă→țintă e UN bloc: săgeata nu înseamnă nimic ruptă de câmpurile pe care
   le leagă, deci wrapul se face ÎNTRE grupuri, nu prin mijlocul lor (regula „ce trebuie să stea
   împreună nu poate wrapa independent", UI_RULES „Aranjament FLUID").
   `flex: 1 1 6rem` pe selecturi, fără `width` fix: pe desktop rândul rămâne unul singur, pe telefon
   cele două selecturi împart un rând în loc să ia câte unul. */
.merge-form { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; width: 100%; padding: 0.25rem 0; }
.merge-form__pair { display: flex; align-items: center; gap: 0.35rem; flex: 1 1 16rem; min-width: 0; }
.merge-form__pair .form-select { flex: 1 1 6rem; min-width: 0; width: auto; }
.merge-form__arrow { flex: 0 0 auto; color: var(--fg3); }
.merge-form > .btn { flex: 0 0 auto; }

/* ── Rând de FILTRE (traduceri) — aceeași idee: butonul de acțiune se leagă de câmpul pe care îl
   acționează. Butonul „Filtrează" cădea singur pe rândul 2 fiindcă `flex-wrap` umple lacom: cele
   trei câmpuri încăpeau pe primul rând și îl împingeau pe el peste margine. Grupat cu căutarea,
   rândul se rupe ca „[limbă][status] / [caută][filtrează]", nu ca „…/[buton orfan]". */
.admin-filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.4rem; width: 100%; }
.admin-filters label { display: flex; flex-direction: column; min-width: 0; }
.admin-filters__sel { flex: 0 1 5rem; }
.admin-filters__go { display: flex; align-items: flex-end; gap: 0.4rem; flex: 1 1 14rem; min-width: 0; }
.admin-filters__go label { flex: 1 1 auto; }
.admin-filters__go .btn { flex: 0 0 auto; }
.admin-item:last-child { border-bottom: none; }
.admin-item:hover { background: var(--sm-s2); }

/* Istoric colapsat într-o secțiune admin (ex. „ELO aplicat": ultimele 3 la vedere, restul aici).
   <details> nativ — zero JS; summary-ul arată ca un rând discret de acțiune. */
.admin-collapse__summary {
    cursor: pointer; list-style-position: inside;
    padding: 0.3rem 0.6rem; font-size: var(--font-sm); color: var(--text-muted);
    border-bottom: 1px solid var(--border-hair);
}
.admin-collapse__summary:hover { color: var(--text); background: var(--paper-2); }
.admin-collapse[open] > .admin-collapse__summary { border-bottom-style: dashed; }


.admin-sys-badge { font-size: var(--font-2xs); font-weight: 700; padding: 1px 6px; border-radius: var(--radius-sm); }
.admin-sys-badge--ok   { background: var(--sm-s2); color: var(--sm-ok); }
.admin-sys-badge--warn { background: var(--warning-soft); color: var(--warning); }
/* Termenul legal al unei cereri de anonimizare (B73) a EXPIRAT — e „eroare", deci roșul de status e
   exact rolul lui (regula din components.css: --danger înseamnă eroare, nu decor). */
.admin-sys-badge--late { background: var(--danger-soft); color: var(--danger); }
/* Coborata din `@layer skin` la B159 L10 (F2). */
.admin-sys-badge--ok::before { content: "\2713"; content: "\2713" / ""; margin-inline-end: .35em; }
/* Neutru: eticheta care nu e nici bine, nici rau — un TIP („Smoke"), o stare oprita („inactiv"),
   o cantitate care lipseste. Fara al doilea canal, fiindca nu semnaleaza nimic. */
.admin-sys-badge--neutral { background: var(--sm-s3); color: var(--sm-text-mid); }
/* „gata": stare buna, dar nu una pe care trebuie s-o remarci — bifa lui `--ok`, fara accent de culoare. */
.admin-sys-badge--ready { background: var(--sm-s2); color: var(--sm-text-hi); }
.admin-sys-badge--ready::before { content: "\2713"; content: "\2713" / ""; margin-inline-end: .35em; }

.admin-skill-tag { display: inline-flex; align-items: center; gap: 3px; font-size: var(--font-xs); background: var(--paper-2); border: 1px solid var(--border-hair); border-radius: var(--radius-sm); padding: 1px 5px; color: var(--fg2); }
.admin-skill-tag__max { color: var(--fg4); font-family: var(--font-mono); }
/* Podea de tinta (B174, WCAG 2.2 SC 2.5.8 AA). Butoanele astea masurau 11x12px — sub un SFERT din
   aria ceruta — iar `__del` STERGE un criteriu dintr-un sistem de jurizare, deci e si actiune
   distructiva, nu doar mica. Pictograma ramane la marimea ei; creste doar cutia de atingere.
   Pretul, MASURAT inainte de livrare: cipul 95x21 -> 108-120 x 24.5-28, iar inaltimea paginii de
   admin +21.5px pe desktop (+1.3%) si +74.5px pe 390px (+2.3%).
   ⚠️ Cipul CRESTE, si nu se poate altfel: varianta cu marja negativa (ca sa nu creasca) ar suprapune
   tintele cipurilor de pe randuri vecine, iar WCAG cere tinte care NU se intersecteaza. */
.admin-skill-tag__del,
.admin-skill-tag__anchor,
.sys-panel-tag__del {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: var(--tap-aa); min-height: var(--tap-aa);
}
.admin-skill-tag__del { color: var(--danger); cursor: pointer; background: none; border: none; padding: 0; line-height: 1; font-size: var(--font-xs); }
.admin-skill-tag__del:hover { color: var(--primary-strong); }
.admin-skill-tag--anchored { border-color: var(--sm-text-hi); }
.admin-skill-tag__anchor { color: var(--fg4); cursor: pointer; background: none; border: none; padding: 0; line-height: 1; font-size: var(--font-xs); }
.admin-skill-tag__anchor:hover { color: var(--primary-strong); }
.admin-skill-tag--anchored .admin-skill-tag__anchor { color: var(--sm-text-hi); }

/* Barem ancorat — panou editare per skill */
.anchor-panel { width: 100%; }
.anchor-form {
    width: 100%; margin-top: 0.2rem;
    border: 1px solid var(--border-hair); border-left: 3px solid var(--primary);
    border-radius: var(--radius-sm); background: var(--paper-2); padding: 0.5rem 0.6rem;
border-bottom-color: var(--sm-card-edge); border-right-color: var(--sm-card-edge); border-top-color: var(--sm-card-edge); }
.anchor-form__title {
    font-family: var(--font-display);
    font-size: var(--font-xs); font-weight: var(--type-label-weight, 900); text-transform: var(--type-label-case, uppercase);
    letter-spacing: var(--type-label-tracking, .08em); color: var(--fg1);
}
.anchor-form__max { color: var(--fg4); font-family: var(--font-mono); }
.anchor-form__hint { font-size: var(--font-xs); color: var(--fg3); margin: 0.15rem 0 0.45rem; }
/* Rândul de ancoră = FLUID, nu fix: cele două câmpuri stau unul lângă altul cât e loc și pică pe
   rânduri singure sub ~14rem, fără niciun prag. `flex: 1 1 5rem` pe etichetă, NU `width: auto`:
   `flex-shrink: 0` (valoarea de dinainte) ar fi supraviețuit unei simple schimbări de `width`, iar
   `width: auto` pe un `<input>` cade pe atributul `size` (~20ch) — adică ar fi ieșit mai LAT. */
.anchor-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.25rem; }
.anchor-row__score { flex-shrink: 0; width: 1.3rem; text-align: center; font-family: var(--font-mono); font-weight: 700; font-size: var(--font-sm); color: var(--fg2); }
.anchor-row__label { flex: 1 1 5rem; width: auto; min-width: 0; }
.anchor-row__text { flex: 2 1 9rem; min-width: 0; }
.anchor-row--penalty .anchor-row__score { color: var(--danger); }

.admin-table { width: 100%; font-size: var(--font-md); border-collapse: collapse; }
.admin-table th {
    font-family: var(--font-display);
    font-size: var(--font-xs); font-weight: var(--type-label-weight, 900); text-transform: var(--type-label-case, uppercase);
    letter-spacing: var(--type-label-tracking, .1em); color: var(--sm-text-hi);
    padding: 0.3rem 0.6rem; border-bottom: 2px solid var(--border-strong); background: var(--sm-strip-surface);
border-bottom-color: var(--sm-line); border-bottom-width: 1px; }
.admin-table td { padding: 0.28rem 0.6rem; border-bottom: 1px solid var(--border-hair); vertical-align: middle; background: var(--card); }
.admin-table tr:last-child td { border-bottom: none; }
.admin-table tr:hover td { background: var(--sm-s2); }
.admin-table .col-actions { width: 1%; white-space: nowrap; text-align: right; }

/* ── Tabelele dense de admin (dansatori, utilizatori) pe ecran îngust: SE STRÂNG ÎNTÂI, se trag
   lateral doar pentru rest (decizie user 2026-08-17). Card-reflow — rândul devine card cu etichete
   — a fost RESPINS explicit: adminul compară valori pe coloană când repară date în timpul unui
   eveniment, iar 30 de carduri a 8 câmpuri sunt de patru ori mai lungi de derulat.

   `@media` e legitim aici: e comutatorul de DENSITATE, nu o prăbușire de aranjament.

   ⚠️ `overflow-wrap: anywhere`, NU `word-break: break-word`: numai `anywhere` scade contribuția de
   MIN-CONTENT a celulei, adică singura care face tabelul mai îngust (`break-word` rupe textul la
   randare, dar lățimea minimă rămâne aceeași). Se pune pe `td`, nu pe `th`: un antet ar fi rupt în
   „Nume sce/nă".
   ⚠️ Podeaua e OBLIGATORIE alături: `anywhere` coboară min-content până la o literă, deci cu
   `width: 100%` pe layout automat tabelul ar încăpea MEREU și n-ar mai trage niciodată lateral —
   ar pulveriza coloanele la ~3 caractere. Podeaua stă pe COLOANĂ (`th`), nu pe tabel: regula reală
   e „nicio coloană sub ~3.5rem, altfel devine ilizibilă", iar totalul iese singur din numărul de
   coloane — utilizatori (5) încape la 360px, dansatori (8) trage puțin. O cifră pe tabel ar fi
   fost aceeași podea pentru amândouă, deci scroll inutil la cel cu 5 coloane.
   ⚠️ Modificator, nu `.admin-table` gol: `.trad-table` (traduceri) e `table-layout: fixed` cu
   coloane procentuale, deci are nevoie de alt tratament — vezi blocul ei de mai jos. ── */
@media (max-width: 640px) {
    .admin-table--drag { font-size: var(--font-sm); }
    .admin-table--drag th { min-width: 3.5rem; font-size: var(--font-2xs); letter-spacing: var(--type-label-tracking, .04em); padding: .25rem .3rem; }
    .admin-table--drag td { padding: .25rem .3rem; overflow-wrap: anywhere; }
    .admin-table--drag .badge { font-size: var(--font-2xs); }
    /* Coloana de acțiuni rămâne `nowrap`: lăsate să se rupă, cele două butoane de 44px s-ar stivui
       și ar dubla înălțimea FIECĂRUI rând. Podeaua ei sunt oricum două ținte tactile alăturate. */
    .admin-table--drag .col-actions { padding-inline: .25rem; }
}

/* Grid traduceri (i18n Faza 2) — coloane fixe + textarea confortabil pt conținut */
.trad-table { table-layout: fixed; }
.trad-table td { vertical-align: top; }
.trad-col-ent { width: 20%; }
.trad-col-field { width: 13%; }
.trad-col-src { width: 26%; }
.trad-col-status { width: 6rem; }
.trad-table td .form-control { min-height: 2.6rem; resize: vertical; }
.trad-table td, .trad-table th { word-break: break-word; }
/* Antetul se micșorează fluid: la lățimi mici „Traducere (EN)" și „Status" mâncau două rânduri
   fiecare și împingeau butonul de salvare. Capetele scării sunt tokeni (regula: `clamp()` ascunde
   literalele de gate — treptele stau tot în tokeni), fluid doar la mijloc. */
.trad-table th { font-size: clamp(var(--font-3xs), 1.6vw, var(--font-xs)); }

/* ── Traduceri pe telefon: aici NU merge „se strânge cât poate", fiindcă celula de traducere e o
   SUPRAFAȚĂ DE EDITARE, nu o valoare de citit. Cu `table-layout: fixed` și coloana de traducere la
   41%, la 360px rămâneau ~97px pentru un textarea + butonul lui — adică imposibil de folosit
   (raport user). Deci: coloanele se rebalansează în favoarea traducerii ȘI tabelul primește o
   podea, ca restul să se ia prin tragere laterală în loc să sufoce câmpul.
   Sursa rămâne citibilă — se poate derula la ea; traducerea trebuie SCRISĂ, ea are prioritate. ── */
@media (max-width: 640px) {
    .trad-table { min-width: 44rem; }
    .trad-col-ent { width: 16%; }
    .trad-col-field { width: 10%; }
    .trad-col-src { width: 20%; }
    .trad-col-status { width: 4.5rem; }
}

/* Sisteme de jurizare — grilă carduri (≈3 coloane după lățime).
   ⚠️ `min(100%, …)` e plasa anti-depășire, idiomul propriu al proiectului (base-layout.css,
   `.arch-list`). Fostul `minmax(330px, 1fr)` cerea 330px dintr-o cutie de ~259px la 360px (după
   marginile lui .panel-strip + .panel-acc__body), iar restul era înghițit de `overflow: hidden`
   de pe .admin-section — ce dispărea era exact clusterul de acțiuni din dreapta cardului
   (pauză / reactivare / ștergere). */
.judging-grid {
    --judging-col-min: 330px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--judging-col-min)), 1fr));
    gap: 0.5rem; padding: clamp(.35rem, 1.5vw, .5rem) clamp(.35rem, 2vw, .6rem);
    align-items: start;
}
.judging-card {
    border: 1px solid var(--border-hair); border-radius: var(--radius-sm);
    background: var(--sm-card-surface); padding: 0.4rem 0.5rem;
    display: flex; flex-direction: column; gap: 0.4rem;
    min-width: 0;   /* item de grilă: minimul automat e min-content → un nume lung ar lăți pista */
border-bottom-color: var(--sm-card-edge); border-right-color: var(--sm-card-edge); border-top-color: var(--sm-card-edge); }
.judging-card strong { overflow-wrap: anywhere; }
/* Antetul cardului e `justify-content: space-between` cu două clustere; fără `min-width: 0` cel din
   stânga (nume + insigne) nu poate coborî sub conținutul lui, deci împinge acțiunile afară în loc
   să se rupă. `flex-wrap` pe antet ca ultimă plasă: la nume foarte lungi acțiunile trec dedesubt,
   nu în afara ecranului. */
.judging-card > .d-flex { flex-wrap: wrap; }
.judging-card > .d-flex > * { min-width: 0; }
/* Formularele mici din card (adaugă skill / atașează panel): lățimile utilitare CEDEAZĂ lățimii
   cardului — același precedent ca `.jgrid .input-w-*` din components.css. `flex-wrap` prin CSS,
   nu prin clasă în Twig: formularele care nu sunt `d-flex` (toggle, ștergere) sunt `display: block`,
   deci regula e inertă pe ele. `.input-w-score-sm` rămâne îngust — e câmpul de scor maxim, n-are
   ce face cu lățimea numelui de criteriu. */
.judging-card form { flex-wrap: wrap; }
.judging-card .input-w-skill { width: auto !important; min-width: 0; flex: 1 1 5.5rem; }
.judging-card .input-w-score-sm { flex: 0 0 3.2rem; }
.judging-card .form-select { min-width: 0; }
.judging-card:hover {  }
/* Sisteme inactive — VIZIBILE, doar marcate. Regula veche era `display:none` + o clasa de
   dezvaluire pusa de un toggle cu `onclick` inline; toggle-ul a fost scos (regula: zero handlere
   inline), dar ascunderea a ramas -> un sistem dezactivat disparea din admin si NU mai putea fi
   reactivat, desi butonul lui exista in markup. Marcajul e suficient: cardul poarta deja badge-ul
   „inactiv" si butonul de reactivare. */
/* „Nu e în uz" era desenat cu `opacity: .55` + dezvăluire la hover. Opacitatea stinge contrastul, nu se
   poate tematiza, iar hover-ul nu există pe touch — deci pe telefon informația rămânea pur și simplu stinsă.
   Retragerea trece pe tokeni (suprafață și cerneală mai liniștite), iar chenarul punctat rămâne canalul
   care NU e culoare. Un sistem neactiv e CONȚINUT, nu un control dezactivat. */
.judging-card--inactive { border-style: dashed; background: var(--sm-s2); color: var(--sm-text-mid); }

/* Panele specialiste — grup de sisteme cu 1 skill, un jurat pe rol (OUR-3/OUR-5) */
/* Marginile + paddingul sunt FLUIDE: la 360px, lanțul .panel-strip → .panel-acc__body → .judging-grid
   mânca ~80px din lățime înainte ca vreun card să fie desenat. Pe desktop rămân valorile de azi. */
.panel-strip { border: 1px dashed var(--border-hair); border-radius: var(--radius-sm); padding: clamp(.3rem, 1.5vw, .45rem) clamp(.35rem, 2vw, .6rem); margin: 0 clamp(.3rem, 2vw, .6rem) 0.6rem; display: flex; flex-direction: column; gap: 0.45rem; border-color: var(--sm-hair); }
.panel-strip__head { font-size: var(--font-sm); font-weight: 700; display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem; }
/* Singurul supraviețuitor al vechiului grid de panel-carduri (admin folosește .panel-acc):
   mesajul „fără roluri" din corpul acordeonului. Restul blocului = șters la auditul 2026-08-06. */
.panel-card__empty { font-size: var(--font-xs); }
.panel-strip__create { max-width: 360px; }

/* Copierea line-up-ului dintr-o categorie soră — ACELAȘI bloc pe ambele pagini și pe ambele
   variante (jurați / DJ-host): markupul e un singur partial, `contest/_copy_picker.html.twig`.
   `<details>` cu un select de sursă + lista de bife; nu conține niciun formular (ADR 0047).
   Acordeonul per-sursă (.copy-picker__src / __count) a dispărut odată cu varianta care posta. */
.copy-picker { margin-top: .35rem; }
/* Colt pe TOKEN de rol, cu valoarea de azi ca fallback (0): declansatorul e un control, iar pe skinul modern
   primeste forma de pastila fara ca skinul sa scrie inca un `border-radius` (contorul K1, B159). */
.copy-picker > summary {
    border-radius: var(--radius-control, 0);
    /* `display: inline-flex` si `align-items: center` erau scrise AICI si nu se randau: randul
       de mai jos le rescrie (al doilea `align-items` avea chiar aceeasi valoare). Sterse la B179. */
    padding: .2rem .6rem;
    display: flex; align-items: center; gap: .3rem;
    cursor: pointer; user-select: none; list-style: none;
    font-size: var(--font-xs); font-weight: 700; color: var(--sm-text-hi);
box-shadow: inset 0 0 0 1px var(--sm-line); background: var(--sm-s3); }
.copy-picker > summary::-webkit-details-marker { display: none; }
.copy-picker > summary:hover { color: var(--sm-text-hi); background: color-mix(in srgb, var(--sm-text-hi) 12%, var(--sm-s3)); }
.copy-picker__list { padding: .35rem 0 0 .5rem; display: flex; flex-direction: column; gap: .25rem; }
.copy-picker__form { display: flex; flex-direction: column; gap: .25rem; align-items: flex-start; padding: .35rem 0; }
.copy-picker__row { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.copy-picker__row--here { opacity: .55; }
.copy-picker__pick { display: flex; align-items: center; gap: .3rem; font-size: var(--font-xs); cursor: pointer; margin: 0; }
.copy-picker__note { font-size: var(--font-2xs); color: var(--fg4); }

/* Acordeon panel (native <details name>) — deschide un panel îl închide pe celălalt, zero JS */
/* `min-width: 0` în locul lui `overflow: hidden` — aceeași motivație ca la `.admin-section`:
   acordeonul e tot un container care înghițea tăcut cardurile prea late în loc să le lase văzute. */
.panel-acc { border: 1px solid var(--border-hair); border-radius: var(--radius-sm); background: var(--sm-card-surface); min-width: 0; border-bottom-color: var(--sm-card-edge); border-right-color: var(--sm-card-edge); border-top-color: var(--sm-card-edge); }
.panel-acc + .panel-acc { margin-top: 0.35rem; }
.panel-acc--inactive { background: var(--sm-s2); color: var(--sm-text-mid); }   /* fără `opacity`, ca la .judging-card--inactive */
.panel-acc > summary {
    display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem;
    padding: 0.45rem 0.6rem; cursor: pointer; font-weight: 700; font-size: var(--font-sm);
    list-style: none; user-select: none;
}
/* Coborata din `@layer skin` la B159 L10 (F2). */
.copy-picker[open] > summary { background: color-mix(in srgb, var(--sm-text-hi) 12%, var(--sm-s3)); color: var(--sm-text-hi); }
.panel-acc > summary::-webkit-details-marker { display: none; }
.panel-acc > summary::after { content: "\F282"; font-family: "bootstrap-icons"; margin-left: auto; font-size: 0.8em; transition: transform 0.15s ease; color: var(--fg4); }
.panel-acc[open] > summary::after { transform: rotate(180deg); }
.panel-acc > summary:hover { background: var(--paper-2); }
/* Fundalul de hover al lui `summary` acopera coltul de sus al acordeonului. Se vede doar pe
   light (pe dark `--paper-2` = fundalul cardului) si doar la hover — deci sonda nu-l poate
   masura: ea ridica intentionat mouse-ul. Reparat pe rationament, nu pe masuratoare. */
/* ⚠️ AICI `inherit` NU MERGE, si e singura familie in situatia asta. Masurat in Chromium pe elementul
   real: parintele `<details>` computeaza 8px, un `<div>` de control ia raza prin `inherit` fara
   probleme, dar pe `<summary>` `inherit` da 0 — in timp ce aceeasi valoare scrisa LITERAL prinde.
   Deci aici se scrie tokenul, nu `inherit`.
   Pretul: daca `.panel-acc` isi schimba raza, trebuie schimbata si asta. De-aia tokenul e acelasi
   (`--radius-sm`), nu o cifra — ca sa se miste impreuna. */
.panel-acc > summary {
    border-start-start-radius: var(--radius-sm);
    border-start-end-radius: var(--radius-sm);
}
.panel-acc__name { font-weight: var(--type-title-weight, 900); }
.panel-acc__body { padding: clamp(.35rem, 1.5vw, .5rem) clamp(.35rem, 2vw, .6rem) 0.6rem; border-top: 1px solid var(--border-hair); display: flex; flex-direction: column; gap: 0.5rem; border-top-color: var(--sm-hair); }
.panel-acc__actions { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.panel-acc__actions form { display: inline; }
@media (prefers-reduced-motion: reduce) { .panel-acc > summary::after { transition: none; } }

/* Marcaj panel pe cardul sistemului */
.sys-panel-tag { display: inline-flex; align-items: center; gap: 0.2rem; font-size: var(--font-xs); padding: 1px 7px; border-radius: var(--radius-sm); background: var(--paper-2); border: 1px solid var(--border-hair); align-self: flex-start; }
.sys-panel-tag__form { display: inline; }
.sys-panel-tag__del { border: 0; background: transparent; color: var(--danger); padding: 0 0 0 2px; line-height: 1; cursor: pointer; }
/* Accent culoare per panel — leagă cardul panelului de sistemele membre din grid.
   Trecut pe paleta CATEGORIALĂ (`--cat-*`, tokens.css, ADR 0056). Înainte erau șase hexuri literale,
   fără variantă de temă întunecată — deci aceeași nuanță închisă și pe fundal închis — iar două din
   ele călcau semantica: `#e8590c` (portocaliu ≈ avertisment) și `#f08c00` (galben = avertisment);
   `#2f9e44` se citea „ok". Paleta e construită eliminând culorile deja vorbite. Nuanța nu e singurul
   canal: numele panoului e scris lângă dungă. */
.jacc-0 { border-left: 3px solid var(--cat-1); }
.jacc-1 { border-left: 3px solid var(--cat-2); }
.jacc-2 { border-left: 3px solid var(--cat-3); }
.jacc-3 { border-left: 3px solid var(--cat-4); }
.jacc-4 { border-left: 3px solid var(--cat-5); }
.jacc-5 { border-left: 3px solid var(--cat-6); }

/* Rolul unui utilizator = CATEGORIE, nu stare (ADR 0056). Culoarea vine din paleta categorială, iar
   canalul principal rămâne CUVÂNTUL scris în insignă. Contur + text, nu umplere: paleta e calibrată
   pentru ≥ 3:1 pe suprafață, nu are pereche „on-" pentru umpleri. */
.role-badge { background: transparent; border: 1px solid var(--cat-1); color: var(--cat-1); }
.role-badge--admin { border-color: var(--cat-2); color: var(--cat-2); }

/* Singurul supraviețuitor al vechiului grid de carduri Dansatori (tabul e acum .admin-table):
   crew-ul de lângă numele dansatorului. Restul blocului = șters la auditul 2026-08-06. */
.dancer-card__crew { color: var(--fg3); font-size: var(--font-xs); margin-left: 0.3rem; }


/* === 11b. CONTEST EDIT — /cont/{id}/edit ============== */

/* Muchia stângă = semnătura de STIL (aceeași ca .style-pill/.cat-strip__item): hue-ul vine din
   markup (`--style-h`, filtrul style_hue), S/L din scara stilului de dans din `tokens.css`. Diferențiază
   categoriile între ele și de panourile .form-panel din jur (nivel 1 = ramă uniformă). */
.ecat {
    /* Trei laturi: fir de 1px in muchia de card (coborat din `@layer skin` la B159 L10, F2).
       A patra, stanga, ramane rigla groasa cu hue-ul stilului — vezi randul urmator. */
    border: 1px solid var(--sm-card-edge);
    border-left: 3px solid hsl(var(--style-h, 0) var(--style-s, 70%) var(--style-l-accent, 45%));
    border-radius: var(--radius-sm); background: var(--sm-card-surface); margin-bottom: .5rem;
border-right-width: 1px; }
/* `.ecat__hdr` poarta tenta stilului, deci PICTEAZA peste coltul de sus al randului. Acelasi
   tipar ca mai sus; jos nu e nevoie — `.ecat__body` are doar padding. */
.ecat > :first-child { border-start-start-radius: inherit; border-start-end-radius: inherit; }
/* Headerul poartă TENTA stilului (aceeași scară ca .style-pill: --style-l-bg 90% light / 22% dark,
   din scara stilului de dans, `tokens.css`) — fostul var(--paper-2) diferea de fundal cu un micro-pas și
   zonele nu se distingeau (raport user 2026-08-16). Cerneala titlului vine din aceeași scară. */
.ecat__hdr {
    display: flex; align-items: center; justify-content: space-between; gap: 6px;
    padding: .3rem .6rem;
    background: hsl(var(--style-h, 0) var(--style-s, 70%) var(--style-l-bg, 90%));
    border-bottom: 1px solid var(--border-hair);
}
.ecat__title { font-family: var(--font-display); font-size: var(--font-md); font-weight: var(--type-title-weight, 900); text-transform: var(--type-title-case, uppercase); letter-spacing: var(--type-title-tracking, .03em); color: hsl(var(--style-h, 0) var(--style-s, 70%) var(--style-l-fg, 30%)); }
.ecat__meta { font-size: var(--font-xs); color: hsl(var(--style-h, 0) var(--style-s, 70%) var(--style-l-fg, 30%)); opacity: .75; font-weight: 400; text-transform: none; letter-spacing: 0; }
.ecat__body { padding: .5rem .65rem; }
.config-pill--lock { opacity: .6; border-style: dashed; }
.inp-poster { max-width: 160px; }
.edit-locked-note {
    font-size: var(--font-xs); color: var(--fg3);
    display: inline-flex; align-items: center; gap: 4px;
}

/* Câmp modificat dar nesalvat — semnal vizual (form-dirty.js îl pune/scoate). Bară accent la stânga.
   !important: bate border-color-ul cu stare al Bootstrapului (:focus/.is-invalid pe .form-control),
   altfel semnalul dispare exact pe câmpul în care omul tocmai scrie. */
.is-dirty {
    border-color: var(--dirty-signal, var(--accent)) !important;
    /* `!important` si pe umbra, din acelasi motiv ca pe chenar - si nu doar din cauza Bootstrapului:
       `.form-control:focus { box-shadow: none }` (tokens.css, `@layer app`) stinge halo-ul de focus. Regula aia
       e in ACELASI layer ca asta de aici, dar mai specifica (0,2,0 fata de 0,1,0), deci fara `!important` bara
       de 3px ar disparea exact pe campul in care omul tocmai scrie - adica fix regresia pe care chenarul o
       prevenea. Gasit in B159 L6b, cand motivul era ordinea layerelor (`@layer skin`); layerul a disparut la
       L10 F4, MOTIVUL A RAMAS, dar e altul: specificitatea. */
    box-shadow: inset 3px 0 0 0 var(--dirty-signal, var(--accent)) !important;
background: var(--sm-warning-soft); }

/* Bară unică de salvare, lipită jos — un singur „Salvează modificările" pentru tot ce e configurabil. */
.edit-savebar {
    position: sticky; bottom: 0; z-index: 10;
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
    margin-top: .75rem; padding: .55rem .7rem;
    background: var(--surface);
    border: 2px solid var(--border-strong); border-radius: var(--radius-sm);
    box-shadow: var(--sm-elev-float);
    transition: border-color .15s ease, background-color .15s ease;
border-color: var(--sm-card-edge); border-width: 1px; }
/* Stare „nesalvat" — semnal vizual în pagină (fără popup), accent pe bară + status. */
.edit-savebar--dirty { border-color: var(--sm-warning); background: var(--dirty-surface, var(--bg-elevated)); border-width: 2px; }
.savebar-status {
    font-family: var(--font-display); font-weight: var(--type-status-weight, 900); text-transform: var(--type-status-case, uppercase);
    letter-spacing: var(--type-status-tracking, .06em); font-size: var(--font-xs); color: var(--dirty-signal, var(--accent));
}






/* Coborata din `@layer skin` la B159 L10 (F2). */
.acct-card .btn-outline-secondary:hover { background: color-mix(in srgb, var(--sm-text-hi) 12%, var(--sm-s3)); color: var(--sm-text-hi); border-color: var(--sm-line); }
/* Coborata din `@layer skin` la B159 L10 (F2). */
.category-row .category-row__title { color: var(--sm-text-hi); }
/* Coborata din `@layer skin` la B159 L10 (F2). */
.category-row .btn-close { filter: var(--sm-close-filter); }
/* Coborata din `@layer skin` la B159 L10 (F2). */
.copy-picker > summary:active { background: var(--sm-btn-fill); color: var(--sm-on-btn-fill); }
/* Coborata din `@layer skin` la B159 L10 (F2). */
.cbc-days--today { background: var(--sm-warning); color: var(--sm-bg); }
  /* ---- ADMIN, insignele (B175, 2026-09-26) ----
     Aici stateau PATRU reguli care remapau culorile Bootstrap (`--bs-warning-rgb` etc.). Existau doar
     ca sa anuleze o semantica pe care markupul o numea gresit: un CONTOR scris `bg-warning`, o stare
     scrisa `bg-success`. Randarea iesea corecta, markupul mintea, iar regulile erau declaratii de
     anulare — exact tiparul curatat din CSS la B159 L10. Acum numele spun ce sunt, si toate patru
     au disparut.
     Contorul pastreaza `.badge`, ca sa mosteneasca geometria Bootstrap: asa randarea ramane
     identica cu ce dadea remapul, iar schimbarea e doar de NUME. */
  .admin-count { background: var(--sm-s3); color: var(--sm-text-hi); }
  /* ⚠️ Puntea asta NU e un remap de insigna si NU se sterge odata cu ele: `.text-dark` din Bootstrap
     e o culoare FIXA, iar aici o face sa urmeze tema (cerneala inchisa pe light, deschisa pe dark).
     O folosesc butoanele „Salveaza barem" / „Salveaza" din tabul de jurizare (~54, una per rand de
     sistem). Stearsa din greseala la prima incercare de B175, si sonda a prins-o imediat: textul lor
     sarise pe `rgb(33,37,41)`, adica pe cenusiul brut al Bootstrapului, ilizibil pe tema intunecata.
     ⚠️ ATENTIE la ce NU spune comentariul asta — prima versiune a lui afirma ca butoanele stau pe
     „albastru brut". FALS, masurat: `.btn-info` e remapat in `components.css` pe paleta, deci ele se
     randeaza `#dde0d5` / cerneala `--sm-text-hi` pe light si `rgb(49,56,49)` / `#e6e9e3` pe dark.
     Puntea asta tine doar CERNEALA, prin utilitarul `text-dark` din markupul lor.
     Si de aici vine B182: `text-dark` e REDUNDANT, fiindca remapul lui `.btn-info` seteaza deja
     `--bs-btn-color: var(--sm-text-hi)`. Se scoate din markup → puntea ramane fara consumator si
     moare si ea. Nu se sterge INAINTE de markup: ordinea conteaza, altfel se repeta greseala. */
  body.admin { --bs-dark-rgb: var(--sm-text-hi-rgb); }
} /* END @layer app */
