/* ═══════════════════════════════════════════════════════════════════════════
   Nimbus · contractul cojii · v2 · chrome.css
   ---------------------------------------------------------------------------
   Clasele. Fără JavaScript obligatoriu: tot ce e aici se randează corect dintr-un
   șablon Jinja servit de Flask, fără Node și fără pas de build. chrome.js e un
   strat OPȚIONAL peste ele (dialog, starea „se lucrează”, anularea din rând);
   pagina merge și fără el (docs/adr/0009).

   Se leagă DUPĂ tokens.css. Referința vie, cu fiecare componentă în fiecare
   stare, e chrome.html de lângă acest fișier.

   v2 = v1 copiat, plus delta aprobată pe boardul de design (docs/design/board/):
     · butoanele vorbesc cu literă mică de propoziție; antetul paginii rămâne în
       versale (Q14, Q-X3);
     · apăsarea Restrained (.97, 100/160 ms, fără arc), numai de la indicator,
       niciodată de la tastatură; hover numai sub (hover: hover);
     · reduced motion = nimic nu se mișcă și nimic nu se estompează (Q13, ADR-0008);
     · treptele de literă Q7; titlul paginii pe telefon 26, nu 30;
     · 44 px de atins sub (pointer: coarse), scris O DATĂ aici;
     · filele subliniate sunt navigarea paginii; chip-urile sunt numai filtre (Q-X1);
     · tabelul își poartă singur derularea orizontală;
     · stările care lipseau: se lucrează, eroare de câmp, gol / așteptare / eșec,
       inel = necunoscut (Q-X4), anularea din rând, dialogul, foaia, vizualizatorul
       de document, bara de compoziție, cronologia (provizorie);
     · reparațiile găsite pe board (inelul tăiat de .nb-seg, hex-urile brute,
       cascada lui `.nb-body a`, raza legendei, [hidden], acțiunile care nu se
       înfășurau sub 900 px).
   Regula care nu se negociază rămâne: nicio clasă nu are voie să existe doar în Vue.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Temelia ──────────────────────────────────────────────────────────────
   Se aplică pe <body class="nb-body">, nu pe body gol: contractul nu are voie
   să confiște documentul unei aplicații care îl leagă doar pe o pagină.
   Resetul e AL NOSTRU și e limitat la subarborele .nb-body (vezi LEARNINGS,
   N1: un contract care se sprijină pe resetul gazdei nu e un contract). */

.nb-body,
.nb-body *,
.nb-body *::before,
.nb-body *::after { box-sizing: border-box; }

/* `hidden` ascunde, orice ar spune o clasă. În v1, `.nb-btn { display:
   inline-flex }` bătea atributul (aceeași specificitate, venea mai târziu), așa
   că un buton „ascuns” rămânea pe ecran. `until-found` e lăsat browserului. */
.nb-body [hidden]:not([hidden="until-found"]),
.nb-body[hidden] { display: none !important; }

.nb-body {
  margin: 0;
  /* Widgeturile NATIVE (calendarul lui type="date", bara de derulare) se
     desenează închise. CSS-ul nostru nu le atinge: stau în shadow DOM. */
  color-scheme: dark;
  background: var(--nb-bg);
  color: var(--nb-text);
  font-family: var(--nb-font-body);
  font-size: var(--nb-size-base);
  line-height: var(--nb-lh-body);
  word-spacing: var(--nb-word-space);
  -webkit-font-smoothing: antialiased;
}

/* ATENȚIE la specificitate: regula de mai jos are 0,1,1 (clasă + element) și
   bate orice clasă simplă pusă pe un h1–h3, oricât de târziu ar veni în fișier.
   E aceeași ca în v1 și rămâne așa dinadins: aplicațiile care trec de pe v1 au
   reguli de titlu care pierdeau în fața ei, iar dacă v2 ar coborî-o, acele
   reguli ar câștiga peste noapte, adică schimbări de pagină pe care nu le-a
   văzut nimeni. Consecința: o componentă pusă pe un titlu nu-și poate schimba
   aici margin, font-family, font-weight, line-height sau color doar cu o clasă
   (.nb-cap__t, .nb-empty__t, .nb-dialog__t își declară deci exact valorile
   acestea). Pentru o valoare diferită, selectorul are nevoie de 0,1,1 sau mai mult. */
.nb-body h1,
.nb-body h2,
.nb-body h3 {
  margin: 0;
  font-family: var(--nb-font-head);
  font-weight: 600;
  line-height: var(--nb-lh-tight);
  color: var(--nb-text-max);
}

/* Spațierea dintre cuvinte e pentru textul curent. Titlurile în Barlow își au
   spațierea lor; .06em în plus le-ar desface. Eticheta de câmp NU e pe listă:
   paginile aprobate pe board o lasă cu spațierea textului, și o pagină care
   își pune etichetele în literă de propoziție (Formular) are nevoie de ea. */
.nb-body :is(h1, h2, h3, .nb-page-head__title, .nb-tile__name, .nb-eyebrow, .nb-th,
  .nb-btn, .nb-cap__t, .nb-empty__t) { word-spacing: normal; }

/* Un singur inel de focalizare, peste tot, vizibil pe grafit. Pe controalele
   contractului inelul VINE de la 5 px și se așază la 2 px (180 ms); în repaus
   are culoarea transparentă, ca albastrul legăturii să nu fie confundat cu el.
   Stilul rămâne „none” în repaus: un contur transparent ar deveni vizibil în
   modul de contrast ridicat al sistemului. */
.nb-body :focus-visible {
  outline: 2px solid var(--nb-focus);
  outline-offset: 2px;
}
:where(.nb-btn, .nb-chip, .nb-input, .nb-select, .nb-rail__btn, .nb-tabs__tab,
       .nb-seg__btn, .nb-hint__btn, .nb-link, .nb-body a, .nb-tile, .nb-check__box) {
  outline-color: transparent;
  outline-offset: 5px;
}

/* Subliniată, nu doar albastră (axe, link-in-text-block): albastrul față de
   zinc dă 1,54:1, deci culoarea singură nu deosebește legătura de text. */
.nb-link {
  color: var(--nb-blue-link);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Etichetă mică de deasupra unui titlu. Albastru = informație. */
.nb-eyebrow {
  font-size: var(--nb-size-xs);
  font-weight: 600;
  letter-spacing: var(--nb-track-eyebrow);
  text-transform: uppercase;
  color: var(--nb-blue-link);
}

/* Caroiajul de fundal — hârtie milimetrică. Se pune pe un ANTET, niciodată în
   spatele unei grile de plăci. Excepție numită de la „fără gradient” (tokens.css,
   Formă): opriri tăiate, deci linii de 1 px, nu o trecere de culoare. Culoarea
   liniei e --nb-grid-line; v1 o scria ca literal brut. */
.nb-grid-bg {
  background-image:
    linear-gradient(var(--nb-grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--nb-grid-line) 1px, transparent 1px);
  background-size: 44px 44px;
}

/* Pictograma de linie, aceeași peste tot: 14 px, trăsătură 1,6, culoarea textului. */
.nb-ico {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Săgeata dintr-o acțiune și chevronul unui rând: arată încotro duce. La hover
   alunecă 2 px în direcția aceea (Q5); altfel stau. */
.nb-arrow { display: inline-block; margin-left: 6px; }
.nb-arrow--back { margin-left: 0; margin-right: 6px; }
.nb-chev {
  display: inline-block;
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  fill: none;
  stroke: var(--nb-text-muted);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: middle;
  /* În repaus, chevronul e singurul semn că rândul duce undeva (titlul rândului
     arată ca textul). Pe paginile aprobate stătea la .45, adică 2,15:1 pe panou,
     sub pragul de 3:1 pentru un semn grafic care poartă înțeles (WCAG 1.4.11),
     iar pe telefon nu există hover care să-l aprindă. .7 = 3,31:1 pe panou,
     3,51:1 pe fundal; tot stins față de hover (1). */
  opacity: .7;
}

/* ── Coaja: șina + conținutul ─────────────────────────────────────────── */

.nb-shell {
  display: flex;
  min-height: 100vh;
}

/* ȘINA listează APLICAȚII, niciodată pagini dintr-o aplicație (CLAUDE.md §2).
   Sub 900px devine bară jos. */
.nb-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--nb-s2);
  width: var(--nb-rail-w);
  flex-shrink: 0;
  padding: var(--nb-s4) 0;
  background: var(--nb-bg-rail);
  border-right: 1px solid var(--nb-line);
}

.nb-rail__mark {
  display: block;
  margin-bottom: var(--nb-s3);
}

.nb-rail__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--nb-hit);
  height: var(--nb-hit);
  margin: 0;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--nb-radius);
  background: none;
  /* Poate fi <button> („Ieși”, un POST fără JavaScript). Coaja spune fontul. */
  font: inherit;
  color: var(--nb-steel);
  cursor: pointer;
}

.nb-rail__btn--on {
  color: var(--nb-text-max);
  background: var(--nb-bg-raised);
  border-color: var(--nb-line-control);
}

/* Aplicație anunțată, dar care încă nu există: <span>, nu legătură. */
.nb-rail__btn--soon {
  color: var(--nb-text-muted);
  border-style: dashed;
  border-color: var(--nb-line-dashed);
  cursor: default;
  opacity: .6;
}

/* Inițialele omului conectat. Vin din sămânța de identitate, nu din coajă. */
.nb-rail__me {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin-top: auto;
  background: var(--nb-bg-raised);
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  font-size: var(--nb-size-sm);
  font-weight: 700;
  color: var(--nb-text-max);
}
/* Locul ținut gol (MAF, Parc sub M365): serverul știe doar un id, chrome.js pune inițialele.
   Cutia rămâne, ca „Ieși” de sub ea să nu sară când apar. */
.nb-rail__me:empty { visibility: hidden; }

.nb-main {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  min-width: 0; /* fără asta, un tabel lat împinge șina afară din ecran */
}

/* ── Bara de sus: unde sunt, plus o stare la dreapta ──────────────────── */

.nb-topbar {
  display: flex;
  align-items: center;
  gap: var(--nb-s3);
  height: var(--nb-topbar-h);
  padding: 0 var(--nb-s6);
  background: var(--nb-bg-panel);
  border-bottom: 1px solid var(--nb-line);
  font-size: var(--nb-size-md);
}

.nb-topbar__crumb { color: var(--nb-text-muted); }
.nb-topbar__sep { color: var(--nb-text-muted); }
.nb-topbar__here { font-weight: 600; color: var(--nb-text-max); }
/* Firimitura-legătură fără subliniere. Paginile aprobate nu sunt de acord între
   ele: Mașini și Mașina o scot dinadins (cu hover spre alb și inel la Tab), în
   paginile MAF sublinierea e doar moștenită din browser, nescrisă de nimeni.
   Legătura se recunoaște aici după loc și după „/”, nu după culoare; axe
   (link-in-text-block) privește numai legăturile din mijlocul unui text.
   Alegerea 4 din ADR-0009, acceptată odată cu ADR-ul (30.09). */
a.nb-topbar__crumb { text-decoration: none; }

/* Starea e „de când sunt datele astea”. Dacă nu ai ce scrie adevărat, goală.
   Poate să se strângă: o stare lungă nu mai lărgește pagina (AUDIT 11). */
.nb-topbar__state {
  /* Se strânge ÎNAINTEA firimiturilor: „unde sunt” contează mai mult. */
  flex-shrink: 100;
  min-width: 0;
  margin-left: auto;
  overflow: hidden;
  font-size: var(--nb-size-sm);
  color: var(--nb-text-muted);
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Account disclosure: plain links/form, usable in any HTML consumer.
   Closing disables interaction immediately; visibility waits for the fade.
   No timers: reversing the transition also reverses a rapid close/reopen. */
.nb-topbar__utilities {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--nb-s2);
  margin-left: auto;
  min-width: 0;
}
/* MAF și Parc țin starea (și „modificări nesalvate”) chiar înaintea contului: starea ia
   spațiul liber și se strânge prima, contul stă lipit de ea la dreapta. */
.nb-topbar__state + .nb-topbar__utilities { margin-left: 0; }
.nb-account { position: relative; min-width: 0; }
.nb-account .nb-account__trigger { min-height: 44px; max-width: 100%; }
.nb-account__initials {
  color: var(--nb-blue-link);
  font-size: var(--nb-size-sm);
  font-weight: 600;
}
.nb-account__label { max-width: 12ch; overflow: hidden; text-overflow: ellipsis; }
.nb-account__mobile { display: none; }
.nb-account__trigger .nb-chev { transform: rotate(0deg); }
.nb-account__trigger[aria-expanded="true"] { border-color: var(--nb-blue-link); }
@media (prefers-reduced-motion: no-preference) {
  .nb-account__trigger[aria-expanded="true"] .nb-chev { transform: rotate(180deg); }
}
.nb-account__panel {
  position: absolute;
  z-index: 30;
  top: calc(100% + var(--nb-s2));
  right: 0;
  width: min(280px, calc(100vw - 32px));
  max-height: calc(100dvh - var(--nb-topbar-h) - var(--nb-s5));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--nb-s2);
  border: 1px solid var(--nb-line);
  border-radius: var(--nb-radius);
  background: var(--nb-bg-panel);
  box-shadow: 0 var(--nb-s2) var(--nb-s5) var(--nb-bg);
  opacity: 0;
  transform: translateY(-4px);
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--nb-dur-exit) var(--nb-ease), transform var(--nb-dur-exit) var(--nb-ease), visibility 0s var(--nb-dur-exit);
}
.nb-account:has(.nb-account__trigger[aria-expanded="true"]) .nb-account__panel {
  opacity: 1;
  transform: translateY(0);
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--nb-dur-enter) var(--nb-ease-out), transform var(--nb-dur-enter) var(--nb-ease-out), visibility 0s;
}
.nb-account__name {
  margin: 0 0 var(--nb-s2);
  padding: var(--nb-s2);
  border-bottom: 1px solid var(--nb-line);
  color: var(--nb-text-muted);
  font-size: var(--nb-size-sm);
  overflow-wrap: anywhere;
}
/* Rânduri de meniu, nu trei butoane: fără chenar în repaus; umplerea ghost apare la
   hover/apăsare, iar chenarul rămâne transparent ca rândurile să nu „sară” între stări. */
.nb-account .nb-account__item { width: 100%; justify-content: flex-start; min-height: 44px; padding-inline: var(--nb-s2); border-color: transparent; }
.nb-account .nb-account__item:is(:hover, :active, [data-nb-state]) { border-color: transparent; }
/* „Aici ești” ≠ „arăți spre”: pagina curentă e albastră cu un accent în stânga, hoverul
   doar umple — altfel cele două stări se confundă pe panou. */
.nb-account .nb-account__item[aria-current="page"] { color: var(--nb-blue-link); box-shadow: inset 2px 0 0 var(--nb-blue-link); }
@media (hover: hover) {
  .nb-account .nb-account__item:hover { background-color: var(--nb-bg-raised); }
}
.nb-account__panel > form { margin-top: var(--nb-s1); padding-top: var(--nb-s1); border-top: 1px solid var(--nb-line); }
@media (max-width: 599px) {
  .nb-topbar__utilities { gap: var(--nb-s1); }
  .nb-topbar__utilities > .nb-btn { font-size: var(--nb-size-sm); min-height: 44px; }
  .nb-account__label { display: none; }
  .nb-account__mobile { display: inline; }
}
@media (max-width: 899px) {
  .nb-account__panel { max-height: calc(100dvh - var(--nb-topbar-h) - var(--nb-topbar-h) - var(--nb-rail-h) - var(--nb-s5) - env(safe-area-inset-bottom)); }
}

/* ── Antetul paginii: supratitlu + titlu + acțiuni ────────────────────── */

.nb-page-head {
  display: flex;
  align-items: flex-end;
  gap: var(--nb-s5);
  padding: 30px var(--nb-s6) var(--nb-s5);
}

.nb-page-head__id {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s3);
  min-width: 0;
}

.nb-page-head__title { font-size: var(--nb-size-h1); }

.nb-page-head__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nb-s3);
  margin-left: auto;
}

/* Între 900 și 1279 px acțiunile stau pe rândul lor, sub titlu, pe orice pagină (ADR-0009,
   decizia 9, Teo 02.10). Lângă titlu, butoanele se rupeau pe două rânduri numai pe unii pași
   (etichete mai lungi): capul creștea de la 125 la 168 px și bara de pași de dedesubt sărea
   43 px de la un pas la altul (T-19, MAF m0002 la 1024). Pe rândul lor încap întregi, deci
   capul are aceeași înălțime pe toți pașii. Numai acțiunile coboară: ce mai stă lângă titlu
   (semnul din hub) rămâne pe rândul titlului. Rândul se păstrează și cât e gol (un buton care
   apare abia după un calcul, ca „Copiază” din hub), ca bara să nu sară nici atunci. Sub 900 px
   capul e deja o coloană; de la 1280 acțiunile rămân lângă titlu, ca pe paginile aprobate. */
@media (min-width: 900px) and (max-width: 1279px) {
  .nb-page-head {
    flex-wrap: wrap;
    row-gap: var(--nb-s4);
  }
  .nb-page-head__actions {
    flex-basis: 100%;
    min-height: var(--nb-btn-h);
    margin-left: 0;
  }
}

.nb-content {
  display: flex;
  gap: 26px;
  align-items: flex-start;
  padding: 0 var(--nb-s6) var(--nb-s6);
}

.nb-col {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s4);
  flex-grow: 1;
  min-width: 0;
}

/* Coloana îngustă din dreapta: panoul de comandă al paginii. */
.nb-aside {
  display: flex;
  flex-direction: column;
  gap: 18px;
  width: 336px;
  flex-shrink: 0;
}

/* ── Panoul: singura cutie din sistem ─────────────────────────────────── */

.nb-panel {
  background: var(--nb-bg-panel);
  border: 1px solid var(--nb-line);
  border-radius: var(--nb-radius);
}

.nb-panel--pad { padding: var(--nb-s5); }

/* Titlul unei liste (grupul de rânduri dintr-un panou): Barlow 20, literă de
   propoziție (Q-X5), numărătoarea sau o notă la dreapta. Un panou care NU e o
   listă (un formular, un rezumat) își păstrează supratitlul în versale,
   .nb-eyebrow, deasupra conținutului — tot Q-X5. Culoarea stă pe cuvintele de
   stare din rânduri, nu aici. Pe un h2/h3, valorile de mai jos sunt și cele pe
   care le-ar da regula de bază a titlurilor (vezi „ATENȚIE la specificitate”). */
.nb-cap {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  padding: var(--nb-s4) var(--nb-s5);
  border-bottom: 1px solid var(--nb-line);
}
.nb-cap__t {
  margin: 0;
  font-family: var(--nb-font-head);
  font-size: var(--nb-size-h3);
  font-weight: 600;
  line-height: var(--nb-lh-tight);
  color: var(--nb-text-max);
}
.nb-cap__end { margin-left: auto; }

/* Numărătoarea: cifră goală, tabulară, fără pastilă (Q-X6); stinsă la zero. */
.nb-count {
  font-size: var(--nb-size-sm);
  font-weight: 600;
  color: var(--nb-text-strong);
  font-variant-numeric: tabular-nums;
}
.nb-count--info { color: var(--nb-blue-link); }
.nb-count:is(:empty, [data-n="0"]) { color: var(--nb-text-muted); }

/* ── Placa: cartonașul unei aplicații pe hub ──────────────────────────── */

.nb-tile {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: var(--nb-s5);
  background: var(--nb-bg-panel);
  border: 1px solid var(--nb-line);
  border-radius: var(--nb-radius);
  text-decoration: none;
}

.nb-tile__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--nb-hit);
  height: var(--nb-hit);
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  color: var(--nb-blue-link);
}

.nb-tile__name {
  font-family: var(--nb-font-head);
  font-weight: 600;
  font-size: var(--nb-size-tile);
  letter-spacing: var(--nb-track-tile);
  text-transform: uppercase;
  color: var(--nb-text-max);
}

.nb-tile__desc {
  margin: 0;
  font-size: var(--nb-size-base);
  line-height: 1.55;
  color: var(--nb-text);
  text-wrap: pretty;
}

.nb-tile__foot {
  margin-top: auto;
  padding-top: var(--nb-s3);
  border-top: 1px solid var(--nb-line-soft);
  font-size: var(--nb-size-sm);
  font-weight: 600;
  color: var(--nb-blue-link);
}

/* Placa estompată = aplicație în lucru. Nu poartă cifre. */
.nb-tile--soon {
  background: var(--nb-bg-rail);
  border-style: dashed;
  border-color: var(--nb-line-dashed);
}
.nb-tile--soon .nb-tile__icon,
.nb-tile--soon .nb-tile__name,
.nb-tile--soon .nb-tile__desc,
.nb-tile--soon .nb-tile__foot { color: var(--nb-text-muted); }

.nb-tiles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px;
}

/* ── Filele: navigarea ÎNTRE paginile unei aplicații (Q-X1) ───────────────
   Subliniate, nu chip-uri: chip-ul înseamnă de acum numai filtru. Fila
   curentă poartă aria-current="page" (legătură) sau aria-selected="true"
   (tablist), iar sublinierea albastră e informație, nu acțiune. Filele se
   înfășoară pe telefon: niciuna nu se ascunde într-o bandă derulată lateral
   (sub 390 px, „Jurnal” dispărea fără niciun semn). Nicio mișcare la schimbare:
   navigarea se face de zeci de ori pe zi, iar ce sosește e de citit. */
.nb-tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0 2px;
  margin: 0;
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--nb-line);
}
.nb-tabs > li { display: flex; align-items: center; }

.nb-tabs__tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--nb-s2);
  min-height: var(--nb-tab-h);
  margin: 0;
  padding: 0 var(--nb-s3);
  border: 0;
  border-radius: var(--nb-radius);
  background: none;
  font-family: var(--nb-font-body);
  font-size: var(--nb-size-md);
  font-weight: 600;
  line-height: 1;
  color: var(--nb-text-muted);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.nb-tabs > .nb-tabs__tab:first-child,
.nb-tabs > li:first-child > .nb-tabs__tab { padding-left: 0; }

.nb-tabs__tab:is([aria-current="page"], [aria-current="true"], [aria-selected="true"], .is-on) { color: var(--nb-text-max); }
.nb-tabs__tab:is([aria-current="page"], [aria-current="true"], [aria-selected="true"], .is-on)::after {
  content: "";
  position: absolute;
  left: var(--nb-s3);
  right: var(--nb-s3);
  bottom: -1px;
  height: 2px;
  background: var(--nb-blue-info);
}
.nb-tabs > .nb-tabs__tab:first-child::after,
.nb-tabs > li:first-child > .nb-tabs__tab::after { left: 0; }

/* Câte sunt în filă: cifră goală, tabulară, stinsă la zero (Q-X6). */
.nb-tabs__n {
  font-size: var(--nb-size-sm);
  color: var(--nb-blue-link);
  font-variant-numeric: tabular-nums;
}
/* Contorul care cere atenție (ADR-0009, decizia 8): același număr, în chihlimbariul de TEXT.
   Numai culoarea textului — niciodată fundal, insignă sau punct plin (#f6b23c nu umple nimic).
   Culoarea nu poartă singură sensul: lângă cifră, aplicația scrie ce numără, pentru cititorul
   de ecran (`3<span class="nb-sr"> semnalări</span>`). Stins rămâne contorul GOL sau cu
   `data-n="0"`: regula de mai jos câștigă prin specificitate. Un „0” scris numai ca text, fără
   `data-n`, rămâne chihlimbariu — la zero aplicația pune `data-n="0"` sau nu pune `--warn`. */
.nb-tabs__n--warn { color: var(--nb-amber-text); }
.nb-tabs__n:is(:empty, [data-n="0"]) { color: var(--nb-text-muted); }

/* Pașii unui singur lucru (o lucrare în șase pagini): aceleași file, cu număr. */
.nb-tabs--steps > li + li::before {
  content: "";
  width: 14px;
  height: 1px;
  background: var(--nb-line-control);
  opacity: .6;
}
/* Lista de pași e un container (ADR-0009, decizia 7): ce încape se hotărăște după lățimea
   LISTEI, nu a ecranului — în MAF, la 900–1024 px coloana din dreapta lasă pașilor 398–522 px,
   mai puțin decât pe o tabletă de 768. Spațiul de 2 px dintre pași trece din `gap` în marginea
   pasului (aceeași randare), ca pe rândul strâns să poată deveni marginea care împarte locul. */
.nb-tabs--steps {
  container: nb-steps / inline-size;
  column-gap: 0;
}
.nb-tabs--steps > li + li { margin-left: 2px; }
.nb-tabs__step {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  font-size: var(--nb-size-xs);
  color: var(--nb-text-muted);
  font-variant-numeric: tabular-nums;
}
.nb-tabs__tab:is([aria-current="page"], [aria-current="true"], [aria-selected="true"], .is-on) .nb-tabs__step {
  border-color: var(--nb-blue-info);
  color: var(--nb-blue-link);
}

/* Pașii pe un singur rând (ADR-0009, decizia 7; boardul, dosar-dupa). Cuvântul pasului stă în
   .nb-tabs__t. Șase pași cu toate cuvintele cer în MAF 713 px (728 cu contoare de două cifre);
   sub 730 px de listă fiecare pas păstrează numărul și contorul, iar cuvântul rămâne desenat
   numai la pasul curent. Celelalte cuvinte ies din desen ca .nb-sr (tăiate, nu display:none):
   rămân în numele filei, pentru cititorul de ecran și comanda vocală. Fiecare pas are 44 px
   lățime (ținta de atins). Peste 730 px nu se schimbă nimic.
   Sub 350 px de listă (telefoanele de 320–360 px) nici cuvântul curent nu mai încape lângă
   șase ținte de 44 px (cel mai lung caz din MAF, „2 Documente 12” curent cu „3 · 12” alături,
   cere 347 px): rămân numerele și contoarele; pasul curent se vede după chenarul albastru și
   sublinierea, iar titlul paginii îl numește. */
@container nb-steps (max-width: 729px) {
  /* O listă care se înfășoară nu strânge nimic: rupe rândul după mărimea de bază a fiecărui
     pas. De aceea liniuța pornește de la 0 (nu împinge pasul pe rândul următor) și crește până
     la 6 px numai din locul rămas; pasul se lățește spre stânga (flex-end), deci liniuța rămâne
     lipită de numărul lui, iar golul cade între pași, ca pe board (space-between). */
  .nb-tabs--steps > li + li {
    flex: 1 1 auto;
    justify-content: flex-end;
    margin-left: 0;
  }
  .nb-tabs--steps > li + li::before {
    flex: 1 1 0px;
    width: auto;
    max-width: 6px;
  }
  .nb-tabs--steps .nb-tabs__tab {
    justify-content: center;
    gap: 4px;
    min-width: var(--nb-hit);
    padding: 0 4px;
  }
  .nb-tabs--steps > li:first-child > .nb-tabs__tab { justify-content: flex-start; padding-left: 0; }
  .nb-tabs--steps .nb-tabs__tab::after { left: 4px; right: 4px; }
  .nb-tabs--steps > li:first-child > .nb-tabs__tab::after { left: 0; }
  .nb-tabs--steps .nb-tabs__tab:not([aria-current="page"], [aria-current="true"], [aria-selected="true"], .is-on) .nb-tabs__t {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
@container nb-steps (max-width: 349px) {
  .nb-tabs--steps .nb-tabs__t {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* ── Chip-uri: NUMAI filtre (Q-X1) ────────────────────────────────────────
   Un chip restrânge ce vezi pe pagina curentă. Pentru a merge pe altă pagină
   există filele. Starea aleasă: .nb-chip--on (numele din v1), aria-pressed
   (buton comutator) sau aria-current (legătură de filtru). `.nb-chip--active`
   NU există, nici ca alias: boardul l-a găsit ca greșeală în MAF (`filtre()`
   din Gestionează), iar pagina aprobată a trecut acele filtre pe file (Q-G5). */

.nb-chips,
.nb-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nb-s2);
}
/* O singură bandă de filtre sub file. A doua dimensiune intră în aceeași bandă,
   ca <select class="nb-input nb-select">, nu într-un al treilea rând de chip-uri
   (trei rânduri împingeau tabelul cu 220 px în jos la 390, SWEEP-maf). */
.nb-filters { gap: var(--nb-s2) var(--nb-s3); }
.nb-filters__label {
  font-size: var(--nb-size-xs);
  font-weight: 700;
  letter-spacing: var(--nb-track-label);
  text-transform: uppercase;
  color: var(--nb-text-muted);
}
.nb-filters .nb-select { width: auto; min-width: 10em; }

.nb-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: var(--nb-chip-h);
  margin: 0;
  padding: 0 var(--nb-s3);
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  background: none;
  font-family: var(--nb-font-body);
  font-size: var(--nb-size-sm);
  font-weight: 600;
  line-height: 1;
  color: var(--nb-text);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.nb-chip:is(.nb-chip--on, [aria-pressed="true"], [aria-current="page"], [aria-current="true"]) {
  border-color: var(--nb-blue-info);
  background: var(--nb-select-bg);
  color: var(--nb-text-max);
}

.nb-chip__count { color: var(--nb-blue-link); font-variant-numeric: tabular-nums; }

/* Filtrul care încă nu există: vizibil, dezactivat, <span>, deci nefocalizabil. */
.nb-chip--off {
  border-style: dashed;
  border-color: var(--nb-line-dashed);
  color: var(--nb-text-muted);
  cursor: default;
}

/* ── Tabelul ──────────────────────────────────────────────────────────────
   Tabel ADEVĂRAT, nu grilă de <div>. Își poartă singur derularea orizontală:
   învelișul .nb-table-wrap, cu tabindex="0", role="region" și aria-label, ca
   un om cu tastatura să-l poată derula. Trei pagini din patru îl uitaseră și
   ieșeau din ecran la 390 px (+100 … +366 px, SWEEP-parc). Plasa de siguranță de
   mai jos, sub 900 px, prinde tabelul care a rămas totuși fără înveliș. */

.nb-table-wrap {
  /* Blocul care conține: un .nb-sr (absolut) dintr-un <th> scăpa altfel din
     derulare și lărgea pagina cu toată lățimea tabelului (măsurat: 390 → 708). */
  position: relative;
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  border-radius: var(--nb-radius);
}

.nb-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--nb-bg-panel);
  border: 1px solid var(--nb-line);
  border-radius: var(--nb-radius);
}

.nb-th {
  padding: 14px var(--nb-s5);
  border-bottom: 1px solid var(--nb-line);
  font-size: var(--nb-size-xs);
  font-weight: 700;
  letter-spacing: var(--nb-track-th);
  text-transform: uppercase;
  color: var(--nb-text-muted);
  text-align: left;
  white-space: nowrap;
}

.nb-td {
  padding: 14px var(--nb-s5);
  border-bottom: 1px solid var(--nb-line-soft);
  font-size: var(--nb-size-base);
  color: var(--nb-text-strong);
  font-variant-numeric: tabular-nums;
}

.nb-table tr:last-child .nb-td { border-bottom: none; }

/* Tabelul dintr-un panou: panoul e deja cutia, deci tabelul nu mai desenează una. */
.nb-panel > .nb-table,
.nb-panel > .nb-table-wrap > .nb-table { border: 0; border-radius: 0; }

.nb-num { text-align: right; }
.nb-code { color: var(--nb-blue-link); font-weight: 600; white-space: nowrap; }
/* Textul secundar dintr-o celulă sau de lângă un titlu: 13, ca pe paginile
   aprobate (v1 îl ținea pe --nb-size-md, care cade acum pe 13). Nu 12: nicio
   regulă nu l-a coborât, iar legenda unei fotografii devenea mai mică. */
.nb-quiet { color: var(--nb-text-muted); font-size: var(--nb-size-md); }

/* Rândul care duce undeva: titlul e legătura rândului, iar ::after-ul ei
   acoperă tot rândul — o singură oprire de Tab, Ctrl+clic deschide o filă nouă.
   Celelalte controale din rând stau DEASUPRA acoperământului. Rândurile nu se
   scalează niciodată: un tabel care se mișcă nu se mai citește. */
.nb-row { position: relative; cursor: pointer; }
/* Înălțimea rândului nu mai depinde de conținut (AUDIT, „Row”): 10 / 22 și cel
   puțin 52 px pentru un rând de un singur rând de text; unul cu titlu + o linie
   dedesubt ajunge singur la ~60. `height` pe o celulă de tabel e un minim. O
   celulă cu un control (.nb-td--control) își păstrează umplutura ei de 7 px. */
.nb-row > .nb-td:not(.nb-td--control) {
  height: 52px;
  padding-top: 10px;
  padding-bottom: 10px;
}
.nb-row__open {
  color: inherit;
  text-decoration: none;
}
.nb-row__open::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
/* :not(.nb-sr): eticheta ascunsă a unui <select> din rând trebuie să rămână
   absolută; ridicată și ea, ocupa un rând și umfla rândul de la 52 la 74 px. */
.nb-row :is(button, select, input, textarea, a:not(.nb-row__open), label, summary):not(.nb-sr) { position: relative; z-index: 2; }
.nb-body .nb-row__open:focus-visible { outline: none; }
.nb-body .nb-row:has(.nb-row__open:focus-visible) {
  outline: 2px solid var(--nb-focus);
  outline-offset: -2px;
}
.nb-row__chev { width: 12px; padding-left: 0; text-align: right; }

/* Controlul dintr-o celulă (un <select> care atribuie rândul altui element):
   celula se strânge, controlul umple coloana. */
.nb-td--control { padding-top: 7px; padding-bottom: 7px; }
.nb-td--control :is(.nb-input, .nb-select) { min-width: 8em; }

/* Matricea de acoperire: ✓ / – pe perioadă × cont. Scurtă dinadins: varianta
   cu cuvinte întregi n-a încăput nici la 1440 px (SWEEP-parc, jurnalul paginii). */
.nb-matrix { width: auto; }
.nb-matrix :is(.nb-th, .nb-td) { padding: 6px 10px; text-align: center; font-size: var(--nb-size-sm); }
.nb-matrix :is(.nb-th, .nb-td):first-child { text-align: left; }
.nb-matrix__da { color: var(--nb-blue-link); font-weight: 700; }
.nb-matrix__nu { color: var(--nb-text-muted); }

/* ── Stări: formă ȘI cuvânt, niciodată numai culoare ──────────────────────
   Punctul plin = starea e cunoscută. Inelul = nu e (Q-X4): inel punctat stins
   pentru „necunoscut”, inel plin chihlimbariu pentru „uită-te aici”.
   Chihlimbariul de text (#f6b23c) NU umple nimic: umplerea chihlimbarie e a
   acțiunii. Roșul spune un fapt obiectiv („Expirat”, „Depășit”, Q14a) și are
   cuvântul lui; chihlimbariul cere atenție. */
.nb-state {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--nb-size-sm);
  font-weight: 600;
  color: var(--nb-text-muted);
  white-space: nowrap;
}

.nb-state__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

.nb-state--info { color: var(--nb-blue-link); }
.nb-state--ok { color: var(--nb-text-max); }
.nb-state--idle { color: var(--nb-text-muted); }
.nb-state--bad { color: var(--nb-red-text); }
.nb-state--warn { color: var(--nb-amber-text); }
.nb-state--unk { color: var(--nb-text-muted); }
.nb-state:is(.nb-state--warn, .nb-state--unk) .nb-state__dot {
  width: 8px;
  height: 8px;
  background: transparent;
  border: 1.5px solid currentColor;
}
.nb-state--unk .nb-state__dot { border-style: dashed; }

/* Legenda unei bare sau a unei matrice. Cheia ia raza din token (v1 avea
   1 px scris de mână, în trei locuri). */
.nb-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nb-s2) var(--nb-s4);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--nb-size-sm);
  color: var(--nb-text-muted);
}
.nb-legend__item { display: inline-flex; align-items: center; gap: 6px; }
.nb-legend__key {
  display: inline-block;
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: var(--nb-radius);
  background: var(--nb-blue-info);
}
.nb-legend__key--alt { background: var(--nb-line-control); }
.nb-legend__key--none { background: transparent; border: 1px dashed var(--nb-line-control); }
.nb-legend__key--must { background: transparent; border: 1px solid var(--nb-amber-text); }
.nb-legend__key--opt { background: transparent; border: 1px solid var(--nb-line-control); }

/* ── Bara de compoziție (nb-meter): din ce e făcut un întreg ─────────────
   Din Documente (AUDIT, „Duplicated CSS → one contract class”): câte avem,
   câte lipsesc și sunt obligatorii, câte sunt „dacă e cazul”. Lățimea fiecărei
   bucăți = numărul ei, prin --nb-n (style="--nb-n: 5"): o variabilă, nu o
   declarație care să bată o stare. Umplerea e informație, deci albastră;
   ce lipsește și e obligatoriu e un CONTUR chihlimbariu de text (#f6b23c nu
   umple nimic). Fără tranziție: lățimea e layout, iar layoutul nu se animă.
   Bara e role="img" cu aria-label care spune numerele; legenda (.nb-legend
   cu cheile --must / --opt) le spune și celor care văd. */
.nb-meter {
  display: flex;
  gap: 2px;
  height: 6px;
}
.nb-meter__seg {
  flex: var(--nb-n, 1) 1 0;
  min-width: 2px;
  border-radius: var(--nb-radius);
}
.nb-meter__seg--have { background: var(--nb-blue-info); }
.nb-meter__seg--must { border: 1px solid var(--nb-amber-text); }
.nb-meter__seg--opt { border: 1px solid var(--nb-line-control); }

/* ── Cronologia: ce s-a întâmplat, în ordine, și ce urmează ───────────────
   PROVIZORIE: nu a fost desenată pe board și nici aprobată (SWEEP-maf o
   propune ca „nb-timeline, o componentă pe board”); vine din MAF Avizare
   (.maf-tl), cu stările recitite prin Q-X4. Până o vede Teo, numele claselor
   pot rămâne, dar înfățișarea se poate schimba.
   Un șir de puncte legate de o linie de 1 px. Plin = un fapt cunoscut: făcut
   (albastru) sau refuzat (roșu, Q14a). Inelul = ce nu s-a încheiat: acum
   (albastru), urmează (punctat, stins) sau așteaptă pe cineva (punctat,
   chihlimbar de text: „uită-te aici”). */
.nb-timeline {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0 0 0 4px;
  list-style: none;
}
.nb-timeline__item {
  position: relative;
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr);
  gap: 14px;
  padding: 0 0 18px;
}
.nb-timeline__item:last-child { padding-bottom: 0; }
.nb-timeline__item::before {
  content: "";
  position: absolute;
  left: 7px;
  top: 14px;
  bottom: 0;
  width: 1px;
  background: var(--nb-line);
}
.nb-timeline__item:last-child::before { display: none; }
.nb-timeline__dot {
  position: relative;
  z-index: 1;
  width: 15px;
  height: 15px;
  margin-top: 2px;
  border: 1px solid var(--nb-line-control);
  border-radius: 50%;
  background: var(--nb-bg);
}
.nb-timeline__dot--done { border-color: var(--nb-blue-info); background: var(--nb-blue-info); }
.nb-timeline__dot--now { border: 4px solid var(--nb-blue-info); }
.nb-timeline__dot--bad { border-color: var(--nb-red-text); background: var(--nb-red-text); }
.nb-timeline__dot--next { border-style: dashed; }
.nb-timeline__dot--wait { border-style: dashed; border-color: var(--nb-amber-text); }
.nb-timeline__t {
  display: block;
  font-size: var(--nb-size-md);
  font-weight: 600;
  color: var(--nb-text-strong);
  font-variant-numeric: tabular-nums;
}
.nb-timeline__s {
  margin: 2px 0 0;
  font-size: var(--nb-size-sm);
  color: var(--nb-text-muted);
  text-wrap: pretty;
}

/* Jurnalul cu „anulează ultima schimbare”: anularea stă numai pe PRIMA
   intrare (cea mai nouă) și spune ce anulează; restul jurnalului e de citit. */
.nb-log {
  margin: 0;
  padding: 0;
  list-style: none;
}
.nb-log__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px var(--nb-s4);
  padding: 10px 0;
  border-top: 1px solid var(--nb-line-soft);
  font-size: var(--nb-size-md);
  color: var(--nb-text);
}
.nb-log__item:first-child { border-top: 0; }
.nb-log__when {
  font-size: var(--nb-size-sm);
  color: var(--nb-text-muted);
  font-variant-numeric: tabular-nums;
}

/* ── Câmpuri ──────────────────────────────────────────────────────────── */

.nb-field {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.nb-field__label {
  font-size: var(--nb-size-xs);
  font-weight: 600;
  letter-spacing: var(--nb-track-label);
  text-transform: uppercase;
  color: var(--nb-text-muted);
}

.nb-input {
  display: flex;
  align-items: center;
  width: 100%;
  height: var(--nb-control-h);
  margin: 0;
  padding: 0 var(--nb-s3);
  background: var(--nb-bg);
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  font-family: var(--nb-font-body);
  font-size: var(--nb-size-base);
  line-height: normal; /* nu ne sprijinim pe resetul gazdei */
  color: var(--nb-text-max);
  font-variant-numeric: tabular-nums;
}
.nb-input::placeholder { color: var(--nb-text-muted); }

/* Selectul poartă ȘI .nb-input: aceeași înălțime, același contur. Săgeata e a
   noastră (cea nativă diferă între browsere); culoarea ei e --nb-text-muted,
   scrisă aici fiindcă un data: URI nu poate citi var(). */
.nb-select {
  appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' fill='none' stroke='%238e959b' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 14px 14px;
  cursor: pointer;
}

/* Textul lung (un motiv, o notă): același câmp, pe mai multe rânduri. */
.nb-textarea {
  display: block;
  height: auto;
  min-height: 84px;
  padding: 10px var(--nb-s3);
  line-height: 1.5;
  resize: vertical;
}

/* Explicația de sub câmp și eroarea lui. Eroarea e roșie fiindcă e un fapt
   („data asta nu există”), iar câmpul își păstrează valoarea. Câmpul poartă
   aria-invalid="true" și aria-describedby spre eroare. */
.nb-field__hint {
  margin: 0;
  font-size: var(--nb-size-sm);
  color: var(--nb-text-muted);
}
.nb-field__error {
  margin: 0;
  font-size: var(--nb-size-sm);
  font-weight: 600;
  color: var(--nb-red-text);
}
.nb-input[aria-invalid="true"] { border-color: var(--nb-red-text); }
.nb-body .nb-input[aria-invalid="true"]:focus-visible { outline-color: var(--nb-red-text); }

/* „Schimbat, nesalvat”: un punct albastru lângă eticheta câmpului. */
.nb-dirty {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 6px;
  border-radius: 50%;
  background: var(--nb-blue-info);
  vertical-align: middle;
  opacity: 0;
  transform: scale(0);
}
:is(.is-dirty, [data-nb-dirty]) .nb-dirty,
.nb-dirty.is-on { opacity: 1; transform: none; }

.nb-fields-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}

/* ── Butoane ──────────────────────────────────────────────────────────────
   CEL MULT UN .nb-btn--amber pe STRATUL ACTIV. Cât e deschis un dialog modal,
   pagina din spate e inertă și întunecată și nu se numără; confirmarea din
   dialog e acțiunea lui. Nu se poate impune din CSS; se verifică pe pagină.

   Literă de propoziție implicit (Q14, Q-X3): „Salvează”, nu „SALVEAZĂ”.
   Antetul paginii păstrează versalele: o singură voce tare pe ecran. */

.nb-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 9 px între pictogramă / săgeată și text, ca în v1 și pe paginile aprobate.
     Nu --nb-s2 (8): 1 px mai puțin făcea rândul de acțiuni din antetul Mașinii
     să încapă la 390 px și butonul chihlimbariu să se strângă la 198 px, în loc
     să treacă pe rândul lui (proba de fidelitate, 30.09). */
  gap: 9px;
  /* Înălțimea e un minim, nu o cutie fixă: o etichetă pe care aplicația o lasă să se înfășoare
     (MAF, antetul de la 320 px: „Mai departe cu 2 semnalări”) crește butonul în loc să-și
     suprapună rândurile (3 px la line-height 1, cu 6 px de aer; recenzia pasului 3, JV-6). Pe un
     rând, 42 px ca înainte: 6 + 17 + 6 + 2 de chenar < 42. `fit-content`, nu `auto`: un
     buton dintr-un rând flex sau dintr-o grilă NU se întinde cât vecinul cel mai înalt (cu
     `height: 42px` nu se întindea; `auto` l-ar fi lăsat). */
  height: fit-content;
  min-height: var(--nb-btn-h);
  margin: 0;
  padding: 6px var(--nb-s5);
  border: 1px solid transparent;
  border-radius: var(--nb-radius);
  background: none;
  font-family: var(--nb-font-body);
  font-size: var(--nb-size-md);
  font-weight: 600;
  /* Explicit, nu moștenit (LEARNINGS N1: 0,4 px între Flask și Nuxt). 1em + 4 px (17 px la 13),
     nu 1: conturul literelor din Plus Jakarta Sans are ~1,23 em, deci la 1 două rânduri se
     suprapun. Pe un rând, textul cade pe același pixel ca la 1 (măsurat pe chrome.html: 17 px și
     1,2 identice pixel cu pixel; 1,25 și 16 px îl coboară cu 1 px — rotunjirea liniei). */
  line-height: calc(1em + 4px);
  letter-spacing: 0;
  text-transform: none;
  color: var(--nb-text-max);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.nb-page-head__actions .nb-btn {
  font-weight: 700;
  letter-spacing: var(--nb-track-btn);
  text-transform: uppercase;
}

.nb-btn--amber {
  background: var(--nb-amber);
  color: var(--nb-on-amber);
}

.nb-btn--ghost {
  border-color: var(--nb-line-control);
  color: var(--nb-text-max);
}

/* Butonul mic dintr-un rând sau dintr-o foaie. v1 nu-l avea; MAF îl definea
   singur, iar corecția de literă se scria de mână de șapte ori. */
.nb-btn--sm {
  gap: 7px;
  min-height: var(--nb-btn-sm-h);
  padding: 6px var(--nb-s3);
  font-size: var(--nb-size-md);
  font-weight: 600;
}

.nb-btn--block { width: 100%; }

/* Se lucrează: butonul își PĂSTREAZĂ mărimea, își schimbă verbul și arată
   rotitorul. Marcajul:
     <button class="nb-btn nb-btn--amber" aria-busy="false">
       <span class="nb-btn__idle">Generează</span>
       <span class="nb-btn__busy"><span class="nb-spin"></span>Se generează…</span>
     </button>
   Cele două etichete stau în aceeași celulă de grilă, deci butonul e cât cea
   mai lată dintre ele și nu sare. FĂRĂ aria-hidden pe __busy: eticheta ascunsă
   cu visibility iese singură din arborele de accesibilitate, deci numele
   butonului e mereu cel vizibil („Generează”, apoi „Se generează…”). Cu
   aria-hidden, butonul care lucrează rămânea fără niciun nume. Starea e aria-busy, NU aria-disabled: v1 punea
   .45 pe aria-disabled, care se citea „indisponibil”, iar opacitățile se
   compuneau. Primele 300 ms nu se schimbă nimic (Q-S1): un răspuns rapid nu
   clipește un rotitor. Butonul care lucrează nu mai reacționează la hover:
   nu oferă nimic încă. */
.nb-btn:has(> .nb-btn__busy) {
  display: inline-grid;
  grid-template-areas: "label";
  place-items: center;
}
.nb-btn__idle,
.nb-btn__busy {
  grid-area: label;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: inherit; /* același spațiu ca butonul: 9, sau 7 la --sm */
}
.nb-btn__busy { visibility: hidden; }
.nb-btn[aria-busy="true"] { cursor: progress; }
.nb-btn[aria-busy="true"] > .nb-btn__busy {
  visibility: visible;
  animation: nb-hold-hidden var(--nb-wait-show) step-end;
}
.nb-btn[aria-busy="true"] > .nb-btn__idle {
  visibility: hidden;
  animation: nb-hold-visible var(--nb-wait-show) step-end;
}
.nb-btn .nb-spin {
  width: 14px;
  height: 14px;
  border-width: 1.5px;
  border-top-color: var(--nb-blue-link);
}
.nb-btn--amber .nb-spin {
  border-color: color-mix(in srgb, var(--nb-on-amber) 25%, transparent);
  border-top-color: var(--nb-on-amber);
}
.nb-btn--ghost[aria-busy="true"] { border-color: var(--nb-blue-info); }

@keyframes nb-hold-hidden { from, to { visibility: hidden; } }
@keyframes nb-hold-visible { from, to { visibility: visible; } }

/* Formularul care lucrează: câmpurile se estompează la .7 după 300 ms (valoarea
   măsurată de Parc auto, D50), fără să devină indisponibile. */
form[aria-busy="true"] { cursor: progress; }
form[aria-busy="true"] :where(.nb-input, .nb-select, .nb-seg, .nb-check, textarea) {
  opacity: .7;
  animation: nb-hold-opaque var(--nb-wait-show) step-end;
}
@keyframes nb-hold-opaque { from, to { opacity: 1; } }

/* Rândul rezervat pentru „ce se întâmplă”: există GOL de la încărcare (o
   regiune live adăugată odată cu textul ei nu se anunță) și își ține înălțimea,
   ca nimic să nu sară. role="status" pe el. */
.nb-live {
  display: flex;
  align-items: flex-start;
  gap: var(--nb-s2);
  min-height: 20px;
  margin: 10px 0 0;
  font-size: var(--nb-size-md);
  line-height: 1.5;
  color: var(--nb-text);
}
.nb-live > * { animation: nb-rise var(--nb-dur-enter) var(--nb-ease-out) both; }
.nb-live .nb-ico { margin-top: 3px; color: var(--nb-blue-link); }

/* N-a ajuns la server: controlul e înapoi, ce s-a scris a rămas. Avertisment
   (chihlimbar de TEXT), nu fapt rău: se poate încerca din nou. */
.nb-fail {
  display: flex;
  align-items: flex-start;
  gap: var(--nb-s2);
  color: var(--nb-text);
}
.nb-fail .nb-ico { margin-top: 3px; color: var(--nb-amber-text); }
.nb-fail b { font-weight: 600; color: var(--nb-amber-text); }

@keyframes nb-rise { from { opacity: 0; transform: translateY(4px); } }

/* ── Sub 900px: șina devine bară jos ────────────────────────────────────── */

@media (max-width: 899px) {
  .nb-shell { flex-direction: column; }

  .nb-rail {
    position: fixed;
    z-index: 10;
    inset: auto 0 0 0;
    flex-direction: row;
    justify-content: center;
    width: auto;
    height: var(--nb-rail-h);
    padding: 0 var(--nb-s3);
    border-right: none;
    border-top: 1px solid var(--nb-line);
  }

  .nb-rail__mark,
  .nb-rail__me { display: none; }

  .nb-main { padding-bottom: var(--nb-rail-h); }

  /* Bara de jos e fixă: browserul aduce un control focalizat cu Tab lângă
     marginea de jos a ecranului, adică exact sub ea (la 390 px, „Data
     primirii” stătea acoperit 38 din 38 px — WCAG 2.4.11). Zona de derulare
     își rezervă înălțimea barei, plus aer. :has(), ca o pagină fără coajă să
     nu primească o margine de care n-are nevoie. */
  html:has(.nb-body .nb-rail) { scroll-padding-bottom: calc(var(--nb-rail-h) + var(--nb-s3)); }

  .nb-topbar,
  .nb-page-head,
  .nb-content { padding-left: var(--nb-s4); padding-right: var(--nb-s4); }

  /* Pe telefon bara cedează ca pe paginile aprobate: starea se strânge cu „…”,
     firimiturile se înfășoară pe două rânduri (niciun cuvânt tăiat), iar
     pagina curentă — „unde sunt” — nu cedează deloc până la 60% din bară.
     Varianta de dinainte ținea firimiturile întregi și strângea pagina
     curentă: la 390 px, „NMB_020” ajungea la 0 px și bara se termina cu un „/”
     (proba de fidelitate, 30.09). Bara crește dacă un nume lung cere un al
     treilea rând, în loc să-l taie. */
  .nb-topbar {
    height: auto;
    min-height: var(--nb-topbar-h);
  }
  .nb-topbar__here {
    flex: 0 0 auto;
    max-width: 60%;
    overflow-wrap: break-word;
  }
  .nb-topbar__state { flex-shrink: 1; }

  .nb-page-head {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--nb-s4);
  }
  .nb-page-head__actions { margin-left: 0; }
  /* Pe treaptă (Q7): 26, nu 30 ca în v1. */
  .nb-page-head__title { font-size: var(--nb-size-h2); }

  .nb-content { flex-direction: column; }
  .nb-content > * { width: 100%; }
  .nb-aside { width: 100%; }
  .nb-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Plasa de siguranță: un tabel rămas fără .nb-table-wrap derulează el însuși,
     în loc să lărgească pagina. Pe telefon, un tabel îngust nu mai umple lățimea
     — preț mic față de o pagină care fuge lateral. */
  .nb-table:where(:not(.nb-table-wrap > .nb-table)) {
    display: block;
    max-width: 100%;
    overflow-x: auto;
  }
}

/* ── Sub 600px: bara de sus spune numai unde ești ─────────────────────────
   Decizia 6 din ADR-0009: Teo a lăsat alegerea deschisă (30.09, „Confirm ca sa
   fie ok sa se vada frumos”), iar lead-ul a ales varianta asta. La 390 px bara
   întreagă nu încăpea: pe 29 din 44 de rute MAF starea era tăiată în mijlocul
   cuvântului („0 do…”; R11 din verifica-contract, care numără orice „…”, găsește
   37 din 44), iar firimiturile se rupeau câte un cuvânt pe rând („Aprobare /
   materiale”). Pe telefon rămân:
   - pagina curentă, întreagă, pe câte rânduri îi trebuie;
   - firimitura dinaintea ei, dacă e o legătură, ca „‹”: numele părintelui
     rămâne în DOM și e numele accesibil al legăturii, doar că nu se mai vede
     (text-indent + overflow; în modul de contrast ridicat al sistemului
     culoarea transparentă se pierde, deplasarea nu). Cutia are 44 × 44, adică
     ținta de atins; inelul e cel al oricărei legături;
   - starea, pe rândul ei, pe toată lățimea, înfășurată ca un text obișnuit:
     niciun „…”, niciun cuvânt tăiat; goală, nu ocupă rândul.
   Restul firimiturilor, cu „Nimbus” cu tot, pleacă numai când există o pagină
   curentă (acasă în hub „Nimbus” e singura firimitură și rămâne). Proiectul nu
   se pierde: în MAF stă în supratitlul antetului („Proiect Oanleic · NMB_020”).
   Numai CSS, pe marcajul pe care aplicațiile îl scriu deja. Tableta și ecranul
   mare nu văd blocul; întoarcerea = blocul șters. */
@media (max-width: 599px) {
  .nb-topbar {
    flex-wrap: wrap;
    align-items: center;
    column-gap: var(--nb-s2);
    row-gap: 0;
    padding-top: var(--nb-s1);
    padding-bottom: var(--nb-s1);
  }
  .nb-topbar:has(> .nb-topbar__here) > :is(.nb-topbar__crumb, .nb-topbar__sep) { display: none; }

  .nb-topbar > a.nb-topbar__crumb:has(+ .nb-topbar__sep + .nb-topbar__here) {
    position: relative;
    display: block;
    flex: 0 0 auto;
    width: var(--nb-hit);
    height: var(--nb-hit);
    /* Cutia de atins începe la 4 px de marginea ecranului (16 − 12), ca inelul
       de focalizare (2 px, la 2 px de cutie) să încapă întreg; vârful săgeții
       stă pe coloana de 16 px a paginii, sub care încep supratitlul și titlul. */
    margin-left: calc(var(--nb-s3) * -1);
    overflow: hidden;
    white-space: nowrap;
    text-indent: 100%;
    color: transparent;
    border-radius: var(--nb-radius);
  }
  /* „‹” desenat ca .nb-chev (trăsătură 1,8), întors: nu depinde de un glif din font.
     Pătratul de 8 px rotit cu 45° iese cu 1,66 px (4√2 − 4) în stânga locului lui;
     deplasarea asta îl aduce înapoi, ca vârful să cadă exact la 12 px în cutie,
     adică pe coloana de 16 px a paginii. */
  .nb-topbar > a.nb-topbar__crumb:has(+ .nb-topbar__sep + .nb-topbar__here)::before {
    content: "";
    position: absolute;
    top: 50%;
    left: calc(var(--nb-s3) + 1.66px);
    width: 8px;
    height: 8px;
    border-bottom: 1.8px solid var(--nb-text-muted);
    border-left: 1.8px solid var(--nb-text-muted);
    transform: translateY(-50%) rotate(45deg);
    transition: border-color var(--nb-dur-1) var(--nb-ease);
  }
  /* Apăsarea se vede și fără hover: pe telefon e singurul semn că atingerea a prins. */
  .nb-topbar > a.nb-topbar__crumb:has(+ .nb-topbar__sep + .nb-topbar__here):active::before { border-color: var(--nb-text-max); }

  /* Primul rând are înălțimea țintei de atins, cu sau fără „‹” (acasă în hub,
     „Nimbus” singur), ca bara să nu sară de la o pagină la alta. */
  .nb-topbar > :is(.nb-topbar__crumb, .nb-topbar__here) {
    display: flex;
    align-items: center;
    min-height: var(--nb-hit);
  }
  .nb-topbar__here {
    flex: 1 1 0;
    min-width: 0;
    max-width: none;
    overflow-wrap: break-word;
  }
  /* Spațiul de sub stare e al stării, nu al barei: o aplicație care ascunde
     starea (display: none) ia și spațiul cu ea, iar bara rămâne un singur rând
     de 44 px, centrat (4 + 44 + 4). Cu stare: 4 + 44 + starea + 8 = 12 sub ea. */
  .nb-topbar__state {
    flex: 0 0 100%;
    min-width: 0;
    margin-left: 0;
    padding-bottom: var(--nb-s2);
    overflow: visible;
    white-space: normal;
    text-overflow: clip;
    overflow-wrap: break-word;
  }
  .nb-topbar__state:empty { display: none; }
  /* Cu un cont după ea, starea coboară pe rândul ei și contul rămâne sus, lângă pagină. */
  .nb-topbar__state:has(+ .nb-topbar__utilities) { order: 1; }
  .nb-topbar__state + .nb-topbar__utilities { margin-left: auto; }
}
@media (max-width: 599px) and (hover: hover) {
  .nb-topbar > a.nb-topbar__crumb:has(+ .nb-topbar__sep + .nb-topbar__here):hover::before { border-color: var(--nb-text-max); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BLOC C2 — primitivele unui CALCULATOR (PRD-C2), din v1
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Numai pentru cititorul de ecran ─────────────────────────────────────── */
.nb-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Indiciul: „de ce contează asta?” — <details>, fără JavaScript ─────── */
.nb-hint {
  position: relative;
  display: inline-block;
  vertical-align: middle;
}

.nb-hint__btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  border: 1px solid var(--nb-line-control);
  border-radius: 50%;
  /* Pe treaptă: 11, nu 10 ca în v1. */
  font-size: var(--nb-size-xs);
  font-weight: 700;
  line-height: 1;
  color: var(--nb-text-muted);
  cursor: pointer;
  list-style: none;
}
.nb-hint__btn::-webkit-details-marker { display: none; }
.nb-hint[open] .nb-hint__btn { color: var(--nb-text-max); border-color: var(--nb-blue-info); }
/* Indiciul de lângă marginea din dreapta (coloana îngustă, capătul unui rând):
   panoul se deschide spre stânga, altfel iese din ecran. */
.nb-hint--end .nb-hint__panel { left: auto; right: 0; }

.nb-hint__panel {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  width: max-content;
  max-width: 320px;
  margin-top: var(--nb-s2);
  padding: var(--nb-s3);
  background: var(--nb-bg-raised);
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  font-size: var(--nb-size-sm);
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: normal;
  text-transform: none;
  color: var(--nb-text);
  text-wrap: pretty;
}

/* ── Nota: un adevăr despre rezultat, nu o alertă ─────────────────────────
   Muchia spune rolul: albastru = informație, chihlimbar de TEXT = avertisment.
   --lock: nu se mai modifică după o schimbare de stare (o lucrare deja transmisă, de exemplu). */
.nb-note {
  margin: 0;
  padding: var(--nb-s3);
  background: var(--nb-bg-rail);
  border: 1px solid var(--nb-line);
  border-left: 2px solid var(--nb-blue-info);
  border-radius: var(--nb-radius);
  font-size: var(--nb-size-sm);
  line-height: 1.55;
  color: var(--nb-text);
  text-wrap: pretty;
}

.nb-note--warn {
  border-left-color: var(--nb-amber-text);
  color: var(--nb-amber-text);
}

.nb-note--lock {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: var(--nb-size-md);
}
.nb-note--lock .nb-ico { margin-top: 3px; color: var(--nb-blue-link); }
.nb-note--lock b { color: var(--nb-text-max); }

/* De ce e indisponibil un control: scris lângă el, nu într-un tooltip. */
.nb-why {
  margin: 0;
  max-width: 34ch;
  font-size: var(--nb-size-sm);
  line-height: 1.45;
  color: var(--nb-text);
}

/* ── Comutatorul între două-trei moduri ───────────────────────────────────
   Butoane adevărate cu aria-pressed (sau role="radio" + aria-checked), fără
   indicator care alunecă. v1 avea overflow: hidden pe grup, care tăia inelul
   de focalizare al FIECĂRUI segment la o fâșie; în v2 grupul nu mai taie, iar
   inelul stă ÎNĂUNTRUL segmentului (-4 px), unde nu-l poate tăia nimic. */
.nb-seg {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
}

.nb-seg__btn {
  position: relative;
  height: var(--nb-control-h);
  margin: 0;
  padding: 0 var(--nb-s3);
  border: none;
  border-right: 1px solid var(--nb-line-control);
  border-radius: 0;
  background: none;
  font-family: var(--nb-font-body);
  /* 13, ca în v1 (--nb-size-md) și pe paginile aprobate; segmentul e un
     control, nu o notă. */
  font-size: var(--nb-size-md);
  font-weight: 600;
  line-height: 1;
  color: var(--nb-text);
  white-space: nowrap;
  cursor: pointer;
}
.nb-seg__btn:first-child { border-radius: calc(var(--nb-radius) - 1px) 0 0 calc(var(--nb-radius) - 1px); }
.nb-seg__btn:last-child { border-right: none; border-radius: 0 calc(var(--nb-radius) - 1px) calc(var(--nb-radius) - 1px) 0; }
:where(.nb-seg__btn) { outline-offset: 0; }
.nb-body .nb-seg__btn:focus-visible { outline-offset: -4px; }

.nb-seg__btn:is(.nb-seg__btn--on, [aria-pressed="true"], [aria-checked="true"]) {
  background: var(--nb-select-bg);
  color: var(--nb-text-max);
}

/* ── Bifa, desenată de noi (appearance: none o scoate din shadow DOM) ──── */
.nb-check {
  display: flex;
  align-items: flex-start;
  gap: var(--nb-s3);
  padding: var(--nb-s3);
  background: var(--nb-bg);
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  cursor: pointer;
}

.nb-check__box {
  appearance: none;
  flex-shrink: 0;
  width: 17px;
  height: 17px;
  margin: 2px 0 0;
  background: var(--nb-bg-panel);
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  cursor: pointer;
}
.nb-check__box:checked {
  background: var(--nb-blue-info);
  border-color: var(--nb-blue-info);
  /* Culoarea bifei e --nb-bg, scrisă aici fiindcă un data: URI nu citește var(). */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-6' fill='none' stroke='%2317191b' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size: 15px 15px;
  background-position: center;
  background-repeat: no-repeat;
}

.nb-check__text {
  font-size: var(--nb-size-base);
  font-weight: 600;
  color: var(--nb-text-max);
}

.nb-check__hint {
  display: block;
  margin-top: 2px;
  font-size: var(--nb-size-sm);
  font-weight: 400;
  color: var(--nb-text-muted);
}

/* ── Câmp cu unitate lipită (lei, %) ──────────────────────────────────────── */
.nb-control {
  display: flex;
  align-items: stretch;
}

.nb-control .nb-input {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-right: none;
}

.nb-control__suffix {
  display: flex;
  align-items: center;
  padding: 0 var(--nb-s3);
  background: var(--nb-bg-panel);
  border: 1px solid var(--nb-line-control);
  border-radius: 0 var(--nb-radius) var(--nb-radius) 0;
  font-size: var(--nb-size-sm);
  font-weight: 600;
  color: var(--nb-text-muted);
  white-space: nowrap;
}

/* ── Cifra de rezultat ────────────────────────────────────────────────────── */
.nb-figure {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s1);
  min-width: 0;
}

.nb-figure__label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--nb-size-xs);
  font-weight: 600;
  letter-spacing: var(--nb-track-label);
  text-transform: uppercase;
  color: var(--nb-text-muted);
}

.nb-figure__value {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--nb-font-head);
  font-size: var(--nb-size-figure);
  font-weight: 600;
  line-height: var(--nb-lh-tight);
  color: var(--nb-text-max);
  font-variant-numeric: tabular-nums;
}

.nb-figure--sm .nb-figure__value { font-size: var(--nb-size-figure-sm); }

.nb-figure__unit {
  font-family: var(--nb-font-body);
  font-size: var(--nb-size-sm);
  font-weight: 600;
  color: var(--nb-text-muted);
}

.nb-figure__note {
  margin: 0;
  font-size: var(--nb-size-sm);
  color: var(--nb-text-muted);
  font-variant-numeric: tabular-nums;
}

/* ── Rândul cheie–valoare ─────────────────────────────────────────────────── */
.nb-rows {
  display: flex;
  flex-direction: column;
}

.nb-kv {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--nb-s4);
  padding: 10px 0;
  border-bottom: 1px solid var(--nb-line-soft);
}
.nb-rows .nb-kv:last-child { border-bottom: none; }

.nb-kv__key {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--nb-size-md);
  color: var(--nb-text-muted);
}

.nb-kv__val {
  font-size: var(--nb-size-base);
  font-weight: 600;
  color: var(--nb-text-strong);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* ── Secțiunea dintr-un panou ─────────────────────────────────────────────── */
.nb-sec {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s4);
  padding: var(--nb-s5);
  border-bottom: 1px solid var(--nb-line);
}
.nb-panel > .nb-sec:last-child { border-bottom: none; }

.nb-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.nb-pair > * + * {
  border-left: 1px solid var(--nb-line);
  padding-left: var(--nb-s5);
}

/* ── Valoarea copiabilă ───────────────────────────────────────────────────── */
.nb-copy {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  text-align: inherit;
  cursor: pointer;
}

.nb-copy__mark {
  align-self: center;
  flex-shrink: 0;
  color: var(--nb-text-muted);
  opacity: .35;
}
.nb-copy:focus-visible .nb-copy__mark { opacity: 1; color: var(--nb-blue-link); }

/* ── Bara de acțiuni de sub un rezultat ───────────────────────────────────── */
.nb-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nb-s3);
}

/* ── Mesajul efemer ───────────────────────────────────────────────────────
   „Copiat.” Colț dreapta-jos, role="status". Apare urcând 8 px dinspre locul
   lui; pleacă pe aceeași margine, mai repede (.is-leaving, chrome.js). */
.nb-toast {
  position: fixed;
  z-index: 30;
  right: var(--nb-s4);
  bottom: var(--nb-s4);
  max-width: calc(100vw - 2 * var(--nb-s4));
  padding: 10px var(--nb-s4);
  background: var(--nb-bg-raised);
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  font-size: var(--nb-size-md);
  font-weight: 600;
  color: var(--nb-text-max);
  animation: nb-toast-in var(--nb-dur-enter) var(--nb-ease-out) both;
}
.nb-toast.is-leaving { animation: nb-toast-out var(--nb-dur-exit) var(--nb-ease) both; }
@keyframes nb-toast-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes nb-toast-out { to { opacity: 0; transform: translateY(8px); } }

/* Două câmpuri pe rând, când trei ar fi prea strâmte. */
.nb-fields-row--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (max-width: 899px) {
  .nb-toast { bottom: calc(var(--nb-rail-h) + var(--nb-s3)); }

  .nb-fields-row,
  .nb-fields-row--2 { grid-template-columns: minmax(0, 1fr); }

  /* Pe telefon panoul nu mai depinde de unde stă semnul „?” (lângă o margine
     ar ieși din ecran, în stânga sau în dreapta): devine un card fix, lat cât
     ecranul minus marginile, deasupra barei de jos. */
  .nb-hint__panel,
  .nb-hint--end .nb-hint__panel {
    position: fixed;
    top: auto;
    left: var(--nb-s4);
    right: var(--nb-s4);
    bottom: calc(var(--nb-rail-h) + var(--nb-s3));
    width: auto;
    max-width: none;
    margin-top: 0;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BLOC V2 — ce lipsea din v1: golul, eșecul, anularea, dialogul, foaia
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Gol: de ce e gol și singurul lucru de făcut ─────────────────────────── */
.nb-empty {
  display: grid;
  justify-items: center;
  gap: 10px;
  margin: 0;
  padding: 34px var(--nb-s5) 36px;
  text-align: center;
}
.nb-empty .nb-nimbi { width: 96px; margin-bottom: 4px; }
/* Resetul e al componentei: un <p> sau un titlu pus în gol fără clasa lui nu
   aduce marginea browserului (13 px sus și jos au lăsat golul din Stări cu
   26 px mai lăsat decât pagina aprobată, 30.09). */
.nb-empty > :where(p, h2, h3) { margin: 0; }
.nb-empty__t {
  margin: 0;
  font-family: var(--nb-font-head);
  font-size: var(--nb-size-h3);
  font-weight: 600;
  line-height: var(--nb-lh-tight);
  color: var(--nb-text-max);
}
.nb-empty__s {
  margin: 0;
  max-width: 46ch;
  font-size: var(--nb-size-md);
  line-height: 1.55;
  color: var(--nb-text);
}
.nb-empty__act { margin-top: var(--nb-s2); }
/* Varianta de un rând, într-o listă care are deja titlu. */
.nb-empty--line {
  display: block;
  padding: 18px var(--nb-s5);
  text-align: left;
  font-size: var(--nb-size-md);
  color: var(--nb-text-muted);
}

/* Filtrul ascunde tot: spune ce s-a cerut și o singură cale înapoi. Fără
   mișcare la apariție: apare cât omul tastează. */
.nb-noresult {
  display: grid;
  justify-items: center;
  gap: var(--nb-s2);
  padding: 36px 20px 40px;
  text-align: center;
}
.nb-noresult .nb-ico { width: 28px; height: 28px; margin-bottom: 2px; stroke-width: 1.4; color: var(--nb-text-muted); }
.nb-noresult__t { margin: 0; font-size: var(--nb-size-lg); font-weight: 600; color: var(--nb-text-max); }
.nb-noresult__s { margin: 0 0 6px; max-width: 46ch; font-size: var(--nb-size-md); line-height: 1.55; color: var(--nb-text-muted); }

/* Nimic scadent: o singură frază calmă, în culoare plină, cu bifa. */
.nb-calm {
  display: flex;
  align-items: center;
  gap: var(--nb-s2);
  margin: 0;
  padding: 14px var(--nb-s5) 18px;
  font-size: var(--nb-size-lg);
  font-weight: 600;
  color: var(--nb-text-max);
}
.nb-calm .nb-ico { color: var(--nb-blue-link); }

/* Lipsește / n-ai acces: o pagină ÎN coajă, nu o redirecționare tăcută. */
.nb-page-state {
  display: grid;
  justify-items: start;
  gap: 10px;
  max-width: 620px;
  padding: 40px 0 56px;
}
.nb-page-state .nb-nimbi { width: 110px; margin-bottom: var(--nb-s2); }
.nb-page-state p { margin: 0; max-width: 52ch; font-size: var(--nb-size-lg); line-height: 1.6; color: var(--nb-text); }
.nb-page-state__act { display: flex; flex-wrap: wrap; gap: 10px; margin-top: var(--nb-s3); }
.nb-page-state__code { font-size: var(--nb-size-sm); color: var(--nb-text-muted); font-variant-numeric: tabular-nums; }

/* ── Anularea din rând (Teo, 30.09) ───────────────────────────────────────
   O acțiune reversibilă nu cere confirmare: se face, iar anularea apare ACOLO
   unde e atenția omului — în rândul schimbat, cu focalizarea pe ea — nu într-un
   mesaj sus pe pagină. Rămâne până la următoarea schimbare sau până pleci de pe
   pagină; un cronometru e opțional (data-nb-undo-ttl, chrome.js) și stă pe loc
   cât cursorul sau focalizarea sunt pe anulare. Fără JavaScript, „Anulează” e un
   formular POST obișnuit. */
.nb-undo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nb-s2) var(--nb-s3);
  padding: var(--nb-s2) 10px var(--nb-s2) var(--nb-s3);
  background: var(--nb-bg-rail);
  border: 1px solid var(--nb-line-control);
  border-left: 2px solid var(--nb-blue-info);
  border-radius: var(--nb-radius);
  font-size: var(--nb-size-sm);
  line-height: 1.5;
  color: var(--nb-text);
}
.nb-undo__t { display: flex; align-items: flex-start; gap: var(--nb-s2); flex: 1; min-width: 0; margin: 0; }
.nb-undo__t .nb-ico { margin-top: 2px; color: var(--nb-blue-link); }
.nb-undo__t q, .nb-undo__t b { color: var(--nb-text-max); }
.nb-undo .nb-btn { flex-shrink: 0; }
/* Urma unui rând scos din listă: stă pe locul rândului, cu anularea în ea. */
.nb-undo--row {
  min-height: 52px;
  padding: 10px var(--nb-s5);
  border: 0;
  border-top: 1px solid var(--nb-line-soft);
  border-radius: 0;
  font-size: var(--nb-size-md);
}
.nb-body .nb-undo:focus-visible { outline-offset: -2px; }

@media (max-width: 899px) {
  /* Într-un tabel care derulează lateral, anularea stă lipită de marginea
     vizibilă și e cât conținutul ei: lată cât tabelul, „Anulează” ajungea în
     afara ecranului, adică exact unde omul nu se uită. */
  .nb-table-wrap .nb-undo {
    position: sticky;
    left: 0;
    width: max-content;
    max-width: calc(100vw - 2 * var(--nb-s4) - 2 * var(--nb-s5) - 2px);
  }
}

/* ── „Aici s-a schimbat” (poarta de mișcare #1) ───────────────────────────
   După o salvare sau o redirecționare, rândul schimbat clipește O DATĂ în
   albastru, apoi revine la fundalul lui. Numai culoare, deci se vede și după
   o acțiune de la tastatură. Fără JavaScript: rândul-țintă al fragmentului
   (#rand-12 → <tr id="rand-12">) sau un atribut pus de server. */
@keyframes nb-flash { from { background-color: var(--nb-flash); } }
@keyframes nb-flash-field { from { background-color: var(--nb-select-bg-press); border-color: var(--nb-blue-info); } }
:is(.nb-flash, [data-nb-flash]):not(tr, .nb-input),
tr:is(.nb-flash, [data-nb-flash], :target) > .nb-td,
[data-nb-flash-target]:target {
  animation: nb-flash var(--nb-dur-flash) var(--nb-ease);
}
.nb-input:is(.nb-flash, [data-nb-flash]) { animation: nb-flash-field 1.3s var(--nb-ease); }

/* ── Dialogul (nb-dialog) ─────────────────────────────────────────────────
   <dialog class="nb-dialog">, deschis cu showModal(): pagina din spate devine
   inertă și întunecată, deci chihlimbariul ei nu se mai numără. Intră cu
   opacitate + scală .98 și iese pe un keyframe CU ALT NUME (același keyframe
   rulat invers nu mai trimite animationend, iar dialogul rămânea deschis).
   Deschis de la tastatură: nicio mișcare (.is-still, chrome.js).
   Confirmarea distructivă (Q-X7): butonul chihlimbariu poartă EFECTUL scris
   („Mută în coș”, „Scoate din parc”), nu „Da” / „OK”; focalizarea pornește pe
   alegerea sigură. Roșul rămâne pentru faptele rele, nu pentru butoane. */
.nb-dialog {
  width: min(520px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100dvh - 32px);
  margin: auto;
  padding: 0;
  overflow: auto;
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  background: var(--nb-bg-panel);
  color: var(--nb-text);
}
.nb-dialog::backdrop,
.nb-sheet::backdrop { background: var(--nb-scrim); }
.nb-dialog[open] { animation: nb-dialog-in var(--nb-dur-enter) var(--nb-ease-out) both; }
.nb-dialog.is-closing { animation: nb-dialog-out var(--nb-dur-exit) var(--nb-ease) both; }
.nb-dialog[open]::backdrop,
.nb-sheet[open]::backdrop { animation: nb-fade-in var(--nb-dur-enter) var(--nb-ease) both; }
.nb-dialog.is-closing::backdrop,
.nb-sheet.is-closing::backdrop { animation: nb-fade-out var(--nb-dur-exit) var(--nb-ease) both; }
:is(.nb-dialog, .nb-sheet).is-still,
:is(.nb-dialog, .nb-sheet).is-still::backdrop { animation: none; }
@keyframes nb-dialog-in { from { opacity: 0; transform: scale(.98); } }
@keyframes nb-dialog-out { to { opacity: 0; transform: scale(.98); } }
@keyframes nb-fade-in { from { opacity: 0; } }
@keyframes nb-fade-out { to { opacity: 0; } }

.nb-dialog__head { display: grid; gap: var(--nb-s2); padding: 22px 24px 4px; }
.nb-dialog__t {
  margin: 0;
  font-family: var(--nb-font-head);
  font-size: var(--nb-size-h2);
  font-weight: 600;
  line-height: var(--nb-lh-tight);
  color: var(--nb-text-max);
}
.nb-dialog__head p { margin: 0; font-size: var(--nb-size-md); line-height: 1.55; color: var(--nb-text); }
.nb-dialog__body { display: grid; gap: 18px; padding: 18px 24px 4px; }
/* Ce anume se schimbă: lucrul numit, pe fundalul câmpurilor. */
.nb-dialog__what {
  display: grid;
  gap: 3px;
  padding: var(--nb-s3) 14px;
  background: var(--nb-bg);
  border: 1px solid var(--nb-line);
  border-radius: var(--nb-radius);
}
.nb-dialog__what b { font-size: var(--nb-size-lg); font-weight: 600; color: var(--nb-text-max); overflow-wrap: anywhere; }
.nb-dialog__what small { font-size: var(--nb-size-sm); color: var(--nb-text-muted); overflow-wrap: anywhere; }
.nb-dialog__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px;
  padding: 18px 24px 22px;
}

/* ── Foaia (nb-sheet): o sarcină care nu merită o pagină ─────────────────
   <dialog class="nb-sheet"> din dreapta. Alunecă 16 px dinspre marginea de
   care aparține; fundalul se estompează. --wide pentru formulare mai late. */
.nb-sheet {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(460px, 100vw);
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  overflow: auto;
  border: 0;
  border-left: 1px solid var(--nb-line-control);
  background: var(--nb-bg-panel);
  color: var(--nb-text);
}
.nb-sheet--wide { width: min(600px, 100vw); }
.nb-sheet[open] { animation: nb-sheet-in var(--nb-dur-enter) var(--nb-ease-out) both; }
.nb-sheet.is-closing { animation: nb-sheet-out var(--nb-dur-exit) var(--nb-ease) both; }
@keyframes nb-sheet-in { from { opacity: 0; transform: translateX(16px); } }
@keyframes nb-sheet-out { to { opacity: 0; transform: translateX(16px); } }

.nb-sheet__head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding: 24px 26px 18px;
  background: var(--nb-bg-panel);
  border-bottom: 1px solid var(--nb-line);
}
.nb-sheet__head .nb-dialog__t { margin-top: 6px; }
.nb-sheet__body { display: grid; align-content: start; gap: 18px; padding: var(--nb-s5) 26px; }
.nb-sheet__foot { display: flex; flex-wrap: wrap; gap: 10px; padding: 4px 26px 26px; }

/* ── Dialogul care arată un document: fundal mai adânc ───────────────────
   Când în dialog stă o pagină albă (un document, o fotografie), fundalul de .6
   lasă pagina din spate să concureze cu ea; .72 o stinge (AUDIT, „Dialog”). */
.nb-dialog--media::backdrop,
.nb-viewer::backdrop { background: var(--nb-scrim-media); }

/* ── Vizualizatorul de document (nb-viewer) ──────────────────────────────
   UNUL pentru orice „uită-te la un document”: dosarul (cu secțiunile din
   OPIS), șablonul Word (o pagină, fără bandă), o anexă (N pagini, fără
   secțiuni). Din Dosar (pagina aprobată, dosar-dupa.css/.js), mutat aici ca
   MAF Dosar, Șablon și Documente să nu-l refacă fiecare.
     <dialog class="nb-viewer" aria-labelledby="…">
       <header class="nb-viewer__head">
         <div class="nb-viewer__id"><span class="nb-viewer__eye">…</span><h2>nume.pdf</h2></div>
         <div class="nb-viewer__pager">‹ <span class="nb-viewer__n">Pagina <b>1</b> din 3</span> ›</div>
         <div class="nb-seg nb-viewer__zoom">Pagina · Lățimea · 200%</div>
         <a class="nb-btn nb-btn--ghost nb-btn--sm nb-viewer__dl" download>…</a>
         <button class="nb-btn nb-btn--ghost nb-btn--sm" data-nb-close>Închide</button>
       </header>
       <div class="nb-viewer__body">
         <nav class="nb-viewer__strip">… .nb-viewer__thumb …</nav>
         <div class="nb-viewer__canvas" tabindex="0" role="region" data-zoom="…">
           <p class="nb-viewer__where">…</p>
           <div class="nb-viewer__sheet"><img class="nb-viewer__paper" alt="…"><p class="nb-viewer__status" role="status"></p></div>
         </div>
       </div>
       <footer class="nb-viewer__foot">… paginarea, pe telefon …</footer>
     </dialog>
   chrome.js îl deschide, îl închide și îi ține Tab-ul ca pe orice dialog
   (data-nb-dialog, data-nb-close, Esc, fundalul), cu focalizarea pe pagină,
   și schimbă mărimea (butoanele cu data-zoom → data-zoom pe
   .nb-viewer__canvas + aria-pressed). Răsfoitul (ce imagine urmează, banda de
   miniaturi, stările de încărcare) e al aplicației: numai ea știe de unde vin
   paginile. Sursa lui de pornire: dosar-dupa.js de pe board.
   Mărimea implicită, fără data-zoom (Q-D5): „Pagina” pe ecran mare, „Lățimea”
   pe telefon. Răsfoitul nu se animă: se face de zeci de ori pe document. */
.nb-viewer {
  width: min(1180px, calc(100vw - 40px));
  max-width: none;
  height: min(920px, calc(100dvh - 40px));
  max-height: none;
  margin: auto;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--nb-line);
  border-radius: var(--nb-radius);
  background: var(--nb-bg);
  color: var(--nb-text);
}
.nb-viewer[open] {
  display: flex;
  flex-direction: column;
  animation: nb-dialog-in var(--nb-dur-enter) var(--nb-ease-out) both;
}
.nb-viewer.is-closing { animation: nb-dialog-out var(--nb-dur-exit) var(--nb-ease) both; }
.nb-viewer[open]::backdrop { animation: nb-fade-in var(--nb-dur-enter) var(--nb-ease) both; }
.nb-viewer.is-closing::backdrop { animation: nb-fade-out var(--nb-dur-exit) var(--nb-ease) both; }
.nb-viewer.is-still,
.nb-viewer.is-still::backdrop { animation: none; }

.nb-viewer__head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: var(--nb-s3) var(--nb-s4) var(--nb-s3) var(--nb-s5);
  border-bottom: 1px solid var(--nb-line);
}
.nb-viewer__id { display: grid; gap: 3px; flex: 1; min-width: 0; }
.nb-viewer__eye {
  font-size: var(--nb-size-xs);
  font-weight: 600;
  letter-spacing: var(--nb-track-eyebrow);
  text-transform: uppercase;
  color: var(--nb-text-muted);
}
.nb-viewer__eye.is-warn { color: var(--nb-amber-text); }
.nb-viewer__id h2 {
  margin: 0;
  overflow: hidden;
  font: 600 var(--nb-size-h3)/1.15 var(--nb-font-head);
  color: var(--nb-text-max);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.nb-viewer__pager { display: flex; align-items: center; gap: var(--nb-s2); }
.nb-viewer__n {
  min-width: 104px;
  font-size: var(--nb-size-md);
  color: var(--nb-text-muted);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.nb-viewer__n b { color: var(--nb-text-max); font-weight: 600; }
.nb-viewer__step { width: var(--nb-btn-sm-h); padding: 0; }
.nb-viewer__zoom .nb-seg__btn { height: var(--nb-btn-sm-h); font-size: var(--nb-size-sm); }
.nb-viewer__dl { gap: 6px; }

.nb-viewer__body {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  flex: 1;
  min-height: 0;
}
.nb-viewer__body.is-single { grid-template-columns: minmax(0, 1fr); }
.nb-viewer__strip {
  overflow: auto;
  overscroll-behavior: contain;
  padding: var(--nb-s3) 14px 20px;
  border-right: 1px solid var(--nb-line);
  background: var(--nb-bg-rail);
  scrollbar-width: thin;
}
.nb-viewer__sec {
  margin: var(--nb-s3) 0 6px;
  overflow: hidden;
  font-size: var(--nb-size-xs);
  font-weight: 600;
  line-height: 1.35;
  color: var(--nb-text-muted);
}
.nb-viewer__sec:first-child { margin-top: 0; }
.nb-viewer__sec span { display: block; overflow: hidden; color: var(--nb-text); white-space: nowrap; text-overflow: ellipsis; }
/* Miniatura: o singură oprire de Tab pentru toată banda (tabindex 0 numai pe
   cea curentă, săgețile răsfoiesc); aplicația mută tabindex-ul. */
.nb-viewer__thumb {
  all: unset;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: 76px auto;
  align-items: end;
  gap: var(--nb-s2);
  width: 100%;
  margin-bottom: var(--nb-s2);
  border-radius: var(--nb-radius);
  cursor: pointer;
}
.nb-viewer__thumb img {
  display: block;
  width: 76px;
  height: 107px;
  border: 1px solid var(--nb-line-control);
  border-radius: var(--nb-radius);
  background: var(--nb-paper);
  transition: border-color var(--nb-dur-1) var(--nb-ease);
}
.nb-viewer__thumb span {
  font-size: var(--nb-size-xs);
  color: var(--nb-text-muted);
  font-variant-numeric: tabular-nums;
  transition: color var(--nb-dur-1) var(--nb-ease);
}
.nb-viewer__thumb[aria-current="page"] img { border: 2px solid var(--nb-blue-info); }
.nb-viewer__thumb[aria-current="page"] span { color: var(--nb-blue-link); font-weight: 600; }
.nb-body .nb-viewer__thumb:focus-visible { outline: 2px solid var(--nb-focus); outline-offset: 2px; }
@media (hover: hover) {
  .nb-viewer__thumb:not([aria-current]):hover img { border-color: var(--nb-text-max); }
  .nb-viewer__thumb:not([aria-current]):hover span { color: var(--nb-text-max); }
}

.nb-viewer__canvas {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  justify-items: center;
  gap: 10px;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
  padding: 14px 24px 24px;
  background: var(--nb-canvas-dim);
}
.nb-body .nb-viewer__canvas:focus-visible { outline: 2px solid var(--nb-focus); outline-offset: -2px; }
.nb-viewer__where {
  justify-self: stretch;
  margin: 0;
  overflow: hidden;
  font-size: var(--nb-size-sm);
  color: var(--nb-text-muted);
  text-align: center;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.nb-viewer__where b { color: var(--nb-text); font-weight: 600; }
.nb-viewer__sheet { position: relative; display: grid; place-items: start center; width: 100%; height: 100%; min-height: 0; }
.nb-viewer__paper { display: block; }

/* „Pagina”: încape toată (implicit pe ecran mare). */
.nb-viewer__canvas:where(:not([data-zoom]), [data-zoom="page"]) .nb-viewer__sheet { grid-template-rows: minmax(0, 1fr); }
.nb-viewer__canvas:where(:not([data-zoom]), [data-zoom="page"]) .nb-viewer__paper {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: top center;
}
/* „Lățimea” și „200%”: pagina se citește derulând. */
.nb-viewer__canvas:is([data-zoom="width"], [data-zoom="200"]) { grid-template-rows: auto auto; align-content: start; }
.nb-viewer__canvas:is([data-zoom="width"], [data-zoom="200"]) .nb-viewer__sheet { height: auto; place-items: start center; }
.nb-viewer__canvas[data-zoom="width"] .nb-viewer__paper { width: min(100%, 900px); height: auto; }
.nb-viewer__canvas[data-zoom="200"] .nb-viewer__sheet { place-items: start; }
.nb-viewer__canvas[data-zoom="200"] .nb-viewer__paper { width: 200%; max-width: none; height: auto; }

/* Încărcarea unei pagini (Q-S1): sub 300 ms nimic (pagina veche rămâne), apoi
   o foaie goală care spune ce se întâmplă; la 30 s, eșecul spus. Clasele le
   pune aplicația, pe aceleași praguri ca „se lucrează”. */
.nb-viewer__status {
  position: absolute;
  top: 40%;
  left: 50%;
  width: min(80%, 360px);
  margin: 0;
  translate: -50% 0;
  font-size: var(--nb-size-md);
  line-height: 1.5;
  color: var(--nb-text);
  text-align: center;
}
.nb-viewer__status:empty { display: none; }
.nb-viewer__sheet:is(.is-loading, .is-blank) .nb-viewer__paper { visibility: hidden; }
.nb-viewer__sheet.is-loading {
  width: auto;
  height: auto;
  max-height: 100%;
  aspect-ratio: .707;
  justify-self: center;
  outline: 1px dashed var(--nb-line-dashed);
  outline-offset: -1px;
}
.nb-viewer__sheet.is-failed .nb-viewer__status { color: var(--nb-red-text); }
/* Paginarea de jos există numai pe telefon, la îndemâna degetului. */
.nb-viewer__foot { display: none; }

@media (max-width: 899px) {
  .nb-viewer__body { grid-template-columns: minmax(0, 1fr); }
  .nb-viewer__strip { display: none; }
}
@media (min-width: 600px) and (max-width: 899px) {
  /* Numele primește rândul lui; controalele se înfășoară sub el, în loc să-l strângă. */
  .nb-viewer__head { flex-wrap: wrap; row-gap: 10px; }
  .nb-viewer__id { flex-basis: 100%; }
  .nb-viewer__dl { white-space: nowrap; }
}
@media (max-width: 599px) {
  /* Pe telefon: tot ecranul, iar paginarea coboară într-o bară de jos. */
  .nb-viewer {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    border: 0;
    border-radius: 0;
  }
  .nb-viewer__head { gap: 10px; padding: 10px 10px 10px var(--nb-s4); }
  .nb-viewer__head > :is(.nb-viewer__pager, .nb-viewer__zoom, .nb-viewer__dl) { display: none; }
  .nb-viewer__canvas { padding: 10px 10px var(--nb-s4); }
  /* Q-D5: fără data-zoom, pe telefon „Lățimea”. */
  .nb-viewer__canvas:not([data-zoom]) { grid-template-rows: auto auto; align-content: start; }
  .nb-viewer__canvas:not([data-zoom]) .nb-viewer__sheet { height: auto; grid-template-rows: none; place-items: start center; }
  .nb-viewer__canvas:not([data-zoom]) .nb-viewer__paper { width: min(100%, 900px); height: auto; object-fit: fill; }
  .nb-viewer__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--nb-s2);
    padding: var(--nb-s2) 10px calc(var(--nb-s2) + env(safe-area-inset-bottom));
    border-top: 1px solid var(--nb-line);
    background: var(--nb-bg-panel);
  }
  .nb-viewer__foot .nb-btn { width: var(--nb-hit); height: var(--nb-hit); padding: 0; }
  .nb-viewer__foot .nb-viewer__n { flex: 1; }
}

/* ── Motivul cerut, fără dialog: <details> ca poartă ──────────────────────
   Pentru o scoatere mică și reversibilă: „Scoate…” deschide un câmp obligatoriu
   și butonul care face efectul. Merge fără JavaScript. */
.nb-gate > summary { list-style: none; }
.nb-gate > summary::-webkit-details-marker { display: none; }
.nb-gate[open] > summary.nb-btn--ghost { border-color: var(--nb-blue-info); }
.nb-gate__body {
  display: grid;
  gap: var(--nb-s2);
  max-width: 360px;
  margin-top: var(--nb-s2);
}

@media (max-width: 899px) {
  .nb-dialog__head { padding: 20px 18px 4px; }
  .nb-dialog__body { padding: 16px 18px 4px; }
  .nb-dialog__foot { padding: 16px 18px 20px; }
  .nb-dialog__foot .nb-btn { flex: 1 1 auto; }
  .nb-dialog__t { font-size: var(--nb-size-h3); }
  .nb-sheet__head { padding: 20px 18px 16px; }
  .nb-sheet__body { padding: 18px; }
  .nb-sheet__foot { padding: 4px 18px 22px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BLOC N4 — INTRAREA (PRD-N4 partea A · ADR-0007), din v1
   ═════════════════════════════════════════════════════════════════════════ */

.nb-intrare {
  display: grid;
  grid-template-columns: minmax(0, 520px) minmax(0, 1fr);
  min-height: 100vh;
}

.nb-intrare__brand {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s6);
  padding: 44px 40px;
  background: var(--nb-bg-rail);
  border-right: 1px solid var(--nb-line);
}

.nb-intrare__brand-name {
  display: flex;
  align-items: center;
  gap: var(--nb-s3);
  font-family: var(--nb-font-head);
  /* Pe treaptă: 20, nu 22 ca în v1. */
  font-size: var(--nb-size-h3);
  font-weight: 600;
  letter-spacing: var(--nb-track-brand);
  text-transform: uppercase;
  color: var(--nb-text-max);
}

.nb-intrare__semn {
  display: flex;
  flex-grow: 1;
  align-items: center;
  justify-content: center;
  min-height: 210px;
}

.nb-intrare__scena {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--nb-s7) var(--nb-s6);
}

.nb-intrare__card {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 26px;
  width: 100%;
  max-width: 372px;
}

.nb-intrare__head {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s3);
}

/* Card headings may contain long unbroken identifiers. Keep them readable. */
.nb-intrare__card .nb-page-head__title { overflow-wrap: anywhere; }

.nb-intrare__lead {
  margin: 0;
  font-size: var(--nb-size-lg);
  line-height: 1.6;
  color: var(--nb-text);
  text-wrap: pretty;
}

.nb-intrare__form {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s4);
}

.nb-intrare__sau {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: var(--nb-size-xs);
  letter-spacing: var(--nb-track-label);
  text-transform: uppercase;
  color: var(--nb-text-muted);
}
.nb-intrare__sau::before,
.nb-intrare__sau::after {
  content: '';
  flex-grow: 1;
  height: 1px;
  background: var(--nb-line-control);
}

/* Calea care nu există încă: contur punctat, stins, nu se apasă. */
.nb-intrare__sso:disabled {
  flex-wrap: wrap;
  height: auto;
  min-height: var(--nb-btn-h);
  padding-top: 10px;
  padding-bottom: 10px;
  border-style: dashed;
  border-color: var(--nb-line-dashed);
  color: var(--nb-text-muted);
  white-space: normal;
  cursor: default;
}

.nb-intrare__tag {
  padding: 3px 6px;
  border: 1px solid var(--nb-blue-info);
  border-radius: var(--nb-radius);
  /* Pe treaptă: 11, nu 10 ca în v1. */
  font-size: var(--nb-size-xs);
  letter-spacing: var(--nb-track-label);
  color: var(--nb-blue-link);
  white-space: nowrap;
}

@media (max-width: 899px) {
  .nb-intrare {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr;
  }
  .nb-intrare__brand {
    padding: var(--nb-s4);
    border-right: none;
    border-bottom: 1px solid var(--nb-line);
  }
  .nb-intrare__semn { display: none; }
  .nb-intrare__scena {
    align-items: flex-start;
    padding: var(--nb-s6) var(--nb-s4);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BLOC N4 B — SEMNUL (norul de tablă), din v1, neschimbat
   Geometria stă în ../nimbi/*.svg (v1), inlinată în document; culorile aici.
   ═════════════════════════════════════════════════════════════════════════ */

.nb-nimbi {
  display: inline-flex;
  flex-shrink: 0;
  width: 150px;
  max-width: 100%;
  line-height: 0;
}
.nb-nimbi svg {
  display: block;
  width: 100%;
  height: auto;
  fill: none;
}
.nb-nimbi--mare { width: 280px; }
.nb-nimbi--hub {
  width: 150px;
  margin-left: auto;
  align-self: flex-end;
}

.nb-nimbi__nimb { stroke: var(--nb-blue-link); stroke-width: 2.5; }
.nb-nimbi__corp {
  fill: var(--nb-nimbi-tabla);
  stroke: var(--nb-text-muted);
  stroke-width: 2.5;
  stroke-linejoin: miter;
}
.nb-nimbi__falt {
  stroke: var(--nb-nimbi-falt);
  stroke-width: 1.2;
  stroke-dasharray: 5 5;
}
.nb-nimbi__flansa {
  fill: var(--nb-bg-panel);
  stroke: var(--nb-text-muted);
  stroke-width: 2.5;
  stroke-linejoin: miter;
}
.nb-nimbi__nit { stroke: var(--nb-nimbi-nit); stroke-width: 1.2; }
.nb-nimbi__ochi { fill: var(--nb-nimbi-ochi); }

.nb-nimbi--asteptare .nb-nimbi__nimb { stroke: var(--nb-blue-link); }

.nb-nimbi--lucreaza .nb-nimbi__nimb {
  stroke: var(--nb-blue-info);
  stroke-dasharray: 14 10;
  animation: nb-nimbi-rotire 1.4s linear infinite;
}
.nb-nimbi--lucreaza .nb-nimbi__ochi {
  fill: none;
  stroke: var(--nb-nimbi-ochi);
  stroke-width: 6;
  stroke-linecap: round;
}

.nb-nimbi--gata .nb-nimbi__nimb { stroke-width: 4; }
.nb-nimbi--gata .nb-nimbi__corp { stroke: var(--nb-blue-link); }
.nb-nimbi--gata .nb-nimbi__ochi,
.nb-nimbi--atentie .nb-nimbi__ochi {
  fill: none;
  stroke: var(--nb-nimbi-ochi);
  stroke-width: 5;
  stroke-linecap: round;
}

.nb-nimbi--atentie .nb-nimbi__nimb { stroke: var(--nb-amber); stroke-width: 3; }
/* REGULA 1, ÎN COD: dacă stratul paginii are deja un buton chihlimbariu,
   „Atenție” nu are voie să fie al doilea chihlimbar — nimbul cade pe albastru.
   Se numără numai butoanele din stratul paginii: nu cele dintr-un <dialog>
   (închis, e invizibil; deschis, pagina din spate e inertă — „un chihlimbar pe
   STRATUL ACTIV”) și nu cele ascunse. Fără excepția asta, confirmarea
   chihlimbarie a unui dialog închis (Q-X7) albăstrea „Atenție” pe orice pagină. */
.nb-body:has(.nb-btn--amber:not(dialog *, [hidden], [hidden] *)) .nb-nimbi--atentie .nb-nimbi__nimb { stroke: var(--nb-blue-info); }

.nb-nimbi--gol .nb-nimbi__nimb { stroke: var(--nb-nimbi-nimb-gol); stroke-width: 2; }
.nb-nimbi--gol .nb-nimbi__corp {
  fill: var(--nb-nimbi-tabla-gol);
  stroke: var(--nb-nimbi-falt);
  stroke-dasharray: 7 6;
}
.nb-nimbi--gol .nb-nimbi__flansa { fill: var(--nb-nimbi-tabla-gol); stroke: var(--nb-nimbi-falt); }
.nb-nimbi--gol .nb-nimbi__ochi { fill: var(--nb-steel); }

@keyframes nb-nimbi-rotire { to { stroke-dashoffset: -24; } }

@media (max-width: 899px) {
  .nb-nimbi--hub { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   INTERACȚIUNEA (ADR-0008, amendat de ADR-0009)
   ---------------------------------------------------------------------------
   Ordinea din fișier E regula: timpul → hover → apăsat → indisponibil.
   La aceeași specificitate câștigă poziția, deci „apăsat” stă DUPĂ „hover”.

   Specimenele din chrome.html pun o stare cu data-nb-state="hover | pressed |
   focus", ca pagina de referință să arate starea cu REGULA ADEVĂRATĂ, nu cu o
   copie. Atributul e numai pentru referință și probe; o aplicație nu-l scrie.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Timpul ───────────────────────────────────────────────────────────────
   Regulile de bază stau în :where() (specificitate zero), ca o componentă să
   le poată extinde. v1 scria `.nb-body a { transition-property: … }` la 0,1,1,
   care bătea regula paginii și tăia transformarea: apăsarea pe orice <a>
   sărea direct la scală în loc să curgă (AUDIT 4, propunere §12).
   Transformarea are durata ei: 160 ms înapoi, 100 ms în jos (--nb-t-transform
   se schimbă pe :active). Numai scală și săgeți; nicio proprietate de layout. */
:where(.nb-btn, .nb-chip, .nb-input, .nb-select, .nb-rail__btn, .nb-tabs__tab,
       .nb-seg__btn, .nb-hint__btn, .nb-link, .nb-body a, .nb-copy__mark,
       .nb-check__box, .nb-arrow, .nb-chev, .nb-dirty, .nb-tabs__step) {
  transition-property: color, background-color, border-color, outline-color, outline-offset, box-shadow, opacity, transform;
  transition-duration: var(--nb-dur-1), var(--nb-dur-1), var(--nb-dur-1), var(--nb-dur-1), var(--nb-dur-2), var(--nb-dur-1), var(--nb-dur-1), var(--nb-t-transform, var(--nb-dur-release));
  transition-timing-function: var(--nb-ease), var(--nb-ease), var(--nb-ease), var(--nb-ease), var(--nb-ease-out), var(--nb-ease), var(--nb-ease), var(--nb-t-transform-ease, var(--nb-ease-release));
}
/* Suprafețele respiră mai încet (180 ms). */
:where(.nb-body .nb-tile, .nb-table tbody .nb-td) {
  transition-property: color, background-color, border-color, outline-color, outline-offset, box-shadow, opacity, transform;
  transition-duration: var(--nb-dur-2), var(--nb-dur-2), var(--nb-dur-2), var(--nb-dur-1), var(--nb-dur-2), var(--nb-dur-2), var(--nb-dur-2), var(--nb-t-transform, var(--nb-dur-release));
  transition-timing-function: var(--nb-ease), var(--nb-ease), var(--nb-ease), var(--nb-ease), var(--nb-ease-out), var(--nb-ease), var(--nb-ease), var(--nb-t-transform-ease, var(--nb-ease-release));
}

/* ── Hover: numai unde există un indicator adevărat ───────────────────────
   Pe telefon, un :hover rămâne lipit după atingere și minte despre stare.
   Nimic indisponibil, nimic care lucrează, nimic ales nu reacționează. */
@media (hover: hover) {
  .nb-link:where(:not([aria-disabled="true"])):hover,
  .nb-link[data-nb-state="hover"] { color: var(--nb-text-max); }

  a.nb-topbar__crumb:hover { color: var(--nb-text-max); }

  .nb-rail__btn:where(:not(:disabled, [aria-disabled="true"], .nb-rail__btn--soon, .nb-rail__btn--on)):hover,
  .nb-rail__btn[data-nb-state="hover"] {
    color: var(--nb-text-max);
    background-color: var(--nb-hover-fill);
  }
  .nb-rail__btn--on:where(:not(:disabled, [aria-disabled="true"])):hover {
    background-color: var(--nb-bg-raised);
    color: var(--nb-text-max);
  }

  .nb-btn--amber:where(:not(:disabled, [aria-disabled="true"], [aria-busy="true"])):hover,
  .nb-btn--amber[data-nb-state="hover"] {
    background-color: var(--nb-amber-hover);
    box-shadow: inset 0 1px 0 var(--nb-amber-sheen);
  }
  .nb-btn--ghost:where(:not(:disabled, [aria-disabled="true"], [aria-busy="true"])):hover,
  .nb-btn--ghost[data-nb-state="hover"] {
    border-color: var(--nb-text-max);
    background-color: var(--nb-hover-fill);
  }

  .nb-chip:where(:not(:disabled, [aria-disabled="true"], .nb-chip--off, .nb-chip--on, [aria-pressed="true"], [aria-current="page"], [aria-current="true"])):hover,
  .nb-chip[data-nb-state="hover"] {
    border-color: var(--nb-text);
    background-color: var(--nb-hover-fill);
    color: var(--nb-text-max);
  }
  .nb-chip:where(.nb-chip--on, [aria-pressed="true"], [aria-current="page"], [aria-current="true"]):where(:not(:disabled, [aria-disabled="true"])):hover {
    background-color: var(--nb-select-bg-hover);
    border-color: var(--nb-blue-link);
    color: var(--nb-text-max);
  }

  .nb-seg__btn:where(:not(:disabled, [aria-disabled="true"], .nb-seg__btn--on, [aria-pressed="true"], [aria-checked="true"])):hover,
  .nb-seg__btn[data-nb-state="hover"] {
    background-color: var(--nb-hover-fill);
    color: var(--nb-text-max);
  }
  .nb-seg__btn:where(.nb-seg__btn--on, [aria-pressed="true"], [aria-checked="true"]):where(:not(:disabled, [aria-disabled="true"])):hover {
    background-color: var(--nb-select-bg-hover);
    color: var(--nb-text-max);
  }

  .nb-tabs__tab:where(:not(:disabled, [aria-disabled="true"], [aria-current="page"], [aria-current="true"], [aria-selected="true"], .is-on)):hover,
  .nb-tabs__tab[data-nb-state="hover"] { color: var(--nb-text-max); }
  .nb-tabs__tab:where(:not([aria-current="page"], [aria-current="true"], [aria-selected="true"], .is-on)):hover .nb-tabs__step,
  .nb-tabs__tab[data-nb-state="hover"] .nb-tabs__step {
    border-color: var(--nb-text);
    color: var(--nb-text-max);
  }

  .nb-input:where(:not(:disabled, [aria-disabled="true"], :focus, [aria-invalid="true"])):hover,
  .nb-input[data-nb-state="hover"] {
    border-color: var(--nb-text);
    background-color: color-mix(in srgb, var(--nb-bg) 70%, var(--nb-bg-panel));
  }

  .nb-hint__btn:hover,
  .nb-hint__btn[data-nb-state="hover"] { color: var(--nb-text-max); border-color: var(--nb-text-max); }

  .nb-copy:hover .nb-copy__mark { opacity: 1; color: var(--nb-blue-link); }

  .nb-tile:where(:not(.nb-tile--soon, [aria-disabled="true"])):hover,
  .nb-tile[data-nb-state="hover"] {
    background-color: color-mix(in srgb, var(--nb-bg-panel), var(--nb-text-max) 2.4%);
    border-color: var(--nb-text);
  }

  .nb-table tbody tr:where(:not([aria-disabled="true"])):hover > .nb-td,
  .nb-table tbody tr[data-nb-state="hover"] > .nb-td { background-color: var(--nb-row-hover); }
  .nb-row:where(:not([aria-disabled="true"])):hover > .nb-td:first-child,
  .nb-row[data-nb-state="hover"] > .nb-td:first-child { box-shadow: inset 2px 0 0 var(--nb-blue-info); }
  :is(.nb-row:hover, .nb-row[data-nb-state="hover"]) .nb-chev { opacity: 1; stroke: var(--nb-text-max); }
  :is(.nb-row:hover, .nb-row[data-nb-state="hover"]) .nb-row__open { color: var(--nb-blue-link); }
}

/* Mișcarea de la hover: săgețile alunecă 2 px spre unde duc. Numai cu un
   indicator adevărat și numai dacă omul n-a cerut mai puțină mișcare. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  :is(.nb-btn, .nb-link, .nb-tile):where(:not(:disabled, [aria-disabled="true"], [aria-busy="true"], .nb-tile--soon)):hover .nb-arrow:not(.nb-arrow--back),
  [data-nb-state="hover"] .nb-arrow:not(.nb-arrow--back) { transform: translateX(var(--nb-nudge)); }
  :is(.nb-btn, .nb-link):where(:not(:disabled, [aria-disabled="true"], [aria-busy="true"])):hover .nb-arrow--back,
  [data-nb-state="hover"] .nb-arrow--back { transform: translateX(calc(var(--nb-nudge) * -1)); }
  :is(.nb-row:hover, .nb-row[data-nb-state="hover"]) .nb-chev { transform: translateX(var(--nb-nudge)); }
}

/* ── Apăsat: DUPĂ hover ───────────────────────────────────────────────────
   Culoarea se schimbă mereu. Scala (Restrained) numai de la indicator:
   :not(:focus-visible) scoate apăsarea de la tastatură — Space pe un buton
   focalizat cu Tab pune :active, dar și :focus-visible; clicul nu pune
   :focus-visible pe un buton. Tastatura se repetă toată ziua: n-o animăm. */
.nb-btn--amber:where(:not(:disabled, [aria-disabled="true"], [aria-busy="true"])):active,
.nb-btn--amber[data-nb-state="pressed"] {
  background-color: var(--nb-amber-press);
  box-shadow: none;
}
.nb-btn--ghost:where(:not(:disabled, [aria-disabled="true"], [aria-busy="true"])):active,
.nb-btn--ghost[data-nb-state="pressed"] {
  border-color: var(--nb-text-max);
  background-color: var(--nb-ghost-press);
}
.nb-chip:where(:not(:disabled, [aria-disabled="true"], .nb-chip--off)):active,
.nb-chip[data-nb-state="pressed"],
.nb-seg__btn:where(:not(:disabled, [aria-disabled="true"])):active,
.nb-seg__btn[data-nb-state="pressed"] {
  color: var(--nb-text-max);
  border-color: var(--nb-text);
  background-color: var(--nb-press-fill);
}
.nb-chip:where(.nb-chip--on, [aria-pressed="true"], [aria-current="page"], [aria-current="true"]):where(:not(:disabled, [aria-disabled="true"])):active,
.nb-seg__btn:where(.nb-seg__btn--on, [aria-pressed="true"], [aria-checked="true"]):where(:not(:disabled, [aria-disabled="true"])):active {
  background-color: var(--nb-select-bg-press);
  color: var(--nb-text-max);
}
.nb-chip:where(.nb-chip--on, [aria-pressed="true"], [aria-current="page"], [aria-current="true"]):where(:not(:disabled, [aria-disabled="true"])):active { border-color: var(--nb-blue-link); }
.nb-tabs__tab:where(:not(:disabled, [aria-disabled="true"])):active,
.nb-tabs__tab[data-nb-state="pressed"] { color: var(--nb-text-max); }
.nb-rail__btn:where(:not(:disabled, [aria-disabled="true"], .nb-rail__btn--soon)):active,
.nb-rail__btn[data-nb-state="pressed"] {
  background-color: var(--nb-ghost-press);
  color: var(--nb-text-max);
}
.nb-rail__btn--on:where(:not(:disabled, [aria-disabled="true"])):active { background-color: var(--nb-bg-raised-press); }
.nb-table tbody tr.nb-row:where(:not([aria-disabled="true"])):active > .nb-td,
.nb-table tbody tr.nb-row[data-nb-state="pressed"] > .nb-td { background-color: var(--nb-press-fill); }

@media (prefers-reduced-motion: no-preference) {
  :is(.nb-btn, .nb-tabs__tab):where(:not(:disabled, [aria-disabled="true"], [aria-busy="true"], :focus-visible)):active,
  :is(.nb-btn, .nb-tabs__tab)[data-nb-state="pressed"] {
    transform: scale(var(--nb-press));
    --nb-t-transform: var(--nb-dur-press);
    --nb-t-transform-ease: var(--nb-ease-out);
  }
  :is(.nb-chip, .nb-rail__btn):where(:not(:disabled, [aria-disabled="true"], .nb-chip--off, .nb-rail__btn--soon, :focus-visible)):active,
  :is(.nb-chip, .nb-rail__btn)[data-nb-state="pressed"],
  .nb-check:active .nb-check__box:where(:not(:disabled, :focus-visible)) {
    transform: scale(var(--nb-press-sm));
    --nb-t-transform: var(--nb-dur-press);
    --nb-t-transform-ease: var(--nb-ease-out);
  }
  .nb-tile:where(:not(.nb-tile--soon, [aria-disabled="true"], :focus-visible)):active,
  .nb-tile[data-nb-state="pressed"] {
    transform: scale(var(--nb-press-lg));
    --nb-t-transform: var(--nb-dur-press);
    --nb-t-transform-ease: var(--nb-ease-out);
  }
  /* Orice altă legătură: durata apăsării, ca o transformare a paginii să curgă. */
  .nb-body a:active { --nb-t-transform: var(--nb-dur-press); --nb-t-transform-ease: var(--nb-ease-out); }
}

/* Inelul de focalizare, forțat pentru specimenele din chrome.html. */
.nb-body [data-nb-state="focus"] {
  outline: 2px solid var(--nb-focus);
  outline-offset: 2px;
}
.nb-body .nb-seg__btn[data-nb-state="focus"] { outline-offset: -4px; }

/* ── Indisponibil (ADR-0008, neschimbat) ──────────────────────────────────
   Text alb compus la .45 pe panou ≥3:1. Nu pointer-events:none: ținta arată
   cursorul not-allowed. Semantica aria-disabled și anularea acțiunii rămân ale
   gazdei. Butonul care LUCREAZĂ nu e indisponibil: poartă aria-busy, nu asta. */
.nb-body :is(:disabled, [aria-disabled="true"]) {
  opacity: .45;
  cursor: not-allowed;
}
.nb-body :is(.nb-btn, .nb-chip, .nb-input, .nb-select, .nb-rail__btn, .nb-tabs__tab, .nb-seg__btn, .nb-link):is(:disabled, [aria-disabled="true"]) {
  color: var(--nb-text-max);
  background-color: transparent;
  border-color: var(--nb-line-dashed);
  box-shadow: none;
}
.nb-body :is(.nb-btn, .nb-chip):is(:disabled, [aria-disabled="true"]) { border-style: dashed; }
.nb-body :is(.nb-btn, .nb-chip):is(:disabled, [aria-disabled="true"]) :where(*) { color: inherit; }

/* ── 44 px de atins (Q-S4), scris O DATĂ ──────────────────────────────────
   Sub un indicator grosier, ținta crește la 44 px fără ca desenul să se
   schimbe: un pseudo-element centrat, parte din cutia controlului la atingere.
   Pe orizontală crește numai ce e mai îngust de 44. Câmpul nu poate avea
   pseudo-element, deci el crește de-adevăratelea. */
@media (pointer: coarse) {
  :is(.nb-btn, .nb-chip, .nb-seg__btn, .nb-hint__btn)::before {
    content: "";
    position: absolute;
    top: calc(50% - var(--nb-hit) / 2);
    bottom: calc(50% - var(--nb-hit) / 2);
    left: min(0px, calc(50% - var(--nb-hit) / 2));
    right: min(0px, calc(50% - var(--nb-hit) / 2));
  }
  .nb-chip { position: relative; }
  /* Numai câmpul de un rând: aceeași specificitate ca .nb-textarea și mai jos
     în fișier, regula strângea orice <textarea> de la 84 la ~61 px pe telefon
     (motivul din dialog, poarta cu motiv). */
  .nb-input:not(.nb-textarea) { min-height: var(--nb-hit); }
  .nb-tabs__tab { min-height: var(--nb-hit); }
  /* Chip-urile au 32 px desenați și 44 de atins: rândurile unei benzi care se
     înfășoară stau la 44 − 32 = 12 px, ca țintele să se atingă fără să se
     suprapună (la 8 px, chip-ul de jos fura 4 px din cel de sus). */
  :is(.nb-chips, .nb-filters) { row-gap: calc(var(--nb-hit) - var(--nb-chip-h)); }
}

/* ── Încărcarea (ADR-0008) + pragul de 300 ms (Q-S1) ──────────────────────
   Scheletul apare abia după 300 ms: o pagină care răspunde repede nu clipește
   forma a ceva ce a sosit deja. */
.nb-sk {
  display: block;
  border-radius: var(--nb-radius);
  background-color: var(--nb-bg-raised);
  background-image: linear-gradient(90deg, var(--nb-bg-raised) 25%, var(--nb-sk-sheen) 40%, var(--nb-bg-raised) 55%);
  background-size: 300% 100%;
  animation: nb-sk-licarire 1.2s linear infinite, nb-hold-hidden var(--nb-wait-show) step-end;
}
.nb-sk--text { height: 11px; }
.nb-sk--row { height: var(--nb-control-h); }
@keyframes nb-sk-licarire {
  from { background-position: 100% 0; }
  to { background-position: -100% 0; }
}
.nb-spin {
  display: inline-block;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  border: 2px solid var(--nb-line-dashed);
  border-top-color: var(--nb-text-muted);
  border-radius: 50%;
  animation: nb-spin-rotire .8s linear infinite;
}
@keyframes nb-spin-rotire {
  to { transform: rotate(360deg); }
}

/* ── Încărcarea la orice clic (ADR-0009, decizia 10; Teo, 02.10) ──────────
   „Pulsarea să fie frumoasă, premium, eventual cu un soft glow, să vezi clar că aștepți ceva
   să se încarce.” O singură stare, aceeași ca „se lucrează”: aria-busy="true" pe ce ai apăsat
   (legătură, filă, pas, buton, rând). chrome.js o pune la clic și la trimitere (secțiunea 6);
   o aplicație care navighează singură (fetch, router) o pune prin nbChrome.loading.start(el).
   Timpul e AL CSS-ULUI (întârzieri de tranziție și de animație), nu al unor cronometre JS și nici
   al lui requestAnimationFrame — un tab încetinit sau Chromium headless sub @view-transition nu
   mai amână indicatorul:
     0 ms    elementul apăsat: inel de 1 px în nuanța lui + o tentă (120 ms, ease-out);
     150 ms  strălucirea respiră (1,4 s dus-întors, ease-in-out, amplitudine mică) și apare bara
             albastră de 2 px din vârful ecranului, care crește încet și nu ajunge niciodată la
             capăt (nu știm cât mai durează, deci nu mințim un procent);
     300 ms  verbul și rotitorul pe butonul care trimite (Q-S1, neschimbat);
     400 ms  restul conținutului se estompează la .65 (200 ms) — nu și ce ai apăsat, nici bara
             de sus, nici rândul rezervat care vorbește.
   Nuanța e a elementului: albastru (informație) pentru file, legături, butoane secundare, rânduri;
   chihlimbar numai pe butonul care E deja chihlimbariu — același chihlimbar, nu încă unul. Bara de
   sus e mereu albastră. Strălucirea e a patra excepție numită de la „fără umbră” (tokens.css,
   Formă) și există numai cât elementul așteaptă. Sub reduced motion: inel static, bară statică,
   nimic nu respiră și nimic nu se estompează (Q13 rămâne, blocul de la coada fișierului). */
/* Specificitate (0,1,0): fila, pasul și rândul de mai jos o suprascriu fără să se întreacă cu ea. */
:where(.nb-body) :where(a, button, input[type="submit"], input[type="image"], [role="button"], [role="link"], [role="tab"])[aria-busy="true"] {
  --nb-load-ring: var(--nb-load-ring-blue);
  --nb-load-ring-on: var(--nb-load-ring-blue-on);
  --nb-load-glow: var(--nb-load-glow-blue);
  box-shadow: 0 0 0 1px var(--nb-load-ring), 0 0 0 0 transparent;
  cursor: progress;
  animation: nb-load-glow var(--nb-dur-breathe) ease-in-out var(--nb-wait-mark) infinite alternate;
}
/* Tenta: numai unde fundalul e liber (secundar, legătură, chip, șină). Acțiunea își ține chihlimbarul. */
:where(.nb-body) :where(a, button, [role="button"], [role="link"]):not(.nb-btn--amber, .nb-row__open, .nb-tabs__tab)[aria-busy="true"] {
  background-color: var(--nb-load-tint-blue);
}
/* Acțiunea apăsată rămâne apăsată (--nb-amber-press, aceeași nuanță, mai adâncă): reacția de la 0 ms
   pe butonul care e deja chihlimbariu, unde un inel de aceeași culoare abia s-ar vedea. */
:where(.nb-body) .nb-btn--amber[aria-busy="true"] {
  background-color: var(--nb-amber-press);
  --nb-load-ring: var(--nb-load-ring-amber);
  --nb-load-ring-on: var(--nb-load-ring-amber-on);
  --nb-load-glow: var(--nb-load-glow-amber);
}
@keyframes nb-load-glow {
  from { box-shadow: 0 0 0 1px var(--nb-load-ring), 0 0 0 0 transparent; }
  to { box-shadow: 0 0 0 1px var(--nb-load-ring-on), 0 0 14px 1px var(--nb-load-glow); }
}
@keyframes nb-load-breathe {
  from { opacity: .45; }
  to { opacity: 1; }
}

/* Fila și pasul: nu se încadrează. Linia filei apăsate apare și respiră (cu strălucire), iar la
   pas chenarul numărului se aprinde. aria-current rămâne pe pagina în care ești până sosește
   cealaltă: sublinierea fără strălucire e „aici ești”, cea care respiră e „acolo mergi”. */
:where(.nb-body) .nb-tabs__tab[aria-busy="true"] {
  box-shadow: none;
  animation: none;
  color: var(--nb-text-max);
}
:where(.nb-body) .nb-tabs__tab[aria-busy="true"]::after {
  content: "";
  position: absolute;
  left: var(--nb-s3);
  right: var(--nb-s3);
  bottom: -1px;
  height: 2px;
  background: var(--nb-blue-info);
  box-shadow: 0 0 8px 1px var(--nb-load-glow-blue);
  opacity: .45;
  animation: nb-load-breathe var(--nb-dur-breathe) ease-in-out var(--nb-wait-mark) infinite alternate;
}
.nb-tabs > .nb-tabs__tab:first-child[aria-busy="true"]::after,
.nb-tabs > li:first-child > .nb-tabs__tab[aria-busy="true"]::after { left: 0; }
:where(.nb-body) .nb-tabs__tab[aria-busy="true"] .nb-tabs__step {
  --nb-load-ring: var(--nb-load-ring-blue);
  --nb-load-ring-on: var(--nb-load-ring-blue-on);
  --nb-load-glow: var(--nb-load-glow-blue);
  border-color: var(--nb-blue-info);
  color: var(--nb-blue-link);
  animation: nb-load-glow var(--nb-dur-breathe) ease-in-out var(--nb-wait-mark) infinite alternate;
}

/* Rândul care duce undeva: legătura lui (.nb-row__open) acoperă tot rândul, deci rândul arată
   starea, celulă cu celulă (aceeași cale ca hover-ul și apăsarea), cu muchia albastră pe prima.
   Un tabel ale cărui rânduri devin cărți (celulele nu mai pictează nimic, ca în MAF sub 1400 px)
   poartă .nb-table--cards: atunci rândul pictează o dată, pe <tr>. */
:where(.nb-body) .nb-row__open[aria-busy="true"] { box-shadow: none; animation: none; background: none; }
.nb-table:not(.nb-table--cards) tbody tr.nb-row:has(.nb-row__open[aria-busy="true"]) > .nb-td {
  background-color: var(--nb-select-bg-press);
  animation: nb-load-row var(--nb-dur-breathe) ease-in-out var(--nb-wait-mark) infinite alternate;
}
.nb-table:not(.nb-table--cards) tbody tr.nb-row:has(.nb-row__open[aria-busy="true"]) > .nb-td:first-child { box-shadow: inset 2px 0 0 var(--nb-blue-info); }
.nb-table--cards tbody tr.nb-row:has(.nb-row__open[aria-busy="true"]) {
  background-color: var(--nb-select-bg-press);
  box-shadow: inset 2px 0 0 var(--nb-blue-info);
  animation: nb-load-row var(--nb-dur-breathe) ease-in-out var(--nb-wait-mark) infinite alternate;
}
/* Tenta rândului pornește plină (.22: peste hover-ul rândului, apăsarea trebuie să se vadă pe loc)
   și respiră spre .14. */
@keyframes nb-load-row {
  from { background-color: var(--nb-select-bg-press); }
  to { background-color: var(--nb-select-bg-hover); }
}

/* Numai referința (chrome.html, data-nb-state): starea oprită la 0 ms (inelul și tenta, încă fără
   respirație, eticheta încă cea obișnuită) și starea fără mișcare (aceleași valori ca în blocul
   reduced motion de la coada fișierului), puse cu regulile adevărate. O aplicație nu le scrie. */
.nb-body [data-nb-state="busy-0"][aria-busy="true"],
.nb-body [data-nb-state="busy-0"][aria-busy="true"]::after,
.nb-body [data-nb-state="busy-0"][aria-busy="true"] .nb-tabs__step { animation: none; }
.nb-body .nb-btn[data-nb-state="busy-0"][aria-busy="true"] > .nb-btn__busy { visibility: hidden; animation: none; }
.nb-body .nb-btn[data-nb-state="busy-0"][aria-busy="true"] > .nb-btn__idle { visibility: visible; animation: none; }
.nb-body [data-nb-state="busy-still"][aria-busy="true"]:not(.nb-tabs__tab, .nb-row__open) { animation: none; box-shadow: 0 0 0 2px var(--nb-load-ring-on); }
.nb-body .nb-tabs__tab[data-nb-state="busy-still"][aria-busy="true"]::after { animation: none; opacity: 1; }
.nb-body .nb-tabs__tab[data-nb-state="busy-still"][aria-busy="true"] .nb-tabs__step { animation: none; box-shadow: 0 0 0 1px var(--nb-blue-info); }

/* Butonul fără eticheta „se lucrează” scrisă în marcaj: chrome.js o adaugă la trimitere și îi
   fixează lățimea (data-nb-pin), ca să nu sară. Un verb mai lung decât butonul se taie. */
.nb-btn[data-nb-pin] > .nb-btn__busy { max-width: 100%; overflow: hidden; }

/* Bara de sus: un singur element, pus de chrome.js la încărcare (aria-hidden). Fixă, deci nu
   lărgește pagina; transform, deci nu mută nimic. Desenul de .nb-loadbar__line poate fi pus și
   de mână, într-un cadru, cu data-nb-state="on" (numai referința). */
.nb-loadbar {
  position: fixed;
  inset: 0 0 auto;
  z-index: 1000;
  height: 2px;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}
.nb-loadbar__line {
  position: absolute;
  inset: 0;
  background: var(--nb-blue-info);
  box-shadow: 0 0 8px 1px var(--nb-load-ring-blue);
  transform-origin: 0 50%;
  transform: scaleX(0);
}
:root[data-nb-loading] .nb-loadbar,
.nb-loadbar[data-nb-state="on"] {
  visibility: visible;
  opacity: 1;
  transition: opacity var(--nb-dur-1) var(--nb-ease-out) var(--nb-wait-mark);
}
:root[data-nb-loading] .nb-loadbar__line,
.nb-loadbar[data-nb-state="on"] .nb-loadbar__line {
  animation: nb-load-bar var(--nb-wait-give-up) cubic-bezier(.08, .7, .2, 1) var(--nb-wait-mark) both;
}
/* Repede la început (răspunsul obișnuit), apoi tot mai încet: la 30 s, 94 %. Niciodată 100 %. */
@keyframes nb-load-bar {
  0% { transform: scaleX(0); }
  4% { transform: scaleX(.45); }
  20% { transform: scaleX(.7); }
  60% { transform: scaleX(.86); }
  100% { transform: scaleX(.94); }
}

/* Conținutul care NU e pe drumul spre ce ai apăsat se estompează la 400 ms: fiecare frate al
   fiecărui strămoș al elementului apăsat (data-nb-load-src, pus de chrome.js), până la .nb-main
   (sau .nb-body, pe o pagină fără coajă). Ce ai apăsat rămâne întreg — rândul de tabel al unei
   legături de rând, întreg, nu numai celula ei (`:not(tr, tr *)`) —, bara de sus și rândul rezervat la fel. Se estompează subarborii, nu fiecare element, deci opacitățile nu se compun.
   Sub reduced motion nu se estompează nimic (Q13). */
@media (prefers-reduced-motion: no-preference) {
  :root[data-nb-loading] :is(.nb-main, .nb-body:not(:has(.nb-main)), :is(.nb-main, .nb-body:not(:has(.nb-main))) :has([data-nb-load-src]):not(tr, tr *)) > :not([data-nb-load-src], :has([data-nb-load-src]), .nb-topbar, .nb-loadbar, .nb-live, [role="status"], [aria-live], dialog, script, style, template),
  :is([data-nb-state="dim"], [data-nb-state="dim"] :has([data-nb-load-src])) > :not([data-nb-load-src], :has([data-nb-load-src]), .nb-loadbar) {
    opacity: .65;
    transition: opacity var(--nb-dur-2) var(--nb-ease) var(--nb-wait-dim);
  }
  /* Formularul care lucrează își estompa câmpurile la .7 (D50); sub estomparea paginii s-ar
     compune la .45. Cât se încarcă pagina, câmpurile rămân sub estomparea ei. */
  :root[data-nb-loading] form[aria-busy="true"] :where(.nb-input, .nb-select, .nb-seg, .nb-check, textarea) { opacity: 1; }
}

/* ── De la tastatură: nimic nu se mișcă ───────────────────────────────────
   chrome.js pune data-nb-keyboard pe <html> cât ultima intrare a fost o
   tastă. Culoarea rămâne (clipirea „aici s-a schimbat” e culoare, deci se
   vede); intrările cu mișcare (rândul „ce se întâmplă”, mesajul) apar pe loc. */
[data-nb-keyboard] :is(.nb-live > *, .nb-toast) { animation: none; }

/* Navigări între documente, fără JavaScript obligatoriu (ADR-0008). */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: var(--nb-dur-2);
  animation-timing-function: var(--nb-ease);
}

/* ── Reduced motion = NIMIC (Q13, ADR-0008 neschimbat) ────────────────────
   Nimic nu se mișcă și nimic nu se estompează: nicio tranziție, nicio
   animație — nici ale aplicației, sub .nb-body. Transformările de apăsare și de
   hover stau deja sub (prefers-reduced-motion: no-preference), deci nu există
   nici „saltul” fără tranziție. Stările rămân vizibile prin culoare.
   Două excepții, care nu sunt mișcare, ci timp: pragul de 300 ms al stării
   „se lucrează” și al scheletului. Clipirea „aici s-a schimbat” devine o
   muchie albastră statică (chrome.js o stinge după 3 s). */
@media (prefers-reduced-motion: reduce) {
  .nb-body, .nb-body *, .nb-body *::before, .nb-body *::after, .nb-body ::backdrop {
    transition: none !important;
    animation: none !important;
  }
  .nb-body .nb-btn[aria-busy="true"] > .nb-btn__busy { animation: nb-hold-hidden var(--nb-wait-show) step-end !important; }
  .nb-body .nb-btn[aria-busy="true"] > .nb-btn__idle { animation: nb-hold-visible var(--nb-wait-show) step-end !important; }
  .nb-body form[aria-busy="true"] :where(.nb-input, .nb-select, .nb-seg, .nb-check, textarea) { animation: nb-hold-opaque var(--nb-wait-show) step-end !important; }
  .nb-body .nb-sk { background-image: none; animation: nb-hold-hidden var(--nb-wait-show) step-end !important; }

  /* Încărcarea (decizia 10): o stare clară și STATICĂ, tot la 150 ms. Inelul elementului apăsat
     e plin de la început (2 px, fără respirație); linia filei apăsate e aprinsă; bara de sus stă
     întreagă, fără să crească. Apariția la 150 ms e timp, nu mișcare (step-end, ca nb-hold-*). */
  .nb-body :is(a, button, input[type="submit"], input[type="image"], [role="button"], [role="link"], [role="tab"])[aria-busy="true"]:not(.nb-tabs__tab, .nb-row__open) {
    box-shadow: 0 0 0 2px var(--nb-load-ring-on);
  }
  .nb-body .nb-tabs__tab[aria-busy="true"]::after { opacity: 1; }
  .nb-body .nb-tabs__tab[aria-busy="true"] .nb-tabs__step { box-shadow: 0 0 0 1px var(--nb-blue-info); }
  :root[data-nb-loading] .nb-body .nb-loadbar { animation: nb-hold-hidden var(--nb-wait-mark) step-end !important; }
  .nb-body .nb-loadbar__line { transform: none; }

  :is(.nb-flash, [data-nb-flash]):not(tr, .nb-input, [data-nb-flash-done]),
  tr:is(.nb-flash, [data-nb-flash], :target):not([data-nb-flash-done]) > .nb-td:first-child,
  [data-nb-flash-target]:target:not([data-nb-flash-done]) { box-shadow: inset 2px 0 0 var(--nb-blue-info); }
  .nb-input:is(.nb-flash, [data-nb-flash]):not([data-nb-flash-done]) { border-color: var(--nb-blue-info); }

  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}
