/* ============================================================================
   ECU-LAB — soft azure design (reference: BeTheme "BeDentist 4" language)
   Airy layout, rounded white cards with soft shadows, azure accent from the
   brand imagery, concentric-circle motif, Poppins type, monospace for
   technical data (SW/HW/ECU). Fonts self-hosted — zero external requests.
   ========================================================================== */

/* ------------------------------------------------------------------ fonts */
@font-face {
  font-family: "Poppins";
  src: url("/assets/fonts/Poppins-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("/assets/fonts/Poppins-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("/assets/fonts/Poppins-SemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("/assets/fonts/Poppins-Bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ----------------------------------------------------------------- tokens */
:root {
  --bg: #071019;             /* page background — very light azure          */
  --panel: #0d1822;          /* cards                                       */
  --ink: #f1f7fa;            /* deep blue ink                               */
  --ink-soft: #a4b8c4;
  --line: rgba(159,190,207,.16);           /* hairlines                                   */
  --accent: #20d6ef;         /* brand azure (hero, links, highlights)       */
  --accent-btn: #139fd0;     /* buttons — darker azure, AA with white text  */
  --accent-dark: #7fd6f6;
  --accent-ink: #031017;
  --accent-soft: rgba(32,214,239,.12);    /* pale circle tone from the brand imagery     */
  --hero-1: #0d1c27;         /* hero band gradient — from the reference     */
  --hero-2: #0a151e;
  --error: #ff796f;
  --error-bg: rgba(255,121,111,.11);
  --ok: #54e99a;
  --ok-bg: rgba(84,233,154,.11);
  --neutral-bg: rgba(154,184,201,.08);
  --shadow: 0 22px 70px rgba(0,0,0,.42);
  --shadow-soft: 0 12px 34px rgba(0,0,0,.26);
  --radius: 14px;
  --radius-s: 8px;
  --mono: var(--sans); /* monospace retired at client request */
  --sans: "Poppins", -apple-system, "Segoe UI", Arial, sans-serif;

  /* ---------------------------------------------------------------------
     Familiile de mai jos au inlocuit 218 culori scrise direct in fisier.
     Valorile sunt exact cele dinainte, deci nu s-a schimbat nimic vizual —
     rostul lor e ca tema sa se poata schimba dintr-un singur loc.
     --------------------------------------------------------------------- */
  --panel-2: #111f2a;  /* a doua suprafata: randuri, casute, preview  */
  --muted: #91a5b2;  /* text secundar, mai stins decat --ink-soft   */
  --line-strong: rgba(159,190,207,.30);  /* linie mai apasata decat --line              */
  --accent-line: rgba(32,214,239,.34);  /* chenar in familia albastra                  */
  --accent-bright: #8fe4f8;  /* albastru deschis, pe fundal inchis          */
  --ok-line: rgba(84,233,154,.3);
  --error-ink: #ffb3aa;
  --error-line: rgba(255,121,111,.32);
  --warn: #efa72c;  /* chihlimbar: atentionare, nu eroare          */
  --warn-bright: #ffc861;
  --warn-bg: rgba(239,167,44,.13);
  /* Umplere mai tare, pentru benzile care TREBUIE vazute (dispozitiv
     neverificat). 13% pe fundal aproape negru se pierde. */
  --warn-bg-strong: rgba(239,167,44,.20);
  --warn-ink: #f2c579;
  --warn-line: #5a4420;
  --violet: #a98cf0;  /* sursa manuala / stage 2                     */
  --violet-ink: #c9b6ff;
  --violet-bg: rgba(169,140,240,.15);
  --chart-stock: #5b7686;  /* liniile de referinta din grafice            */
  --chart-stock-2: #8a7a60;
  --chart-alt: #c98a52;
  /* "onink" = ce se scrie PESTE o suprafata inchisa (banner de cookie).
     Pe tema inchisa devin aproape identice cu cerneala normala. */
  --onink: #e8f0f5;
  --onink-soft: #b9cad5;
  --onink-dim: #8ba0ac;
  --onink-line: #2b3b47;
  /* Suprafata inchisa ridicata PESTE pagina: balonul de ajutor si bannerul de
     cookie. Pe tema deschisa era chiar cerneala (#12303f); pe tema inchisa
     trebuie sa fie mai DESCHISA decat pagina, altfel nu se vede ca sta peste. */
  --ink-surface: #16242f;
  /* Al doilea accent: verdele. Nu inlocuieste cianul — merg impreuna, in
     degradeuri (butonul principal, inelul de incarcare) si ca semnal de
     „reusit". Scris o data, folosit peste tot. */
  --accent-2: #57e79b;
  --grad: linear-gradient(100deg, #0b98d3, #18b9dc 55%, #45d98d);
  --grad-hover: linear-gradient(100deg, #22bfe2, #51e49b);
}

* { box-sizing: border-box; }

/* ---------------------------------------------------------------------------
   FUNDALURILE (2026-08-21, imaginile alese de Xprime)
   `position: fixed` il scoate din flux, deci NU devine element de flex in
   `body` (care e flex-column) si nu impinge nimic. Sta la `z-index: -1`, adica
   sub tot continutul, dar peste culoarea de fundal a paginii.
   --------------------------------------------------------------------------- */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: url("/assets/img/bg-pages.jpg") center center / cover no-repeat;
  opacity: .5;
}
/* Imaginea e deschisa jos (podeaua) si acolo sta continutul: fara valul asta,
   textul de jos ar cadea peste partea cea mai luminoasa. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(180deg,
              rgba(10,13,17,.45) 0%, rgba(10,13,17,.72) 45%, rgba(10,13,17,.92) 100%);
}


html {
  font-size: 16px;
  /* Fundal explicit pe `html`: altfel fundalul lui `body` se propaga la panza
     paginii, iar straturile cu `z-index: -1` de mai jos pot ajunge SUB ea si
     sa nu se mai vada deloc. */
  background: var(--bg);
  /* Un rand care rezolva tot ce e desenat de browser, nu de noi: bifele,
     butoanele radio, barele de derulare, selectorul de data. Fara el raman
     albe pe fundal inchis si se vad ca niste petice. */
  color-scheme: dark;
  accent-color: var(--accent);
}

body {
  margin: 0;
  background: var(--bg);
  /* Fundalul propriu-zis vine din `body::before` (vezi mai jos), nu de aici:
     ca imagine de `background` pe `body` ar fi trebuit `fixed`, iar `fixed` pe
     telefon e cunoscut ca sacadeaza si, pe iOS, se intinde aiurea. */
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 400;
  line-height: 1.65;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* FULL-STRETCH 2026-07-30 (cerinta Xprime): toate paginile folosesc
   latimea intreaga a ecranului (cu margini), nu banda centrata de 1140px —
   altfel cele 12 coloane ale bazei de fisiere nu incap. */
.wrap { width: calc(100% - 3rem); margin-inline: auto; }

.mono { font-family: var(--sans); font-size: inherit; letter-spacing: normal; }

a { color: var(--accent-btn); text-underline-offset: 3px; }
a:hover { color: var(--accent-dark); }

h1, h2, h3 { font-weight: 600; line-height: 1.25; color: var(--ink); }
h1 { font-size: 2.3rem; margin: 0 0 1rem; font-weight: 700; }
h2 { font-size: 1.4rem; margin: 2rem 0 0.8rem; }
h3 { font-size: 1.05rem; }

/* ----------------------------------------------------------------- header */
.site-header { background: var(--panel); box-shadow: var(--shadow-soft); position: relative; z-index: 5; }
.header-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 4.2rem; }
.brand { font-weight: 700; font-size: 1.35rem; letter-spacing: 0.02em; text-decoration: none; color: var(--ink); }
.brand-dash { color: var(--accent); }
.admin-tag { font-size: 0.66rem; border: 1px solid var(--line); border-radius: 999px; padding: 0.15rem 0.55rem; margin-left: 0.5rem; color: var(--ink-soft); vertical-align: 0.35em; letter-spacing: 0.1em; }

.main-nav { display: flex; align-items: center; gap: 1.4rem; flex-wrap: wrap; }
.main-nav a { text-decoration: none; font-size: 0.9rem; font-weight: 500; color: var(--ink); }
.main-nav a:hover { color: var(--accent-btn); }
/* Pastila „Creeaza cont". Textul NU poate fi `--accent-ink` (aproape negru):
   fundalul e acum translucid pe fond inchis, deci ar fi invizibil — exact ce
   s-a intamplat in propunerea „terminal", unde iesea la 1,08:1.
   `.main-nav a` da si el o culoare, de-aia selectorul e mai specific aici in
   loc de `!important`. */
.main-nav a.nav-cta {
  background: rgba(87,231,155,0.10);
  border: 1px solid rgba(87,231,155,0.65);
  color: var(--accent-2);
  border-radius: 999px; padding: 0.5rem 1.3rem;
  font-size: 0.8rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;
  box-shadow: 0 0 22px rgba(87,231,155,0.12);
  transition: background 0.15s ease, color 0.15s ease;
}
.main-nav a.nav-cta:hover { background: rgba(87,231,155,0.18); color: var(--ink); }

.inline-form { display: inline; margin: 0; }
.link-button { background: none; border: none; padding: 0; font: inherit; font-size: 0.9rem; font-weight: 500; cursor: pointer; color: var(--ink); }
.link-button:hover { color: var(--accent-btn); }

/* language switcher */
.lang-switch { position: relative; }
.lang-switch summary { cursor: pointer; list-style: none; font-family: var(--mono); font-size: 0.8rem; border: 1px solid var(--line); border-radius: 999px; padding: 0.3rem 0.8rem; background: var(--bg); }
.lang-switch summary::-webkit-details-marker { display: none; }
.lang-switch ul { position: absolute; right: 0; top: calc(100% + 6px); background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-s); margin: 0; padding: 0.3rem 0; list-style: none; z-index: 10; min-width: 4.8rem; box-shadow: var(--shadow); }
.lang-switch li a { display: block; padding: 0.3rem 1rem; text-decoration: none; font-family: var(--mono); font-size: 0.8rem; color: var(--ink); }
.lang-switch li a.current { color: var(--accent-btn); font-weight: 600; }
.lang-switch li a:hover { background: var(--bg); }

/* ----------------------------------------------------------------- layout */
main.wrap { flex: 1; padding: 2rem 0 3.5rem; }

.site-footer { background: var(--panel); border-top: 1px solid var(--line); padding: 1.2rem 0; color: var(--ink-soft); font-size: 0.85rem; }

/* -------------------------------------------------------------- hero band
   Azure band with the concentric-circle motif from the brand imagery. */
.hero {
  position: relative; overflow: hidden;
  /* Banda paginilor interioare: acelasi fundal ca al sitului, cu un val
     albastru peste. Costa zero (poza e deja incarcata) si scoate banda din
     plat — inainte era un dreptunghi de degradeu si atat. */
  background:
    linear-gradient(120deg, rgba(14,59,82,.93), rgba(10,34,51,.96)),
    url("/assets/img/bg-pages.jpg") center center / cover no-repeat;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 3.2rem 3rem 3.4rem;
  margin: 0.6rem 0 2rem;
  color: var(--ink);
  box-shadow: var(--shadow);
}

/* --- banda paginii principale, cu fotografia masinii ---------------------
   Masina sta in dreapta imaginii, deci ancoram fundalul la dreapta si punem
   un val care se ingroasa spre stanga: textul isi are locul lui intunecat,
   masina ramane vizibila, si nu trebuie stinsa toata poza ca sa se citeasca.
   Inaltimea e ceruta explicit — altfel banda ar fi cat textul si din masina
   s-ar vedea doar o dunga. */
.hero-photo {
  background:
    linear-gradient(95deg, rgba(8,11,14,.97) 0%, rgba(8,11,14,.9) 26%,
                    rgba(8,11,14,.55) 52%, rgba(8,11,14,.12) 78%, rgba(8,11,14,.05) 100%),
    url("/assets/img/bg-home.jpg") right center / cover no-repeat;
  min-height: 26rem;
  display: flex; flex-direction: column; justify-content: center;
}
/* Cercurile decorative erau motivul vechiului fundal plat. Peste fotografie
   se bat cu masina, deci pe banda cu poza nu se deseneaza. */
.hero-photo::before, .hero-photo::after { display: none !important; }

@media (max-width: 760px) {
  /* Pe telefon masina ar cadea fix sub text. O coboram: textul sus, masina jos. */
  .hero-photo {
    min-height: 30rem;
    background:
      linear-gradient(180deg, rgba(8,11,14,.96) 0%, rgba(8,11,14,.88) 38%,
                      rgba(8,11,14,.3) 68%, rgba(8,11,14,.1) 100%),
      url("/assets/img/bg-home.jpg") 72% bottom / cover no-repeat;
    justify-content: flex-start;
  }
}
.hero::before, .hero::after {
  content: ""; position: absolute; border-radius: 50%; pointer-events: none;
  border: 2px solid rgba(255, 255, 255, 0.14);
  /* `z-index: 0` explicit. Textul are deja 1 (vezi `.hero > *`), deci ordinea era
     corecta si inainte — dar scrisa doar pe jumatate, iar jumatatea nescrisa e
     genul de lucru care se strica la urmatoarea atingere. */
  z-index: 0;
}
.hero::before { width: 420px; height: 420px; right: -90px; top: -140px; }
/* CERCUL PLIN se arata DOAR cand are loc (2026-08-21).
   Sta la 250px de marginea dreapta si are 190px — deci ocupa banda dintre 250 si
   440 de la dreapta. Textul e limitat la 620px de la stanga (`.hero > *`), asa ca
   pe o banda lata de peste ~1000px cele doua nu se ating. Sub atat, cercul cade
   fix peste randurile de text: e in spate, dar e si foarte deschis la culoare, iar
   scrisul alb peste el devine greu de citit — exact ce s-a raportat de pe telefon,
   si se vede la fel pe o fereastra ingusta de calculator.

   Deci nu il mutam si nu il micsoram: il ascundem cand n-are loc. Un desen
   decorativ care incurca cititul nu are ce cauta acolo, iar banda ramane
   frumoasa si fara el — arcul subtire din `::before` duce singur motivul. */
.hero::after { display: none; }
@media (min-width: 1000px) {
  .hero::after {
    display: block;
    width: 190px; height: 190px; right: 250px; top: 40px;
    /* Pe tema deschisa era un disc alb-albastrui. Pe fundal inchis, un disc
       plin devine o pata de lumina; motivul se pastreaza mai bine ca inel
       aprins — acelasi cerc, doar ca lumineaza in loc sa acopere. */
    border: none;
    background: radial-gradient(circle,
                rgba(34,184,240,.18) 0%, rgba(34,184,240,.05) 58%, transparent 70%);
    box-shadow: inset 0 0 0 2px rgba(34,184,240,.38), 0 0 40px rgba(34,184,240,.18);
  }
}
.hero > * { position: relative; z-index: 1; max-width: 620px; }
.hero h1 { color: var(--ink); font-size: clamp(2rem, 4.5vw, 3rem); }
.eyebrow { color: var(--accent); font-size: 0.78rem; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; margin-bottom: 0.7rem; }
.hero .lead, .lead { font-size: 1.05rem; margin-top: 0; }
.hero .lead { color: rgba(255, 255, 255, 0.92); }
.lead { color: var(--ink-soft); max-width: 44rem; }

.hero-compact { padding: 2.4rem 3rem 2.6rem; }
.hero-compact h1 { font-size: clamp(1.7rem, 3.5vw, 2.3rem); margin-bottom: 0.4rem; }
.hero-compact .lead { margin-bottom: 0; }

/* SE FACE LOC PENTRU CERC (2026-08-21). Cercul plin ocupa banda dintre 250 si 440
   de la marginea dreapta; rezervam 28rem de padding, deci textul se rupe INAINTE
   sa ajunga acolo. Fara asta, scrisul alb trecea peste un cerc foarte deschis la
   culoare si devenea greu de citit — raportat de Xprime, si la fel de vizibil pe
   o fereastra de calculator ingusta.

   Regula sta AICI, dupa `.hero-compact`, si nu langa `::after` unde ii era locul
   logic: `.hero-compact` seteaza `padding` prin PRESCURTARE, deci rescrie si
   `padding-right`. Pusa mai sus, era anulata tacut — prima incercare chiar asa a
   fost, si se vedea in captura de verificare.

   Nu strangem in schimb latimea textului: `.hero > *` are aceeasi specificitate
   ca `.lead` (care cere 44rem si e scris mai jos), deci ar fi insemnat inca o
   regula care sa bata inca o regula. Un padding nu se bate cu nimeni. */
@media (min-width: 1000px) {
  .hero, .hero-compact { padding-right: 28rem; }
}

.placeholder-panel { margin-top: 2rem; border: 1px dashed var(--line); border-radius: var(--radius); padding: 1.25rem 1.5rem; color: var(--ink-soft); background: var(--panel); }

/* ------------------------------------------------------------------ cards */
/* CARDUL: zona delimitata, nu panou umflat (ton B2B, 09.09.2026).
   Regula asta a stat o zi la COADA foisei, ca bloc de suprascriere. Era gresit
   si s-a vazut: `.card` si `.device-gate` au aceeasi specificitate (o clasa),
   deci cine e scris ultimul castiga — iar la coada era `.card`. Rezultatul:
   TOATE variantele de card si-au pierdut culoarea. Banda chihlimbar „dispozitiv
   neverificat" arata ca un card obisnuit, dungile de accent de pe `.ready-card`,
   `.manual-fallback` si `.msg-admin` disparusera (`border` e prescurtare, deci
   rescrie si `border-left`), la fel starile ok/rau ale dispozitivului si
   abonamentului. Nu se repara pe variante, una cate una: se repara punand baza
   INAINTEA lor, adica exact aici. */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.15rem 1.3rem;
  box-shadow: none;
}
.card > h2:first-child { margin-top: 0; }
.card.narrow { max-width: 470px; margin-inline: auto; }
.card.narrow-left { max-width: 470px; }
.card.center { text-align: center; }
.alt-action { text-align: center; font-size: 0.92rem; margin-top: 1.35rem; color: var(--ink-soft); }

/* ------------------------------------------------------------------ forms */
label { display: block; font-size: 0.85rem; font-weight: 600; margin: 1.1rem 0 0.35rem; }
label .hint { font-weight: 400; color: var(--ink-soft); }
.hint { color: var(--ink-soft); font-size: 0.9rem; }

input[type="text"], input[type="email"], input[type="password"], select, textarea {
  width: 100%; padding: 0.68rem 0.95rem;
  border: 1px solid var(--line); border-radius: var(--radius-s);
  background: var(--bg); color: var(--ink);
  font: inherit;
  transition: border-color 0.15s ease, background 0.15s ease;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent-btn); background: var(--panel); outline: none; }
button:focus-visible, summary:focus-visible, a:focus-visible { outline: 2px solid var(--accent-btn); outline-offset: 2px; }

/* BUTOANELE: conturate, fara degradeu, fara halou (ton B2B, 09.09.2026).
   Butonul principal se umple abia la hover (decizia lui Xprime).

   ACEEASI CUTIE PENTRU TOATE TREI. Butonul principal si cel secundar stau
   aproape mereu unul langa altul, si pana acum nu se aliniau: unul e `<button>`,
   celalalt `<a>`, cu umplutura verticala diferita (0.5 vs 0.48rem), rama
   diferita (1 vs 1.5px) si — cel mai vizibil — `margin-top: 1.2rem` ramas doar
   pe cel secundar, care il impingea cu 19px mai jos in orice rand de actiuni.
   Se vedea in banda de dispozitiv: „Manage devices" cobora sub „Verify this
   device". Deci: aceeasi umplutura, aceeasi rama, marginea de sus zero la toate
   (distantele le pune randul de actiuni, nu butonul), si `vertical-align` scris
   o data pentru cazurile in care randul nu e flex. */
.btn-primary, .btn-secondary, .btn-small {
  margin-top: 0; vertical-align: middle;
  border-style: solid; border-width: 1px;
  border-radius: var(--radius-s); box-shadow: none;
  font: inherit; font-weight: 600; letter-spacing: .04em; text-transform: none;
  cursor: pointer; text-decoration: none;
}
.btn-primary {
  display: inline-block;
  background: transparent; color: var(--accent-bright);
  border-color: var(--accent-btn);
  padding: 0.5rem 1.1rem; font-size: .82rem;
}
.btn-primary:hover, .btn-primary:focus-visible {
  background: var(--accent-btn); color: var(--accent-ink);
  border-color: var(--accent-btn); box-shadow: none;
}
/* Butonul stins trebuie sa arate stins, nu stricat. */
.btn-primary:disabled, .btn-primary[disabled] {
  filter: none; opacity: .45; background: transparent; color: var(--ink-soft);
  border-color: var(--line); box-shadow: none;
}

/* `.btn-small` ramane MIC: sta in randuri de tabel, cu zeci pe ecran. Din cutia
   comuna ia rama, raza si marginea zero — nu si inaltimea. Nu se aliniaza cu
   butonul principal fiindca nu sta niciodata langa el. */
/* AER INTRE ULTIMUL CAMP SI BUTON 2026-09-10 (raportat de Xprime pe /login).
   Butoanele aveau `margin-top: 1.4rem` implicit; cand am unificat cutia lor,
   marginea a plecat — corect pentru randurile de actiuni, care isi pun singure
   distantele, dar in formularele STIVUITE (logare, inregistrare, parola uitata)
   butonul venea imediat dupa `<input>`, iar inputul n-are margine de jos. S-a
   lipit de campul parolei.
   Distanta o pune ADIACENTA, nu butonul: „camp urmat direct de buton". In
   randurile de actiuni butonul nu urmeaza niciodata un camp, deci regula nu-i
   atinge; acolo unde chiar urmeaza (cautari, filtre — randuri flex), o anulam
   pe linia de dedesubt, fiindca acolo distanta e pe orizontala. */
/* `input:not([type="hidden"])` — nu orice `<input>`. Jetonul CSRF e tot un
   input, iar un formular scris `<form>{jeton}<button>` primea 17,6px de aer
   deasupra butonului fara ca nimic vizibil sa fie deasupra lui. Se vedea in
   randurile de actiuni: butonul dintr-un formular statea cu noua pixeli mai jos
   decat linkul de langa el. Un camp invizibil nu poate cere distanta fata de
   ceva. */
:is(input:not([type="hidden"]), select, textarea) + :is(button, .btn-primary, .btn-secondary, .btn-small) {
  margin-top: 1.1rem;
}
:is(.filter-row, .filter-bar, .bulk-bar, .device-add, .rechain-form, .coin-package,
    .catalog-search-row, .device-reset-short, .diag-buttons, .manual-entry, .options-short)
  :is(input, select, textarea) + :is(button, .btn-primary, .btn-secondary, .btn-small) {
  margin-top: 0;
}

.btn-small { font-size: 0.8rem; font-weight: 500; padding: 0.3rem 0.7rem; border-color: var(--line); background: var(--panel); color: var(--ink); transition: border-color 0.15s ease, color 0.15s ease; }
.btn-small:hover { border-color: var(--accent-btn); color: var(--accent-btn); }
.btn-danger { border-color: var(--error); color: var(--error); }
.btn-danger:hover { border-color: var(--error); color: var(--accent-ink); background: var(--error); }

.field-error { color: var(--error); font-size: 0.85rem; margin: 0.3rem 0 0; }

/* ------------------------------------------------------------------ flash */
.flash { padding: 0.8rem 1.1rem; border-radius: var(--radius-s); margin-bottom: 1.25rem; font-size: 0.93rem; }
.flash-success { color: var(--ok); background: var(--ok-bg); }
.flash-error { color: var(--error); background: var(--error-bg); }
/* `ok` si `info` erau folosite in cod (unsprezece locuri, respectiv trei) fara sa
   aiba vreo regula aici — deci se afisau ca o caseta incolora, fara nici macar
   fundal. Le imbracam: `ok` inseamna acelasi lucru cu `success`, `info` e o
   constatare neutra ("nu s-a schimbat nimic"), nu o reusita. */
.flash-ok { color: var(--ok); background: var(--ok-bg); }
.flash-info { color: var(--ink-soft); background: var(--neutral-bg); }

.status-ok { color: var(--ok); }
.status-error { color: var(--error); }

.banner-offline {
  background: var(--error-bg); color: var(--error); border-radius: var(--radius-s);
  padding: 0.8rem 1.1rem; margin: 0 0 1.2rem; font-weight: 500;
}


/* ── MENTENANTA 2026-09-21 ────────────────────────────────────────────────
   Banda de sus, pe toate paginile cat timp modul e pornit. Aceleasi culori ca
   avertismentele existente — nu inventam o a doua limba vizuala pentru o stare
   temporara. Titlul si textul stau pe acelasi rand cat incap, si se aseaza unul
   sub altul pe telefon. */
.maint-banner {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem .6rem;
  margin: 0 0 1rem; padding: .7rem .9rem;
  border: 1px solid var(--warn-ink); border-left-width: 3px; border-radius: 10px;
  background: var(--warn-bg); color: var(--warn-ink);
  font-size: .93rem; line-height: 1.5;
}
.maint-banner-title { font-weight: 700; }
.maint-banner-note { flex: 1 1 100%; opacity: .9; }

/* Poarta de pe formularul de incarcare: nota operatorului, sub textul standard,
   despartita de el printr-o linie subtire — altfel cele doua paragrafe curg
   unul in altul si nu se mai vede care e textul nostru si care e al tau. */
.maint-note {
  margin: .9rem auto 0; padding-top: .8rem; max-width: 34rem;
  border-top: 1px solid var(--line); opacity: .92;
}

/* Ecranul de admin. Cardul isi schimba marginea cand modul e pornit — starea se
   vede din usa, nu se deduce dintr-o bifa. */
.maint-admin.is-on { border-color: var(--warn-ink); border-left: 3px solid var(--warn-ink); }
.maint-admin h2 { display: flex; align-items: center; gap: .5rem; }
.maint-note-input { width: 100%; box-sizing: border-box; resize: vertical; }


/* ── TARA OBLIGATORIE 2026-09-22 ──────────────────────────────────────────
   Selectorul, cardul cu numaratoarea si poarta de pe formularul de incarcare.
   Nimic nou ca limbaj vizual: casuta de filtrare imprumuta forma campurilor
   existente, iar cardul imprumuta cele doua culori de avertizare pe care
   portalul le are deja (chihlimbar pentru „mai ai timp", rosu pentru „s-a
   oprit"). O a treia culoare ar fi insemnat ca omul trebuie sa invete ceva. */
/* `min-width: 0` PE TOATE TREI. Un `<select>` isi cere, dupa continut, latimea
   celei mai lungi optiuni din el — aici „South Georgia & South Sandwich
   Islands" — iar ca element de grila minimul lui implicit e chiar aceea, deci
   `width: 100%` singur nu-l poate stramta. In portal nu se vede, fiindca
   `.admin-main > *` are deja `min-width: 0`; randurile astea sunt ca selectorul
   sa se poarte la fel si in afara invelisului de panou (ecranul de incarcare
   public, si orice pagina viitoare care nu e in `.admin-main`). Masurat la 390px
   in ro/de/ja: fara ele, un card scos din panou iese din ecran cu ~95px. */
.country-picker { display: grid; gap: .4rem; min-width: 0; }
.country-picker select { width: 100%; min-width: 0; max-width: 100%; }
/* Casuta de filtrare e mai mica decat selectul de sub ea: e un ajutor, nu
   campul principal. Fara asta, doua casute de aceeasi marime una peste alta
   intreaba omul care dintre ele conteaza. */
.country-filter {
  width: 100%; min-width: 0; box-sizing: border-box;
  font-size: .88rem; padding: .45rem .6rem;
}

/* Cardul cu numaratoarea. Trei trepte, aceeasi forma:
   is-calm   — inceputul ferestrei, ton neutru;
   is-soon   — sub trei zile, chihlimbar;
   is-blocked— dupa termen, rosu. */
/* SCRISE CU TOATE CELE TREI CLASE, si asta NU e din zel. Portalul are, mai
   jos in foaie, `body:not(.admin) .card, body.panel .card { border: 1px solid
   var(--line); background: … }` — o regula de 0-2-1 care reface chenarul si
   fondul oricarui card. Un `.country-notice.is-soon` (0-2-0) pierde in fata ei
   oriunde l-am pune, si cele trei trepte ar fi aratat identic: culoarea se
   vedea doar pe randul cu termenul, iar cardul ramanea la fel in ziua 1 si in
   ziua 14. Cu `.card.country-notice.is-soon` (0-3-0) treptele se vad.
   Masurat in browser: fara asta, `borderLeftColor` iesea rgba(159,190,207,.16)
   la toate trei. Fiecare treapta isi scrie chenarul intreg — nu exista card
   fara treapta, deci n-are cine sa cada pe un implicit. */
.card.country-notice h2 { margin-top: 0; font-size: 1.05rem; }
.country-notice-text { color: var(--ink-soft); }
.country-notice-deadline { font-weight: 600; margin: .6rem 0 .9rem; }
.card.country-notice.is-calm { border-left: 3px solid var(--accent); }
.card.country-notice.is-soon {
  border-left: 3px solid var(--warn-ink); background: var(--warn-bg);
}
.card.country-notice.is-soon .country-notice-deadline { color: var(--warn-ink); }
.card.country-notice.is-blocked {
  border-left: 3px solid var(--error); background: var(--error-bg);
}
.card.country-notice.is-blocked .country-notice-deadline { color: var(--error-ink); }

/* Formularul din card: selectorul si butonul pe acelasi rand cat incap, unul
   sub altul pe telefon — butonul NU se ingusteaza sub degetul nimanui. */
.country-notice-form {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: .6rem;
  margin: .2rem 0 .6rem;
}
.country-notice-form .country-picker { flex: 1 1 16rem; min-width: 0; }
.country-notice-form .btn-primary { flex: 0 0 auto; }

/* Poarta de pe formularul de incarcare. Selectorul sta centrat sub text, cu
   aceeasi latime ca explicatia celorlalte porti, ca sa nu para alt ecran. */
.country-gate-form {
  display: grid; gap: .6rem; justify-items: center;
  width: 100%; max-width: 24rem; margin: 1rem auto 0;
}
.country-gate-form .country-picker { width: 100%; }

/* In profil: randul tarii, cand chiar lipseste. Doar marginea se schimba —
   un camp obligatoriu intre alte zece trebuie sa se vada, nu sa tipe. */
.field-country .country-hint { color: var(--warn-ink); }
.field-country.is-required select { border-color: var(--warn-ink); }

@media (max-width: 560px) {
  .country-notice-form { display: grid; }
  .country-notice-form .btn-primary { width: 100%; }
}

/* ── FEREASTRA DE TARA, PESTE PAGINA 2026-09-22 ───────────────────────────
   Se vede IMPLICIT, fara niciun script: bifa ascunsa de deasupra ei o inchide,
   si aia e toata mecanica. Un `<dialog>` ar fi fost mai scurt de scris, dar
   fara JavaScript ramane invizibil — exact in cazul in care ai vrea cel mai
   mult sa se vada.
   `position: fixed` + `inset: 0`, deci sta peste orice, oricat ar fi derulat
   omul. `overflow: auto` pe fundal si `margin: auto` pe cutie: pe un telefon
   mic in germana continutul e mai inalt decat ecranul, si atunci fereastra se
   deruleaza in loc sa-si taie butonul de jos. */
.country-modal-off { display: none; }
.country-modal-off:checked ~ .country-modal { display: none; }

.country-modal {
  position: fixed; inset: 0; z-index: 60;
  display: flex; overflow: auto;
  padding: 1.2rem; box-sizing: border-box;
  background: rgba(3, 10, 16, .72);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.country-modal-box {
  position: relative; margin: auto;
  width: 100%; max-width: 30rem; min-width: 0;
  padding: 1.5rem 1.6rem 1.3rem; box-sizing: border-box;
  background: var(--panel-2); border: 1px solid var(--line-strong);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
/* Aceleasi trei trepte ca pe card, ca sa fie evident ca e acelasi lucru. */
.country-modal.is-soon    .country-modal-box { border-top-color: var(--warn-ink); }
.country-modal.is-blocked .country-modal-box { border-top-color: var(--error); }

.country-modal-box h2 { margin: 0 2rem .6rem 0; font-size: 1.15rem; }
.country-modal-why { color: var(--ink-soft); margin: 0 0 .7rem; }
.country-modal-deadline { font-weight: 600; margin: 0 0 1rem; }
.country-modal.is-soon    .country-modal-deadline { color: var(--warn-ink); }
.country-modal.is-blocked .country-modal-deadline { color: var(--error-ink); }

.country-modal-form { display: grid; gap: .7rem; min-width: 0; }
.country-modal-form .btn-primary { width: 100%; }

/* X-ul din colt: zona de atins cat degetul (44px), dar discret la privit. */
/* `font-weight` si `margin` scrise explicit: regula generala `label { display:
   block; font-weight: 600; margin: 1.1rem 0 .35rem }` prinde si eticheta asta,
   fiindca inchiderea E o eticheta (bifa ascunsa = zero JavaScript). Fara ele,
   iesirea secundara arata la fel de apasat ca butonul adevarat. */
.country-modal-x {
  position: absolute; top: .35rem; right: .45rem;
  display: flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; margin: 0;
  font-size: 1.5rem; font-weight: 400; line-height: 1; color: var(--muted);
  cursor: pointer; user-select: none; border-radius: var(--radius-s);
}
.country-modal-x:hover { color: var(--ink); background: var(--neutral-bg); }

/* „Mai tarziu" e o iesire, nu o actiune: text, nu buton, si sub cel adevarat. */
.country-modal-later {
  display: block; margin: .8rem auto 0; width: fit-content;
  padding: .35rem .6rem; font-size: .88rem; font-weight: 400; color: var(--muted);
  cursor: pointer; border-radius: var(--radius-s);
}
.country-modal-later:hover { color: var(--ink); text-decoration: underline; }
.country-modal-safe { margin: .9rem 0 0; text-align: center; }

/* Pagina de dedesubt nu se mai plimba sub deget cat timp fereastra e deschisa.
   Pusa de script; fara script nu exista, si atunci doar se deruleaza fundalul —
   suparator, nu stricat. */
.has-country-modal, .has-country-modal body { overflow: hidden; }

/* ── ANUNTUL DE LA AUTENTIFICARE 2026-09-28 ──────────────────────────────
   Aceeasi fereastra ca cea de tara (aceleasi clase de baza: fundal, cutie,
   X, „inchide"), plus ce are in plus un anunt: o imagine care umple latimea
   cutiei si un buton de legatura. Cutia e putin mai lata cand e doar o
   imagine — o poza de promotie merita spatiul. */
.login-notice-box { max-width: 34rem; }
.login-notice-box.is-image-only { max-width: 40rem; padding-top: 2.4rem; }
.login-notice-box h2 { margin-right: 2.4rem; }
.login-notice-image { margin: .2rem 0 .9rem; }
.login-notice-image img {
  display: block; width: 100%; height: auto; max-height: 70vh; object-fit: contain;
  border-radius: var(--radius-s); background: var(--neutral-bg);
}
.login-notice-text { color: var(--ink); line-height: 1.55; overflow-wrap: anywhere; margin: 0 0 .4rem; }
.login-notice-cta { display: block; width: 100%; box-sizing: border-box; text-align: center; margin-top: .9rem; }
.login-notice-ok { margin-top: .6rem; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Panoul de admin: previzualizarea si miniatura din lista. */
.notice-preview img { display: block; max-width: 20rem; max-height: 12rem; border-radius: var(--radius-s); border: 1px solid var(--line); margin: .3rem 0 .2rem; }
.notice-thumb { display: block; max-width: 9rem; max-height: 5rem; border-radius: var(--radius-s); border: 1px solid var(--line); margin: .3rem 0; }
.notice-cell { max-width: 28rem; }
.notice-text { display: block; white-space: normal; }
.notice-image-delete { margin-top: .6rem; }
#nt-group { margin-top: .4rem; }

@media (max-width: 420px) {
  .country-modal { padding: 0; }
  .country-modal-box {
    min-height: 100%; max-width: none; border-radius: 0; border-left: 0;
    border-right: 0; border-bottom: 0; padding: 1.3rem 1.1rem 1.6rem;
  }
}

/* Tara lipsa, in panoul de admin: in lista si pe fisa contului. Chihlimbar,
   nu rosu — e o casuta necompletata, nu o defectiune. */
.country-missing { color: var(--warn-ink); }
/* Acelasi motiv ca la card: cu toate clasele, ca sa nu piarda in fata regulii
   generale de card. */
.card.user-country-fix { border-left: 3px solid var(--warn-ink); }
.card.user-country-fix.is-blocked { border-left: 3px solid var(--error); }
.card.user-country-fix h2 { margin-top: 0; font-size: 1rem; }
.user-country-form { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.user-country-form select { width: auto; min-width: 14rem; }

/* Randul „pe ce merge" de sub butonul de inregistrare a dispozitivului. */
.device-reqs { margin-top: .35rem; }
/* ----------------------------------------------------------------- tables */
.data-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.data-table th {
  text-align: left; font-size: 0.72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--ink-soft); background: var(--neutral-bg);
  padding: 0.65rem 0.9rem; white-space: nowrap;
}
.data-table th:first-child { border-radius: var(--radius-s) 0 0 var(--radius-s); }
.data-table th:last-child { border-radius: 0 var(--radius-s) var(--radius-s) 0; }
.data-table td { padding: 0.7rem 0.9rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.data-table tr:last-child td { border-bottom: none; }
.data-table .actions { white-space: nowrap; }
.data-table .actions form + form { margin-left: 0.4rem; }

/* Auto table layout sizes columns to content. The only column that can grow
   unbounded is the file name (long single tokens), so cap it and let it wrap.
   Everything else keeps its natural width — no column gets squeezed. */
.data-table .col-file { max-width: 30rem; overflow-wrap: anywhere; word-break: break-word; }
.data-table td.num, .data-table th.num { text-align: right; white-space: nowrap; }

/* OVERFLOW 2026-07-28 (cerinta Xprime): valorile lungi dintr-un singur token
   (nume de fisiere, hash-uri, software ECU, JSON de meta) rupeau layout-ul —
   celulele si perechile dt/dd impingeau cardul in afara paginii. Orice
   continut de date poate acum sa se franga oriunde e nevoie. */
.data-table td { overflow-wrap: anywhere; }
.vehicle-data div { flex-wrap: wrap; min-width: 0; }
.vehicle-data dd { overflow-wrap: anywhere; min-width: 0; text-align: right; }
.msg p, .card p { overflow-wrap: break-word; }
/* zebra + hover: tabelele lungi devin scanabile */
.data-table tbody tr:nth-child(even) td { background: var(--panel-2); }
.data-table tbody tr:hover td { background: var(--neutral-bg); }

/* ---- Group membership pills / chips (Groups + Users pages) ---------------- */
.mem-pill {
  display: inline-block; padding: 0.12rem 0.5rem; border-radius: 999px;
  font-size: 0.78rem; font-weight: 600; white-space: nowrap; line-height: 1.5;
}
.mem-pill-sm { padding: 0.02rem 0.4rem; font-size: 0.72rem; margin-left: 0.25rem; }
.mem-ok        { background: var(--ok-bg); color: var(--ok); }
.mem-soon      { background: var(--warn-bg); color: var(--warn-ink); }
.mem-expired   { background: var(--error-bg); color: var(--error); }
.mem-unlimited { background: var(--accent-soft); color: var(--accent-dark); }

/* Users page: groups column */
.data-table .user-groups { min-width: 12rem; }
/* Keep member action controls on one line so Remove never spills out. */
.member-actions { white-space: nowrap; }
.member-actions .inline-form { display: inline-flex; align-items: center; gap: 0.25rem; margin-right: 0.4rem; vertical-align: middle; }
.group-chip {
  display: inline-flex; align-items: center; gap: 0.2rem;
  padding: 0.14rem 0.5rem; margin: 0 0.3rem 0.3rem 0;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px;
  font-size: 0.82rem; text-decoration: none; color: var(--ink);
  white-space: nowrap; max-width: 100%;
}
.group-chip > :first-child { overflow: hidden; text-overflow: ellipsis; }
.group-chip:hover { border-color: var(--accent-btn); color: var(--accent-btn); }
/* Zilele ramase, lipite de numele grupului (2026-08-21). Culoarea spune
   starea dintr-o privire: verde = fara expirare, chihlimbar = se apropie,
   rosu = a trecut. Pastila ramane citibila si fara culoare — scrie si in text. */
.group-chip-days { color: var(--muted); font-variant-numeric: tabular-nums; }
.group-chip-days::before { content: "· "; }
.group-chip--forever { border-color: var(--ok-line); }
.group-chip--forever .group-chip-days { color: var(--ok); }
.group-chip--soon { border-color: var(--warn-line); }
.group-chip--soon .group-chip-days { color: var(--warn); }
.group-chip--over { border-color: var(--error-line); }
.group-chip--over .group-chip-days { color: var(--error); }

/* Formularul de acordare manuala: campurile pe un rand, nota ia restul latimii
   ca sa nu ramana o casuta de doua degete pentru un text de 200 de caractere. */
.grant-sub-form { align-items: flex-end; gap: .6rem .8rem; }
.grant-sub-form .filter-field { min-width: 8rem; }
.grant-sub-form .grant-sub-note { flex: 1 1 18rem; }
.grant-sub-form .btn-primary { margin-top: 0; }

.add-group-details { display: inline-block; margin-top: 0.2rem; }
.add-group-summary { cursor: pointer; list-style: none; display: inline-block; }
.add-group-details[open] .add-group-summary { margin-bottom: 0.4rem; }
.add-group-form { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; }
.add-group-form select { max-width: 12rem; }

/* running total above the process button (options wizard) */
.opt-price { margin-left: auto; font-weight: 600; font-size: 0.9rem; color: var(--accent-btn); white-space: nowrap; }
.options-total {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  margin: 0.4rem 0 1rem; padding: 0.7rem 0.9rem;
  background: var(--accent-soft); border-radius: var(--radius-s);
}
.options-total-label { font-weight: 600; color: var(--ink); }
.options-total-value { font-weight: 600; color: var(--accent-btn); }
.options-total-value .hint { font-weight: 400; margin-left: 0.35rem; }

.status-badge { font-family: var(--mono); font-size: 0.74rem; padding: 0.2rem 0.65rem; border-radius: 999px; background: var(--neutral-bg); color: var(--ink-soft); }
.status-active { color: var(--ok); background: var(--ok-bg); }
.status-pending_approval { color: var(--accent-btn); background: var(--accent-soft); }
.status-disabled { color: var(--error); background: var(--error-bg); }
.status-unverified { color: var(--ink-soft); }

/* ------------------------------------------------------------------ admin */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1.1rem; margin-bottom: 1.6rem; }
.stat { background: var(--panel); border-radius: var(--radius); padding: 1.2rem 1.4rem; box-shadow: var(--shadow-soft); }
.stat-value { display: block; font-size: 1.9rem; font-weight: 700; line-height: 1.15; color: var(--accent-btn); }
.stat-label { color: var(--ink-soft); font-size: 0.8rem; font-weight: 500; }

.filter-row, .filter-bar { display: flex; gap: 0.6rem; margin: 0 0 1.25rem; flex-wrap: wrap; }
.filter-row input[type="text"], .filter-bar input[type="text"] { max-width: 320px; }
.filter-row select, .filter-bar select { width: auto; }
.filter-row button, .filter-bar button { font: inherit; font-size: 0.85rem; font-weight: 500; padding: 0.55rem 1.2rem; border: 1px solid var(--line); background: var(--panel); border-radius: 999px; cursor: pointer; }
.filter-row button:hover, .filter-bar button:hover { border-color: var(--accent-btn); color: var(--accent-btn); }

/* ------------------------------------------------- home: two entry paths */
.entry-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; margin-bottom: 2.2rem; align-items: stretch; }
.entry-grid-even { grid-template-columns: 1fr 1fr; }
/* un singur punct de intrare: cardul se extinde pe toata latimea */
.entry-grid-single { grid-template-columns: 1fr; }
@media (max-width: 820px) { .entry-grid, .entry-grid-even { grid-template-columns: 1fr; } }

.entry-card { display: flex; flex-direction: column; align-items: flex-start; padding: 2rem 2.1rem 2.2rem; position: relative; overflow: hidden; transition: box-shadow 0.2s ease, transform 0.2s ease; }
.entry-card:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
/* concentric "dial" rings — motif from the brand imagery.

   DESENUL STA IN SPATE 2026-08-21 (raportat de Xprime, cu captura de pe telefon).
   Un `::after` se picteaza DUPA continutul elementului, deci implicit peste el. Pe
   ecran lat inelele cadeau intr-un colt gol si nu se vedea nimic; pe telefon,
   titlul se rupe pe doua randuri, intra sub inele si cuvantul din dreapta era
   acoperit — „Automatic file de███tion".

   Se rezolva dintr-o singura data, pentru ORICE latime, nu cu inca o exceptie in
   `@media`: inelele primesc `z-index: 0`, iar continutul cardului `z-index: 1`.
   `position: relative` pe copii e obligatoriu — fara el, `z-index` nu are ce sa
   aseze. */
.entry-card::after {
  content: ""; position: absolute; right: -40px; top: -40px; z-index: 0;
  width: 150px; height: 150px; border-radius: 50%;
  border: 13px solid var(--accent-soft);
  box-shadow: inset 0 0 0 12px var(--panel), inset 0 0 0 19px var(--accent-soft);
  pointer-events: none;
}
.entry-card > * { position: relative; z-index: 1; }
.entry-card h2 { margin: 0.6rem 0 0.5rem; font-size: 1.35rem; }
.entry-card p { margin: 0 0 1.3rem; color: var(--ink-soft); flex: 1; font-size: 0.95rem; }
.entry-card .btn-primary { margin-top: 0; }
.entry-no {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.6rem; height: 2.6rem; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-btn);
  font-weight: 600; font-size: 0.95rem;
}
.entry-card-soon h2, .entry-card-soon p { opacity: 0.75; }
.soon-badge { display: inline-block; border-radius: 999px; background: var(--neutral-bg); color: var(--ink-soft); padding: 0.4rem 1rem; font-size: 0.76rem; letter-spacing: 0.12em; }

/* ------------------------------------------------------------------ steps */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem; margin: 0 0 2.2rem; }
.step { background: var(--panel); border-radius: var(--radius); padding: 1.6rem 1.7rem; box-shadow: var(--shadow-soft); }
.step-no {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.6rem; height: 2.6rem; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-btn);
  font-weight: 700; font-size: 1.05rem;
}
.step h3 { margin: 0.8rem 0 0.4rem; font-weight: 600; }
.step p { margin: 0; color: var(--ink-soft); font-size: 0.92rem; }
@media (max-width: 720px) { .steps { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------- cifrele (2026-08-21)
   Trei chenare sub pasi: cat dureaza, cate s-au facut, ca merge non-stop.

   Sunt mai MICI si mai tacute decat cardurile de deasupra, dinadins: pasii spun
   cum functioneaza serviciul si trebuie cititi; astea sunt un argument aruncat cu
   coada ochiului. Daca ar avea aceeasi greutate, ar concura cu pasii si ar
   incetini exact drumul pe care il sustin.

   `auto-fit` cu minim de 12rem: trei pe rand pe ecran lat, doua pe tableta, unul
   pe telefon — fara nicio regula scrisa pentru fiecare caz. */
.stat-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
              gap: 1rem; margin: 0 0 2.4rem; }
.stat-tile { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
             padding: 1.1rem 1.2rem 1.15rem; display: grid; gap: .1rem; justify-items: start; }
.stat-tile-icon { color: var(--accent); margin-bottom: .35rem; }
/* `tabular-nums` ca "24/7" si "< 1 min" sa nu danseze pe verticala intre chenare. */
.stat-tile-value { font-size: 1.6rem; font-weight: 700; line-height: 1.15;
                   font-variant-numeric: tabular-nums; }
.stat-tile-label { font-size: .85rem; color: var(--ink-soft); line-height: 1.35; }

/* ----------------------------------------------------------------- upload */
.upload-panel { margin-bottom: 0; }
.upload-form { display: flex; gap: 0.9rem; flex-wrap: wrap; align-items: center; margin-top: 0.9rem; }
.upload-form input[type=file] {
  flex: 1 1 18rem; padding: 0.8rem; border: 2px dashed var(--accent-soft); border-radius: var(--radius-s);
  background: var(--bg); font-family: var(--mono); font-size: 0.85rem;
}
.upload-form input[type=file]:disabled, .upload-form button:disabled { opacity: 0.45; cursor: not-allowed; }
.upload-form .btn-primary { margin-top: 0; }

.catalog-teaser h2 { margin-top: 0; }

/* ------------------------------------------------------------- job wizard */
.job-head { margin-bottom: 1rem; }
.wait-card { text-align: center; padding: 2.4rem 1.4rem; }
.spinner {
  width: 38px; height: 38px; margin: 0 auto 1rem;
  border: 3px solid var(--accent-soft); border-top-color: var(--accent-btn);
  border-radius: 50%; animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.vehicle-card { margin-bottom: 1.3rem; }
.vehicle-data { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 0.5rem 1.5rem; margin: 0.6rem 0 0; }
.vehicle-data div { display: flex; justify-content: space-between; gap: 1rem; border-bottom: 1px solid var(--line); padding: 0.4rem 0; }
.vehicle-data dt { color: var(--ink-soft); font-size: 0.88rem; }
.vehicle-data dd { margin: 0; font-family: var(--mono); font-size: 0.88rem; }

.options-form fieldset { border: 1px solid var(--line); border-radius: var(--radius-s); margin: 0 0 1.1rem; padding: 0.8rem 1rem 0.95rem; }
.options-form legend { padding: 0 0.5rem; font-weight: 600; font-size: 0.95rem; }
.opt { display: flex; align-items: center; gap: 0.6rem; padding: 0.34rem 0; cursor: pointer; border-radius: var(--radius-s); }
.opt input { accent-color: var(--accent-btn); }
/* MUTEX: option locked out because a current selection already covers one of
   its components (e.g. STAGE1+ADBLUE selected -> ADBLUE combos lock). */
.opt--locked { opacity: 0.42; cursor: not-allowed; }
.opt--locked input { pointer-events: none; }

/* NOTES: fitting instructions carried by each modification's source file
   ("disconnect AdBlue module", "remove sensor"...) — shown on ready/paid. */
.summary-notes { margin-top: 0.9rem; padding: 0.75rem 0.9rem; border: 1px solid var(--line); border-left: 4px solid var(--accent-btn); border-radius: var(--radius-s); }
.summary-notes .summary-label { display: block; font-weight: 600; margin-bottom: 0.4rem; }
.mod-notes { margin: 0; padding: 0; list-style: none; }
.mod-notes li { padding: 0.22rem 0; font-size: 0.92rem; }
.mod-notes-code { display: inline-block; min-width: 4.5rem; margin-right: 0.5rem; font-weight: 600; }

.ready-card { border-left: 5px solid var(--accent-btn); }

/* job state badges */
.status-ready, .status-identified, .status-paid, .status-downloaded { background: var(--ok-bg); color: var(--ok); }
.status-not_supported, .status-process_failed, .status-fetch_failed, .status-expired, .status-purged { background: var(--error-bg); color: var(--error); }
.status-queued_identify, .status-identifying, .status-queued_process, .status-processing, .status-queued_fetch, .status-fetching, .status-uploaded { background: var(--neutral-bg); color: var(--ink-soft); }

/* --------------------------------------------------- catalog (DB search) */
.catalog-search { display: flex; gap: 0.9rem; flex-wrap: wrap; align-items: center; margin: 0.2rem 0 1.1rem; }
.catalog-search input[type="text"] { flex: 1 1 22rem; max-width: 36rem; background: var(--panel); box-shadow: var(--shadow-soft); border-color: transparent; }
.catalog-search input[type="text"]:focus { border-color: var(--accent-btn); }
.catalog-search .btn-primary { margin-top: 0; }

.catalog-count { margin: 0 0 0.9rem; }
.catalog-card { padding: 1rem 1.2rem 1.1rem; }
.catalog-card > .hint { padding: 1rem 0.6rem; }
.catalog-table td { font-size: 0.89rem; }

.pagination { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; margin: 1.5rem 0 0; }

.credit-adjust { display: inline-flex; gap: 0.3rem; margin-left: 0.4rem; }
.credit-adjust input[type=text] { width: 5.5rem; padding: 0.28rem 0.5rem; }
.credit-adjust input[name=reason] { width: 9rem; }

.legal h2 { font-size: 1.15rem; margin-top: 1.6rem; }
.legal p { color: var(--ink); font-size: 0.95rem; }
.legal { max-width: 820px; }

/* Perechea PayPal e brand strain: galbenul si bleumarinul merg impreuna si NU
   urmeaza tema. Cu `var(--ink)` textul devenea deschis pe galben (1.38:1). */
.btn-paypal { background: #ffc439; color: #12303f; box-shadow: 0 8px 20px rgba(255, 196, 57, 0.35); }
.btn-paypal:hover { background: #f0b429; color: #12303f; }

/* tickets */
.msg { margin-bottom: 0.9rem; }
.msg-admin { border-left: 5px solid var(--accent-btn); }

/* payment UI */
.price-line { font-size: 1.05rem; margin: 0.8rem 0; }
.price-value { font-size: 1.9rem; font-weight: 700; color: var(--accent-btn); }
.pay-actions { display: flex; gap: 0.9rem; flex-wrap: wrap; align-items: center; margin: 0.4rem 0 0.8rem; }
.pay-actions .btn-primary { margin-top: 0; }
.package-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.55rem 0; border-bottom: 1px solid var(--line); }
.package-row:last-of-type { border-bottom: none; }
.package-name { font-weight: 500; }

/* breadcrumb back-link, honeypot, catalog file links */
.crumbs { margin: 0.2rem 0 0.9rem; font-size: 0.9rem; }
.crumbs a { text-decoration: none; font-weight: 500; }
.hp-field { position: absolute; left: -9999px; top: -9999px; height: 1px; overflow: hidden; }
.file-link { color: var(--ink); font-weight: 500; text-decoration: none; }
.file-link:hover { color: var(--accent-btn); text-decoration: underline; }
.page-link { display: inline-block; min-width: 2.3rem; text-align: center; padding: 0.42rem 0.6rem; border-radius: 999px; background: var(--panel); box-shadow: var(--shadow-soft); text-decoration: none; font-size: 0.87rem; color: var(--ink); }
a.page-link:hover { color: var(--accent-btn); }
.page-current { background: var(--accent-btn); color: var(--accent-ink); font-weight: 600; }
.page-prev, .page-next { font-weight: 500; padding-inline: 1rem; }
.page-gap { color: var(--ink-soft); padding: 0 0.15rem; }

/* ------------------------------------------------------------- responsive */
@media (max-width: 640px) {
  .header-row { flex-wrap: wrap; padding: 0.6rem 0; }
  .hero { padding: 2.2rem 1.5rem 2.4rem; }
  /* `.hero::after` e deja ascuns implicit (vezi mai sus); nu se mai repeta aici. */
  /* Arcul mare ramane, dar mult mai discret: pe latimea unui telefon trece fix
     peste randurile de text, iar doua alburi apropiate — linia si scrisul — se
     citesc ca o zgarietura pe ecran, nu ca un desen. */
  .hero::before { opacity: .35; right: -160px; top: -180px; }
  .card { padding: 1.3rem 1.3rem; }
  .data-table { display: block; overflow-x: auto; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  .spinner { animation: none; }
  .entry-card:hover { transform: none; }
}

/* ---- File status banner (original / modified) + secondary button ---------- */
.file-status {
  margin: 0.2rem 0 1.1rem;
  padding: 0.7rem 1rem;
  border-radius: 12px;
  font-size: 0.9rem;
  font-weight: 600;
}
.file-status--ok {
  background: var(--ok-bg);
  color: var(--ok);
  border: 1px solid var(--ok-line);
}
.file-status--warn {
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid var(--warn-line);
}
/* NEDETERMINAT: engine-ul nu a putut stabili originalitatea (is_modified=null).
   Neutru intentionat -- NU verde: nu confirmam "original" cand nu stim. */
.file-status--unknown {
  background: var(--neutral-bg);
  color: var(--ink-soft);
  border: 1px solid var(--line-strong);
}
.btn-secondary {
  display: inline-block;
  background: var(--panel); color: var(--accent-btn);
  border-color: var(--line);
  padding: 0.5rem 1.1rem; font-size: 0.82rem;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.btn-secondary:hover { background: var(--accent-btn); color: var(--accent-ink); }

/* ---- Admin storage page helpers ------------------------------------------ */
.notice { margin: 0 0 1.1rem; padding: 0.7rem 1rem; border-radius: 12px; font-size: 0.9rem; font-weight: 600; }
.notice--ok { background: var(--ok-bg); color: var(--ok); border: 1px solid var(--ok-line); }
.notice--warn { background: var(--warn-bg); color: var(--warn-ink); border: 1px solid var(--warn-line); }
.form-narrow { max-width: 460px; }
.form-narrow label { display: block; margin: 0.9rem 0 0.3rem; font-size: 0.86rem; font-weight: 600; }
.form-narrow input, .form-narrow select { width: 100%; padding: 0.55rem 0.7rem; border: 1px solid var(--line); border-radius: 10px; font: inherit; }
.link-danger { color: var(--error); }
.link-danger:hover { color: var(--error-ink); }

/* ---- Reports: tabs, filter panel, chips, tags ---------------------------- */
.report-tabs { display: flex; gap: 0.4rem; margin: 0 0 1.2rem; }
.report-tab {
  padding: 0.55rem 1.1rem; border-radius: 999px; font-size: 0.85rem; font-weight: 600;
  text-decoration: none; color: var(--accent-btn); background: var(--panel); border: 1.5px solid var(--line);
}
.report-tab.is-active { background: var(--accent-btn); color: var(--accent-ink); border-color: var(--accent-btn); }
.report-tab:hover { border-color: var(--accent-btn); }

.filter-panel { display: block; }
.filter-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.8rem 1rem; margin-bottom: 1rem;
}
.filter-field label { display: block; font-size: 0.78rem; font-weight: 600; color: var(--ink-soft); margin-bottom: 0.25rem; }
.filter-field input, .filter-field select {
  width: 100%; padding: 0.5rem 0.6rem; border: 1px solid var(--line); border-radius: 10px; font: inherit; font-size: 0.9rem;
}
.filter-check { display: flex; align-items: flex-end; }
.filter-check label { display: flex; align-items: center; gap: 0.4rem; font-size: 0.9rem; }
.filter-check input { width: auto; }

.chip-row { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chip {
  display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.35rem 0.7rem;
  border: 1px solid var(--line); border-radius: 999px; font-size: 0.78rem; cursor: pointer; background: var(--panel);
}
.chip input { accent-color: var(--accent-btn); }
.chip:has(input:checked) { background: var(--accent-soft); border-color: var(--accent-btn); color: var(--accent-dark); }

.filter-actions { display: flex; gap: 0.6rem; align-items: center; margin-top: 1rem; flex-wrap: wrap; }
.filter-actions .btn-primary, .filter-actions .btn-secondary { margin-top: 0; }

.report-table .file-name { display: block; max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.report-table .hint { display: block; font-size: 0.74rem; }
.tag { display: inline-block; padding: 0.1rem 0.45rem; border-radius: 6px; font-size: 0.68rem; font-weight: 600; margin-left: 0.3rem; }
.tag-guest { background: var(--neutral-bg); color: var(--ink-soft); }

/* ---- Fix: primary/secondary buttons must keep color inside filter bars ---- */
.filter-row .btn-primary, .filter-bar .btn-primary,
.member-add-bar .btn-primary {
  background: var(--accent-btn); color: var(--accent-ink); border: none;
}
.filter-row .btn-primary:hover, .filter-bar .btn-primary:hover,
.member-add-bar .btn-primary:hover { background: var(--accent-dark); color: var(--accent-ink); }
.filter-row .btn-secondary, .filter-bar .btn-secondary {
  background: var(--panel); color: var(--accent-btn); border: 1.5px solid var(--accent-btn);
}

/* ---- Add-member bar layout ---------------------------------------------- */
.member-add-bar { display: flex; gap: 1rem; align-items: flex-end; flex-wrap: wrap; margin-top: 0.4rem; }
.member-add-bar .filter-field { margin: 0; }
.member-add-email { flex: 1 1 320px; min-width: 260px; }
.member-add-email input { width: 100%; }
.member-add-days { flex: 0 0 130px; }
.member-add-days input { width: 100%; }
.member-add-action .btn-primary { margin: 0; }

/* ---- Fix: wide report table must scroll inside its card, not overflow ----- */
.report-table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.report-table { min-width: 900px; }
.report-table th, .report-table td { white-space: nowrap; }
.report-table .file-name { max-width: 220px; }

/* ---- Payment settings: status pills + info notice ------------------------ */
.pill { display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.02em; }
.pill-ok   { background: var(--ok-bg); color: var(--ok); }
.pill-warn { background: var(--error-bg); color: var(--error); }
.pill-live { background: var(--ok-bg); color: var(--ok); }
.pill-test { background: var(--warn-bg); color: var(--warn-ink); }
.notice--info { background: var(--accent-soft); border: 1px solid var(--accent-line); color: var(--accent-dark); padding: 0.8rem 1rem; border-radius: 10px; margin: 1rem 0; }
.notice code, .card code { background: rgba(0,0,0,0.05); padding: 0.05rem 0.35rem; border-radius: 5px; font-size: 0.85em; }

/* ---- Custom request: separate, revealed-on-demand section ---------------- */
.custom-card { border: 1px dashed var(--line); }
.custom-card h2 { margin-top: 0; }
.custom-form { margin-top: 1rem; }
.custom-field { display: block; }
.custom-label { display: block; font-weight: 600; font-size: 0.9rem; margin-bottom: 0.4rem; }
.custom-form textarea { width: 100%; padding: 0.7rem 0.8rem; border: 1px solid var(--line); border-radius: 10px; font: inherit; resize: vertical; }
.custom-actions { display: flex; gap: 0.6rem; margin-top: 0.8rem; flex-wrap: wrap; }
.custom-actions .btn-primary, .custom-actions .btn-secondary { margin: 0; }
.auto-options-actions { margin-top: 0.5rem; }
#custom-open { margin-top: 0.4rem; }


/* ---- Custom mode: dimmed but returnable automatic options ----------------- */
.options-form.is-dimmed { opacity: 0.45; position: relative; transition: opacity 0.15s ease; }
.options-form.is-dimmed::after {
  content: ""; position: absolute; inset: 0; cursor: pointer; border-radius: inherit;
}
.custom-cancel-btn { font-weight: 600; color: var(--accent-btn); }
.custom-cancel-btn:hover { text-decoration: underline; }

/* ---- Ready-stage summary card (vehicle + applied mods) ------------------- */
.summary-card { border-right: 5px solid var(--accent-btn); }
.summary-card h2 { margin-top: 0; }
.summary-mods { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin: 0.6rem 0 1.1rem; }
.summary-label { font-weight: 600; font-size: 0.9rem; color: var(--ink-soft); }
.mod-chip {
  display: inline-block; padding: 0.25rem 0.7rem; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-dark);
  font-weight: 700; font-size: 0.8rem; letter-spacing: 0.02em;
}

/* ============================================================================
   2026-07-28 — UX refresh (cerinta Xprime): register-first gate, validitate
   download + countdown, dashboard utilizator, admin control-panel shell.
   ========================================================================== */

/* ---- Register-first upload gate ------------------------------------------ */
.auth-gate { text-align: center; padding: 2.6rem 2rem; }
.auth-gate h2 { margin-top: 0; }
.auth-gate .hint { max-width: 34rem; margin-inline: auto; }
.auth-gate-actions { display: flex; gap: 0.9rem; justify-content: center; flex-wrap: wrap; margin-top: 1.4rem; }
.auth-gate-actions .btn-primary, .auth-gate-actions .btn-secondary { margin-top: 0; }

/* ---- Download validity + countdown (paid page) --------------------------- */
.dl-validity {
  margin: 1rem 0 0.4rem; padding: 0.85rem 1.1rem;
  background: var(--neutral-bg); border-radius: var(--radius-s);
  border-left: 4px solid var(--accent-btn);
  max-width: 30rem;
}
.dl-validity-row { display: flex; justify-content: space-between; gap: 1rem; padding: 0.15rem 0; }
.dl-validity-label { color: var(--ink-soft); font-size: 0.88rem; font-weight: 500; }
.dl-validity-date { font-weight: 600; }
.dl-countdown { font-weight: 700; font-size: 1.05rem; color: var(--accent-btn); font-variant-numeric: tabular-nums; }
.dl-validity--soon { border-left-color: var(--warn); }
.dl-validity--soon .dl-countdown { color: var(--warn-ink); }
.dl-validity--expired { border-left-color: var(--error); background: var(--error-bg); }
.dl-validity--expired .dl-countdown { color: var(--error); }
.dl-attempts { margin: 0.3rem 0 0; }
.dl-ticket-btn { margin-left: 0.7rem; }
.btn-disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
/* BUTOANELE DEZACTIVATE, INDIFERENT DE FEL (2026-09-16, raportat de Xprime).
   Exista stil doar pentru `.btn-primary:disabled`. Un `.btn-secondary` sau un
   `.btn-small` cu `disabled` se desena identic cu unul activ — adica un buton
   care pare ca muta bani si nu face nimic la apasare (cazul „Refund red coins"
   pe o comanda din care nu s-a luat nimic). Regula e pe TOATE clasele de buton,
   ca sa nu mai depinda de care a fost stilizata. */
.btn-secondary:disabled, .btn-secondary[disabled],
.btn-small:disabled, .btn-small[disabled],
button:disabled, button[disabled] { opacity: .45; cursor: not-allowed; }

/* ---- Account dashboard --------------------------------------------------- */
.account-stats { margin-top: 0; }
.section-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.section-head h2 { margin-bottom: 0.8rem; }
.btn-inline { margin-top: 0; padding: 0.55rem 1.4rem; }
.account-grid { display: grid; grid-template-columns: 3fr 2fr; gap: 0 1.6rem; align-items: start; }
@media (max-width: 860px) { .account-grid { grid-template-columns: 1fr; } }
.vehicle-data-stack { grid-template-columns: 1fr; }
.jobs-table .job-file { font-weight: 500; }

/* Friendly job-status badges (account + job pages). One hue per meaning:
   green = ready to take, red = gone/bad, amber = needs the user, blue = ours. */
.ui-badge {
  display: inline-block; padding: 0.22rem 0.7rem; border-radius: 999px;
  font-size: 0.76rem; font-weight: 600; white-space: nowrap;
}
.ui-available        { background: var(--ok-bg); color: var(--ok); }
.ui-expired          { background: var(--error-bg); color: var(--error); }
.ui-failed           { background: var(--error-bg); color: var(--error); }
.ui-not_supported    { background: var(--neutral-bg); color: var(--ink-soft); }
.ui-processing       { background: var(--accent-soft); color: var(--accent-dark); }
.ui-in_review        { background: var(--accent-soft); color: var(--accent-dark); }
.ui-action_needed    { background: var(--warn-bg); color: var(--warn-ink); }
.ui-awaiting_payment { background: var(--warn-bg); color: var(--warn-ink); }
/* Predat procesarii manuale (2026-09-14, cerinta Xprime). Nu e nici esec, nici
   „in lucru la noi": fisierul a plecat pe alt drum, ales de client. Tonul
   neutru al insignei spune exact asta — nu alarmeaza si nu promite. */
.ui-moved_to_manual  { background: var(--neutral-bg); color: var(--ink-soft); }

/* ---- Admin control-panel shell ------------------------------------------- */
body.admin { background: var(--bg); }
.admin-shell { display: flex; min-height: 100vh; align-items: stretch; }
.admin-side {
  flex: 0 0 232px; display: flex; flex-direction: column;
  background: var(--panel); border-right: 1px solid var(--line);
  padding: 1.3rem 1rem 1.1rem; position: sticky; top: 0; height: 100vh;
  overflow-y: auto;
}
.admin-brand { display: block; font-size: 1.15rem; margin-bottom: 1.4rem; padding: 0 0.55rem; }
.admin-nav { flex: 1; }
.admin-nav-group { margin-bottom: 1.15rem; }
.admin-nav-title {
  display: block; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-soft); padding: 0 0.55rem; margin-bottom: 0.3rem;
}
.admin-nav-link {
  display: block; padding: 0.42rem 0.55rem; border-radius: var(--radius-s);
  text-decoration: none; font-size: 0.9rem; font-weight: 500; color: var(--ink);
}
.admin-nav-link:hover { background: var(--neutral-bg); color: var(--accent-btn); }
.admin-nav-link.is-active { background: var(--accent-btn); color: var(--accent-ink); font-weight: 600; }
.admin-side-foot { border-top: 1px solid var(--line); padding-top: 0.8rem; }
.admin-logout { font-size: 0.85rem; }
.admin-who { display: block; font-size: 0.74rem; overflow-wrap: anywhere; margin-top: 0.2rem; }
.admin-main { flex: 1; min-width: 0; padding: 1.8rem 2.2rem 3rem; }
.admin-main h1 { font-size: 1.7rem; margin-bottom: 0.9rem; }

@media (max-width: 900px) {
  .admin-shell { flex-direction: column; }
  .admin-side { position: static; height: auto; flex: none; border-right: none; border-bottom: 1px solid var(--line); }
  .admin-nav { display: flex; flex-wrap: wrap; gap: 0.2rem 1.2rem; }
  .admin-nav-group { margin-bottom: 0.4rem; }
  .admin-main { padding: 1.4rem 1.2rem 2.5rem; }
}

/* ---- Guest quota (2026-07-28) -------------------------------------------- */
.guest-remaining { margin: 0.9rem 0 0; font-weight: 500; color: var(--accent-dark); }
.guest-note { margin: 0.6rem 0 0.2rem; font-weight: 500; }
#guest-process-btn { margin-top: 0.8rem; }

/* ---- Files database: cascading filters (2026-07-29) ---------------------- */
.catalog-filter-card { padding: 1.3rem 1.6rem 1.4rem; margin-bottom: 1.2rem; }
.catalog-filter-card .filter-grid { margin-bottom: 0.9rem; }
/* 2026-07-31 (cerinta Xprime): cascada are acum CINCI niveluri
   (Marca > Serie > Model > Producator ECU > ECU). Cu auto-fit si minim 160px,
   pe ecran larg ieseau 5 pe un rand dar ultimul ramanea orfan pe latimi medii.
   minmax mai mic + auto-fit tine randul intreg pe desktop si il rupe curat in
   doua randuri de cate 2-3 pe tablete. */
.filter-grid-cascade { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
@media (min-width: 1100px) { .filter-grid-cascade { grid-template-columns: repeat(5, 1fr); } }
.filter-grid-cascade select:disabled { opacity: .55; cursor: not-allowed; }
.catalog-search-row { display: flex; gap: 0.7rem; flex-wrap: wrap; align-items: center; }
.catalog-search-row select[name=in] { width: auto; max-width: 14rem; }
.catalog-search-row input[type=text] { flex: 1 1 16rem; }
.catalog-search-row .btn-primary, .catalog-search-row .btn-secondary { margin-top: 0; }
.catalog-reset { padding: 0.55rem 1.3rem; }

/* ---- Client panel (2026-07-29, dyno-style) — reuses .admin-* shell -------- */
.panel-topbar {
  display: flex; align-items: center; justify-content: flex-end; gap: 1rem;
  padding: 0 0 1.1rem; margin-bottom: 1.2rem; border-bottom: 1px solid var(--line);
}
.panel-credits { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.25; }
.panel-credits-label { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-soft); }
.panel-credits-value { font-size: 1.25rem; font-weight: 700; color: var(--accent-btn); }
.panel-grid { display: grid; grid-template-columns: 3fr 2fr; gap: 0 1.6rem; align-items: start; }
@media (max-width: 960px) { .panel-grid { grid-template-columns: 1fr; } }
.nav-badge {
  display: inline-block; min-width: 1.3rem; text-align: center; margin-left: 0.4rem;
  padding: 0.02rem 0.4rem; border-radius: 999px; font-size: 0.72rem; font-weight: 700;
  background: var(--accent-soft); color: var(--accent-dark);
}
.admin-nav-link.is-active .nav-badge { background: rgba(255, 255, 255, 0.25); color: var(--accent-ink); }

/* ── SEMNUL „NOU" PE RANDUL DE TICHET 2026-09-22 ──────────────────────────
   Perechea semnalului din meniu: insigna spune CATE, randul spune CARE. Sta
   langa subiect, nu intr-o coloana proprie — o coloana goala in noua randuri
   din zece ar fi costat latime pe telefon degeaba. Subiectul necitit se si
   ingroasa: e semnalul care se prinde din priviri, inainte sa citesti eticheta. */
/* `tk-unread`, NU `tk-new`: in ecranele de tichete exista deja `tk-new-link`,
   butonul „deschide un tichet nou". Doua intelesuri diferite sub acelasi prefix
   („nou de citit" si „creeaza unul nou") se citesc gresit exact cand cauti
   repede ceva. */
.tk-unread {
  display: inline-block; margin-left: .45rem; vertical-align: middle;
  padding: .05rem .4rem; border-radius: 999px;
  font-size: .68rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: var(--accent-soft); color: var(--accent-dark);
}
td.wrap.is-unread > a { font-weight: 700; color: var(--ink); }

.stat-link { display: block; margin-top: 0.35rem; font-size: 0.8rem; font-weight: 500; text-decoration: none; }

/* quick-upload dropzone */
.dropzone { border: 2px dashed var(--accent-soft); cursor: pointer; text-align: center; padding: 1.6rem 1.2rem; transition: border-color 0.15s ease, background 0.15s ease; }
.dropzone.is-drag { border-color: var(--accent-btn); background: var(--accent-soft); }
.dropzone-input { position: absolute; left: -9999px; }
.dropzone-icon { font-size: 1.8rem; color: var(--accent-btn); display: block; margin-bottom: 0.3rem; }
.dropzone-text { margin: 0 0 0.2rem; font-weight: 600; }
.dropzone[data-disabled="1"] { opacity: 0.5; cursor: not-allowed; }

/* clickable table rows (catalog + panel) */
tr.row-link { cursor: pointer; }
tr.row-link:hover td { background: var(--accent-soft); }

/* admin catalog: hidden files dimmed */
tr.row-hidden td { opacity: 0.55; }

/* ---- File detail page, dyno-style (2026-07-29) --------------------------- */
.file-detail-grid { display: grid; grid-template-columns: 3fr 2fr; gap: 1.4rem; align-items: start; }
@media (max-width: 860px) { .file-detail-grid { grid-template-columns: 1fr; } }
.file-specs div { padding: 0.5rem 0; }
.file-specs dt { font-weight: 500; }
.file-price-title { margin-top: 1.6rem; }
.buy-card { border-left: 5px solid var(--accent-btn); }
.buy-card .btn-primary { margin-top: 0.8rem; }
/* badge-urile nu se mai frang pe litere ("Origina / l") */
.status-badge, .mod-chip, .ui-badge, .mem-pill, .pill { white-space: nowrap; }

/* ---- Abonamente / Subscription plans (cerinta Xprime, 2026-07-31) ---- */
.plans-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:1.2rem;margin:1.5rem 0}
.plan-card{display:flex;flex-direction:column;gap:.75rem}
.plan-card--active{outline:2px solid var(--accent);outline-offset:2px}
.plan-head{display:flex;align-items:center;justify-content:space-between;gap:.5rem}
.plan-head h2{margin:0}
.plan-badge{font-size:.7rem;font-weight:700;letter-spacing:.06em;background:var(--accent);color:var(--accent-ink);border-radius:999px;padding:.15rem .6rem}
.plan-desc{margin:0}
.plan-benefits{list-style:none;padding:0;margin:.25rem 0;display:flex;flex-direction:column;gap:.4rem}
.plan-benefits li{position:relative;padding-left:1.4rem;line-height:1.35}
.plan-benefits li::before{content:"✓";position:absolute;left:0;top:0;color:var(--accent);font-weight:700}
/* Randul de perioada e definit INTR-UN SINGUR LOC, mai jos, langa comentariul
   „Plans: randul de perioada". Aici a existat pana pe 2026-08-21 o a doua
   definitie (o grila pe trei coloane) si undeva mai incolo o a treia — trei
   seturi de reguli pentru aceleasi elemente, care se bateau intre ele dupa
   ordinea din fisier. Asa arata o pagina „imprastiata": nu dintr-o regula
   gresita, ci din trei regretate pe rand. Au ramas doar `.plan-price-value` si
   `.plan-period-label`, care nu tin de asezare. */
.plan-period-label{font-weight:600}
.plan-price-value{font-size:1.15rem;font-weight:700}
.plans-foot{margin-top:1rem;max-width:60ch}
/* 2026-07-31: linia "beneficiile nu sunt setate" nu e un beneficiu — fara bifa. */
.plan-benefits li.hint::before{content:"—";color:inherit;opacity:.6;font-weight:400}
/* Beneficiile aratate si in panoul de reinnoire si in previzualizarea din admin. */
.sub-tier-benefits{margin:.4rem 0 0;font-size:.92rem;gap:.25rem}

/* CE ACOPERA UN PLAN — caseta de dinaintea platii (2026-09-12, cerinta Xprime).
   Chihlimbar, ca toate lucrurile care nu s-au stricat dar pot strica o
   asteptare: banda de dispozitiv, banda de expirare, nota de plata a procesarii
   manuale. Acelasi ton peste tot inseamna ca omul stie ce citeste inainte sa
   citeasca. Dunga din stanga si umplerea ridicata o scot din pagina fara sa
   tipe la client — panoul e B2B, nu o reclama. */
.plan-scope {
  margin: 0 0 1.3rem; padding: 1.1rem 1.25rem;
  border: 1px solid var(--warn-line); border-left: 4px solid var(--warn);
  border-radius: var(--radius-s); background: var(--warn-bg-strong, var(--warn-bg));
}
.plan-scope-title {
  margin: 0 0 .5rem; color: var(--warn-ink);
  font-size: 1.02rem; font-weight: 700; letter-spacing: .01em;
}
.plan-scope-text { margin: 0 0 .9rem; max-width: 72ch; line-height: 1.6; font-size: .92rem; }
/* Bifa e randul pe care se apasa: are contrastul ei si un chenar propriu, ca sa
   nu para o nota de subsol a paragrafului de deasupra. */
.plan-scope-check {
  display: flex; align-items: flex-start; gap: .6rem;
  padding: .65rem .75rem; border: 1px solid var(--warn-line);
  border-radius: var(--radius-s); background: rgba(0,0,0,.16);
  font-size: .92rem; font-weight: 600; line-height: 1.5; cursor: pointer;
}
.plan-scope-check input { margin-top: .22rem; flex: none; }
/* Butoanele stinse spun de ce sunt stinse: nu se apasa, si se vede. */
.plan-buy button[disabled], .sub-plan-actions button[disabled] { opacity: .45; cursor: not-allowed; }
/* RANDUL CARE VINDE PLANUL 2026-09-12 (cerinta Xprime: „vreau ca dimensiunea
   fontului sa fie mai mare, cuvantul «green» sa fie scris cu verde… sa iasa in
   evidenta").

   „60 green coins every day" e singurul rand din lista care spune cat primesti,
   si arata exact ca „limita de upload". Acum e mai mare, cifra e ingrosata, iar
   cuvantul de culoare poarta culoarea monedei. Culoarea INTARESTE, nu duce
   informatia: cuvantul scrie in continuare „green", deci randul se citeste la
   fel si de cineva care nu distinge verdele de rosu. Aceeasi regula ca la
   bulinele din portofel. */
.plan-benefits li.is-coins { font-size: 1.12rem; font-weight: 600; line-height: 1.3; }
.plan-benefits li.is-coins::before { top: .1rem; font-size: 1rem; }
.coin-count { font-weight: 700; font-variant-numeric: tabular-nums; }
.coin-word { font-weight: 700; }
.coin-word--green { color: var(--coin-green-ink); }
.coin-word--red { color: var(--coin-red-ink); }
/* In lista stransa din panou si in previzualizarea din admin randul ramane mai
   mare decat vecinii lui, dar proportional cu ei. */
.sub-tier-benefits li.is-coins, .data-table .plan-benefits li.is-coins { font-size: 1.02rem; }
.data-table .plan-benefits{margin:0;gap:.25rem;font-size:.92rem}
/* 2026-07-31: marcaj in Admin -> Groups pentru clasa a carei cota e calcata de o
   regula pe optiune. Fara el, setai cota si nu intelegeai de ce nu se schimba. */
.rule-overridden{display:inline-block;margin-top:.25rem;color:var(--warn-ink);background:var(--warn-bg);
  border:1px solid var(--warn-line);border-radius:.35rem;padding:.15rem .45rem;line-height:1.35}
.rule-overridden .mono{color:inherit}
.rule-overridden .link-button{color:var(--warn-ink);text-decoration:underline;margin-left:.35rem}
.hidden-form{display:none}
/* Account subscription panel */
/* ---------------------------------------------------------------------------
   ABONAMENTE: UN TIER = UN CARD, PERIOADELE ALATURI  (rescris 2026-08-21)
   ---------------------------------------------------------------------------
   Inainte, fiecare tier era un rand de flex cu numele in stanga si perioadele
   in dreapta. Pe un ecran lat asta insemna numele lipit de marginea din stanga,
   cutiile lipite de cea din dreapta si un metru de gol la mijloc — plus cutii
   inalte (upgrade) langa randuri subtiri (abonare simpla), stivuite pe verticala.
   Pagina se citea ca aruncata din avion.

   Acum: tierul e un CARD, iar cele trei perioade stau UNA LANGA ALTA intr-o
   grila. Grila se strange singura pe ecrane inguste, fara media query.
   --------------------------------------------------------------------------- */
.sub-tier-row{display:block;padding:1.1rem 1.2rem;margin-bottom:.9rem;
              border:1px solid var(--line);border-radius:var(--radius)}
.sub-tier-row:last-child{margin-bottom:0}
.sub-tier-name{display:flex;flex-direction:column;gap:.15rem;margin-bottom:.9rem}
.sub-tier-plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(15.5rem,1fr));
                gap:.7rem;align-items:stretch}
/* Fiecare perioada e o cutie cu aceeasi structura: eticheta sus, sumele la
   mijloc, butoanele jos. `margin-top:auto` pe actiuni le aduce pe toate pe
   aceeasi linie, oricat de diferite ar fi cutiile in inaltime. */
.sub-plan-buy{display:flex;flex-direction:column;gap:.45rem;
              padding:.7rem .8rem;border:1px solid var(--line);
              border-radius:var(--radius-s);background:var(--neutral-bg)}
.sub-plan-buy .sub-plan-actions{margin-top:auto}
.sub-plan-label{font-weight:600;text-align:right}
/* Upload ownership + restore option (2026-07-31) */
.terms-own{display:flex;gap:.5rem;align-items:flex-start;margin:.6rem 0;line-height:1.35}
.opt-restore{font-weight:600}
.restore-intro{max-width:62ch}

/* ── Restore CTA pe pagina de catalog (2026-07-31) ─────────────────────────
   Sub hero, inaintea filtrelor: catalogul e referinta, restaurarea e serviciul. */
.catalog-restore-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  /* 2026-07-31: fara bara colorata pe margine (cerinta Xprime) si cu spatiu
     propriu fata de cardul de filtre de dedesubt -- altfel cele doua carduri
     se lipesc si arata ca o singura sectiune. */
  margin-bottom: 1.2rem;
}
.catalog-restore-copy { flex: 1 1 22rem; min-width: 0; }
.catalog-restore-cta h2 { margin: 0 0 .35rem; font-size: 1.15rem; }
.catalog-restore-cta p { margin: 0; color: var(--muted); }
.catalog-restore-btn { flex: 0 0 auto; white-space: nowrap; }
@media (max-width: 620px) {
  .catalog-restore-cta { flex-direction: column; align-items: flex-start; }
  .catalog-restore-btn { width: 100%; text-align: center; }
}

/* Declaratia de proprietate in dropzone-ul din panou (2026-07-31) */
.dropzone-terms {
  display: flex;
  gap: .55rem;
  align-items: flex-start;
  margin-top: .9rem;
  padding-top: .9rem;
  border-top: 1px solid var(--line);
  font-size: .85rem;
  line-height: 1.45;
  text-align: left;
  cursor: default;
}
.dropzone-terms input[type="checkbox"] { margin-top: .2rem; flex: 0 0 auto; }
.dropzone.needs-terms .dropzone-terms { color: var(--error); }
.dropzone.needs-terms .dropzone-terms input[type="checkbox"] { outline: 2px solid var(--error); outline-offset: 2px; }

/* ── Admin: jurnal de activitate per utilizator / grup (2026-07-31) ──────── */
.user-link { color: inherit; text-decoration: none; border-bottom: 1px dotted currentColor; }
.user-link:hover { color: var(--accent); }
.activity-actions { flex-wrap: wrap; gap: .35rem; }
.activity-actions .btn-small.is-active { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.activity-table td.nowrap { white-space: nowrap; }
.activity-table .activity-meta { max-width: 34rem; word-break: break-word; font-size: .85rem; }
.user-detail-actions { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; }

/* ── Admin Pricing: meniu unic + combinatii existente (2026-08-01, Xprime) ── */
/* Constructorul de pachete (mutat din Packages) + lista tuturor combinatiilor.
   .opt-check.is-on = randul bifat se evidentiaza dinamic, in timp real. */
.opts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: .45rem;
  margin: .35rem 0;
}
.opt-check {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .5rem .7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, box-shadow .12s ease;
  user-select: none;
}
.opt-check:hover { border-color: var(--accent); }
.opt-check .hint { margin-left: auto; }
.opt-check.is-on {
  background: var(--accent-soft);
  border-color: var(--accent);
  box-shadow: inset 3px 0 0 var(--accent);
}
.opt-check.is-on > span:first-of-type { font-weight: 700; }

/* Badge pentru combinatiile care exista deja ca fisier-sursa pe server. */
.pill-detected { background: var(--accent-soft); color: var(--accent-dark); }

/* Rand de combinatie detectata, inca fara pret: cere atentia operatorului. */
tr.combo-unpriced td { background: var(--warn-bg); }
tr.combo-unpriced td:first-child { box-shadow: inset 3px 0 0 var(--warn); }

#pkgForm .preview { margin: .7rem 0; padding: .55rem .7rem; background: var(--panel-2); border-radius: 8px; }
#pkgForm fieldset { border: 1px solid var(--line); border-radius: 8px; margin: .6rem 0; padding: .6rem .8rem; }
#pkgForm legend { padding: 0 .35rem; font-weight: 700; font-size: .9rem; }

/* ── REPORTING PRO (2026-08-01, Xprime): dashboard + raport per user ─────── */
.report-filter { align-items: center; }
.report-presets { display: flex; align-items: center; gap: .5rem; margin: -.4rem 0 1.1rem; flex-wrap: wrap; }
.preset-chip {
  display: inline-block; padding: .3rem .85rem; border: 1px solid var(--line);
  border-radius: 999px; font-size: .85rem; text-decoration: none; color: inherit;
  transition: border-color .12s ease, background .12s ease;
}
.preset-chip:hover { border-color: var(--accent); }
.preset-chip.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.report-presets .hint { margin-left: auto; }

.kpi-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

.chart-card h2 { margin-bottom: .6rem; }
.chart { width: 100%; }
.chart-legend { display: flex; gap: 1.1rem; margin: 0 0 .5rem; flex-wrap: wrap; }
.chart-key { display: inline-flex; align-items: center; gap: .4rem; font-size: .85rem; color: var(--muted); }
.chart-swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }

.report-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; align-items: start; }
@media (max-width: 980px) { .report-cols { grid-template-columns: 1fr; } }

.report-users td, .report-users th { vertical-align: middle; }
.report-users td > .hint { display: block; }

.user-report-head { display: flex; justify-content: space-between; gap: 1.5rem; align-items: flex-start; flex-wrap: wrap; }
.user-report-side { text-align: right; display: flex; flex-direction: column; gap: .25rem; align-items: flex-end; }

/* Optiune inca inactiva (fara pret individual) in constructorul de pachete. */
.opt-check--inactive { opacity: .62; }
.opt-check--inactive.is-on { opacity: 1; }

/* ── User detail lizibil (2026-08-01, Xprime): jobs/ledger/activity ──────── */
.data-table .file-name { display: block; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.data-table td.nowrap, .data-table .nowrap { white-space: nowrap; }
.amount-pos { color: var(--ok); }
.amount-neg { color: var(--error); }
.ledger-desc { font-size: .85rem; max-width: 18rem; }
.panel-grid .card { overflow-x: auto; }
@media (max-width: 1240px) { .panel-grid { grid-template-columns: 1fr; } }

/* PRET DUBLU (2026-08-01, Xprime): pret brut taiat + pret final cu discount + economie */
.options-total { flex-direction: column; align-items: stretch; gap: 0.3rem; }
.options-trow { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.options-base-label { font-size: 0.88rem; color: var(--muted); }
.options-base-value { font-size: 0.92rem; color: var(--muted); }
.options-base-value s { text-decoration-thickness: 1.5px; }
.options-save { justify-content: flex-end; font-size: 0.88rem; font-weight: 600; color: var(--ok); }

/* ANTI-DUBLURI v2: semnal discret (fara blocare) — bifarea ar ateriza pe un
   pachet existent; ramane bifabila. + lista pachetelor care contin selectia. */
.opt-check--exists { border-style: dashed; }
.opt-check--exists .mono.hint { color: var(--warn-ink); }
.opt-check--blocked { opacity: .4; cursor: not-allowed; }
.opt-check--blocked .mono.hint { color: var(--error); }
.pkg-existing { margin: -0.3rem 0 0.7rem; line-height: 1.9; }
.pkg-existing .pill { background: var(--warn-bg); color: var(--warn-ink); }

/* /detect: panoul de upload se lipea de sectiunea de pasi (upload-panel are
   margin-bottom:0, iar .steps n-avea margin-top). Doar cand steps urmeaza
   direct dupa upload-panel (pagina /detect) — pe home precede .entry-grid. */
.upload-panel + .steps { margin-top: 2.2rem; }

/* REVENUE GUARD 2026-08-02: link "contactează-ne" in locul pretului la o
   combinatie fara pret (rand de optiune + rand de total). */
.opt-price-contact { margin-left: auto; font-weight: 600; font-size: 0.9rem; white-space: nowrap; text-decoration: underline; }
.options-contact .options-total-value a { font-weight: 700; text-decoration: underline; }

/* FIX 2026-08-02 (Xprime): randurile din total (contact/base/save/total) se
   ascundeau prin atributul [hidden], dar `.options-trow{display:flex}` il
   suprascria (regula de autor bate UA) -> ramaneau "agatate". Regula asta,
   mai specifica, face din nou hidden sa functioneze. */
.options-trow[hidden] { display: none; }

/* NU-I AJUNG COINS (2026-08-20, Xprime): avertisment sub total, cu butonul de
   cumparare langa el. Chihlimbariu, nu rosu: nu e o eroare — e o informatie
   care are un drum de rezolvare la un click distanta, iar rosul l-ar face pe
   om sa creada ca s-a stricat ceva. Randul se aprinde si se stinge pe masura ce
   bifeaza optiuni, deci nu are voie sa impinga pagina: sta in fluxul totalului,
   la fel ca randul de economie. */
/* IESIREA DIN FUNDATURA (2026-08-20, Xprime): fisier gata, sold insuficient si
   niciun procesator de card pornit -> cardul de plata ramanea o caseta cu un
   pret si o bifa, fara nicio usa. Blocul asta e usa. Sta sub butoanele de plata,
   incadrat, ca sa se citeasca drept "alta cale", nu drept inca un buton de
   plata care nu merge. */
.pay-ways {
  margin-top: 1rem; padding: .95rem 1.1rem; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel-2);
}
.pay-ways-lead { margin: 0 0 .75rem; line-height: 1.5; }
.pay-ways-lead strong { display: block; }
.pay-ways-lead span { color: var(--muted); }
.pay-ways-actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.pay-ways .hint { margin: .75rem 0 0; }
@media (max-width: 560px) {
  .pay-ways-actions { flex-direction: column; }
  .pay-ways-actions > a { text-align: center; }
}

.options-short {
  align-items: center; gap: .8rem; margin-top: .5rem; padding: .6rem .8rem;
  border-radius: 8px; border: 1px solid var(--warn-line); background: var(--warn-bg);
  color: var(--warn-ink); font-size: .9rem; line-height: 1.45;
}
.options-short strong { display: block; color: var(--warn-ink); }
.options-short .btn-inline { flex: none; white-space: nowrap; }
@media (max-width: 560px) {
  .options-short { flex-direction: column; align-items: stretch; }
  .options-short .btn-inline { text-align: center; }
}

/* Buton primar dezactivat = albastru fade (ca "Upload & identify" inactiv).
   Inainte stilul exista doar in .upload-form; butonul "Process my file" din
   .options-form ramanea albastru plin cand selectia era fara pret. */
.btn-primary:disabled, .btn-primary[disabled] { opacity: 0.45; cursor: not-allowed; }

/* COOKIE BANNER 2026-08-02 (Xprime): notificare/consimtamant jos, discreta. */
.cookie-banner { position: fixed; left: 0; right: 0; bottom: 0; z-index: 9999;
  background: var(--ink-surface); color: var(--onink);
  border-top: 1px solid var(--line); box-shadow: 0 -6px 24px rgba(0,0,0,.45); }
.cookie-banner-inner { max-width: 1100px; margin: 0 auto; padding: 1rem 1.2rem;
  display: flex; gap: 1.2rem; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.cookie-banner-text { flex: 1 1 460px; min-width: 260px; }
.cookie-banner-text strong { font-size: 1rem; }
.cookie-banner-text p { margin: .3rem 0 0; font-size: .9rem; line-height: 1.5; color: var(--onink-soft); }
.cookie-banner-text a { color: var(--accent-bright); text-decoration: underline; }
.cookie-banner-actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.cookie-banner-actions .btn-secondary { background: transparent; color: var(--onink); border: 1px solid var(--onink-line); }
.cookie-banner-actions .btn-secondary:hover { border-color: var(--accent-bright); }
.cookie-prefs { margin-top: .7rem; display: grid; gap: .5rem; }
.cookie-cat { display: grid; grid-template-columns: auto 1fr; gap: .1rem .55rem; font-size: .88rem; align-items: start; }
.cookie-cat input { margin-top: .2rem; }
.cookie-cat span { font-weight: 600; }
.cookie-cat em { grid-column: 2; font-style: normal; color: var(--onink-dim); font-size: .82rem; }
.cookie-cat--locked span { color: var(--onink-dim); }
@media (max-width: 620px) { .cookie-banner-actions { width: 100%; } .cookie-banner-actions .cookie-btn { flex: 1 1 auto; } }

/* ============================================================================
   MANUAL FILE SERVICE 2026-08-02 (cerinta Xprime)
   Wizardul de procesare manuala, coada de admin si atributul Auto/Manual din
   lista de fisiere. Aceleasi variabile de tema — nimic nou in paleta.
   ========================================================================= */

/* butonul din pagina de detectie automata */
.manual-entry { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.manual-entry-text { color: var(--ink-soft); font-size: .92rem; flex: 1 1 240px; }
.manual-entry-btn { white-space: nowrap; }

/* atributul din lista unificata de fisiere */
.job-kind { display: inline-block; margin-left: .55rem; padding: .1rem .5rem;
  border-radius: 999px; font-size: .72rem; letter-spacing: .04em; text-transform: uppercase;
  border: 1px solid var(--line); color: var(--ink-soft); background: var(--neutral-bg); vertical-align: middle; }
.job-kind-manual { border-color: var(--accent-line); color: var(--accent-dark); background: var(--accent-soft); }

/* bara de pasi */
.mfs-steps { display: flex; gap: .4rem; list-style: none; margin: 1rem 0 1.4rem; padding: 0; flex-wrap: wrap; }
.mfs-step { display: flex; align-items: center; gap: .45rem; padding: .45rem .8rem;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel); font-size: .88rem; color: var(--ink-soft); }
.mfs-step a { display: flex; align-items: center; gap: .45rem; color: inherit; text-decoration: none; }
.mfs-step-no { display: inline-grid; place-items: center; width: 1.35rem; height: 1.35rem;
  border-radius: 50%; background: var(--neutral-bg); font-size: .78rem; font-weight: 700; }
.mfs-step.is-current { border-color: var(--accent); color: var(--ink); box-shadow: var(--shadow-soft); }
.mfs-step.is-current .mfs-step-no { background: var(--accent-btn); color: var(--accent-ink); }
.mfs-step.is-done .mfs-step-no { background: var(--ok-bg); color: var(--ok); }

/* formulare wizard */
.mfs-form .fld { display: block; margin-bottom: .9rem; }
.mfs-form .fld-label { display: block; font-size: .86rem; color: var(--ink-soft); margin-bottom: .25rem; }
.mfs-form input[type=text], .mfs-form input[type=number], .mfs-form input[type=search],
.mfs-form select, .mfs-form textarea { width: 100%; }
.mfs-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 0 1rem; }
.mfs-actions { display: flex; gap: .6rem; justify-content: flex-end; margin-top: 1.2rem;
  padding-top: 1rem; border-top: 1px solid var(--line); flex-wrap: wrap; align-items: center; }
.mfs-file-current { background: var(--neutral-bg); border-radius: 10px; padding: .6rem .8rem; font-size: .9rem; }

/* categorii */
.mfs-category-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: .7rem; margin: .9rem 0 1.1rem; }
.mfs-category { display: flex; gap: .6rem; align-items: flex-start; padding: .8rem .9rem;
  border: 1px solid var(--line); border-radius: 12px; cursor: pointer; background: var(--panel); }
.mfs-category:has(input:checked) { border-color: var(--accent); box-shadow: var(--shadow-soft); }
.mfs-category-body { display: grid; gap: .15rem; }
.mfs-category-title { font-weight: 600; }
/* Pictograma categoriei (2026-08-21). Sta pe acelasi rand cu butonul radio, la
   inaltimea titlului, si nu se strange cand textul din dreapta are trei randuri
   — de aia `flex-shrink: 0`. Culoarea o ia din text: gri cat cardul e neales,
   in culoarea marcii cand e ales, fara nicio regula in plus. */
.mfs-category-icon { flex-shrink: 0; margin-top: -.1rem; color: var(--ink-soft); }
.mfs-category:has(input:checked) .mfs-category-icon { color: var(--accent); }

/* tipuri de tuning */
.mfs-types { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: .6rem; margin-bottom: 1.4rem; }
.mfs-type { display: grid; grid-template-columns: auto 1fr auto; gap: .6rem; align-items: start;
  padding: .75rem .9rem; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); cursor: pointer; }
.mfs-type:has(input:checked) { border-color: var(--accent); box-shadow: var(--shadow-soft); }
.mfs-type.is-disabled { opacity: .45; cursor: not-allowed; background: var(--neutral-bg); }
.mfs-type-title { font-weight: 600; display: block; }
.mfs-type-price { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--accent-dark); font-weight: 600; }

/* optiuni */
.mfs-search { width: 100%; margin-bottom: .8rem; }
.mfs-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: .45rem; }
.mfs-option { display: grid; grid-template-columns: auto 1fr auto; gap: .55rem; align-items: center;
  padding: .6rem .8rem; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); cursor: pointer; }
.mfs-option:has(input:checked) { border-color: var(--accent); background: var(--panel-2); }
.mfs-option.is-disabled, .mfs-option.is-blocked { opacity: .45; cursor: not-allowed; background: var(--neutral-bg); }
.mfs-option-title { font-size: .93rem; }
.mfs-option-price { font-variant-numeric: tabular-nums; font-size: .85rem; color: var(--ink-soft); white-space: nowrap; }
.mfs-option-price.is-free { color: var(--ok); }

.mfs-total { display: flex; justify-content: space-between; align-items: baseline;
  margin-top: 1.2rem; padding: .8rem 1rem; border-radius: 12px; background: var(--neutral-bg); font-size: 1.05rem; }

/* termene */
.mfs-timeframes { display: grid; gap: .45rem; margin-bottom: 1.2rem; }
.mfs-timeframe { display: grid; grid-template-columns: auto 1fr auto; gap: .6rem; align-items: center;
  padding: .6rem .85rem; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; background: var(--panel); }
.mfs-timeframe:has(input:checked) { border-color: var(--accent); }
.mfs-timeframe-delta { font-variant-numeric: tabular-nums; font-size: .88rem; color: var(--ink-soft); }
.mfs-timeframe-delta.is-discount { color: var(--ok); }
.mfs-timeframe-delta.is-surcharge { color: var(--error); }
.mfs-parts-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: .3rem; margin-bottom: .8rem; }

/* fisa vehiculului: citire ECU + gain */
.mfs-vcard { margin: 1.1rem 0; padding: 1rem; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); }
.mfs-vcard-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.2rem; }
.mfs-vcard h3 { margin: 0 0 .5rem; font-size: .95rem; }
.mfs-read { display: flex; flex-wrap: wrap; gap: .35rem; }
.mfs-chip { display: inline-flex; gap: .35rem; align-items: baseline; padding: .25rem .6rem;
  border-radius: 999px; background: var(--accent-soft); color: var(--accent-dark);
  font-size: .78rem; letter-spacing: .03em; }
/* Regulile graficului cu o singura axa (`.ln-stock`, `.ln-tuned`, `.ax`) au
   fost sterse: sablonul scrie de mult `.ln.hp.stock` si `.ln.nm.tuned`, deci
   nu se mai potriveau cu nimic — dar `.mfs-chart { max-width: 440px }` de
   aici chiar se aplica, si se batea cu cel de mai jos. */
.mfs-estimate { margin-top: .3rem; font-size: .78rem; }

/* sumar + politici */
.mfs-summary-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 1rem; }
.mfs-kv td:first-child { color: var(--ink-soft); width: 42%; }
.mfs-policy { margin: 1rem 0; padding: .8rem 1rem; border: 1px solid var(--line); border-radius: 10px; background: var(--neutral-bg); }
.mfs-policy summary { cursor: pointer; font-weight: 600; }
.mfs-policy p { font-size: .88rem; line-height: 1.55; margin: .6rem 0 0; }
.mfs-optlist { margin: .4rem 0 0; padding-left: 1.1rem; font-size: .9rem; }
.mfs-filelist { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .5rem; }
.mfs-filelist li { display: flex; gap: .55rem; align-items: center; flex-wrap: wrap; }
.mfs-note { background: var(--neutral-bg); border-radius: 10px; padding: .7rem .9rem; font-size: .9rem; }

/* status + SLA */
.mfs-head { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.mfs-kind { text-transform: uppercase; letter-spacing: .05em; font-size: .74rem; }
.mfs-sla { display: flex; align-items: baseline; gap: .6rem; border-left: 3px solid var(--ok); }
.mfs-sla.is-soon { border-left-color: var(--warn); }
.mfs-sla.is-late { border-left-color: var(--error); }
.mfs-sla-label { color: var(--ink-soft); font-size: .88rem; }

/* ASTEAPTA RASPUNSUL CLIENTULUI 2026-08-22. Cand mingea e la client, blocul
   trebuie sa se vada de la prima privire — de-aia are chenar cald si nu se
   pierde intre celelalte carduri. */
.mfs-waiting { border-left: 3px solid var(--warn); }
.mfs-waiting-reason {
  margin: .4rem 0 .9rem;
  white-space: pre-line;      /* operatorul scrie pe randuri, se citeste pe randuri */
  overflow-wrap: anywhere;    /* un cod lung nu iese din chenar */
}
.mfs-schedule .mfs-schedule-head { display: flex; gap: .7rem; align-items: center; flex-wrap: wrap; margin-bottom: .6rem; }
.mfs-badge { padding: .2rem .65rem; border-radius: 999px; font-size: .78rem; font-weight: 600; }
.mfs-badge.ok { background: var(--ok-bg); color: var(--ok); }
.mfs-badge.muted { background: var(--neutral-bg); color: var(--ink-soft); }
.mfs-hours td { padding: .2rem .4rem; font-size: .86rem; }
.mfs-feedback textarea { width: 100%; }
.mfs-cancel { margin-top: .8rem; }

.ui-badge[class*="mfs-status-"] { background: var(--neutral-bg); color: var(--ink-soft); }
.mfs-status-delivered, .mfs-status-completed { background: var(--ok-bg) !important; color: var(--ok) !important; }
.mfs-status-rejected, .mfs-status-cancelled, .mfs-status-expired { background: var(--error-bg) !important; color: var(--error) !important; }
.mfs-status-awaiting_payment, .mfs-status-waiting_client { background: var(--warn-bg) !important; color: var(--warn-ink) !important; }

/* admin */
.sla-late { color: var(--error); font-weight: 600; }
.sla-soon { color: var(--warn-ink); }
.admin-two-col { display: grid; grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr); gap: 1rem; align-items: start; }
@media (max-width: 900px) { .admin-two-col { grid-template-columns: 1fr; } }
.admin-card.is-alert { border-color: var(--error); }
.opt.is-disabled { opacity: .45; }
.opt-manual { border: 1px solid var(--accent); border-radius: 10px; padding: .6rem .8rem; background: var(--panel-2); }
/* Comutatorul de procesare manuala a coborat la CAPATUL listei de optiuni
   (12.09.2026, cerinta Xprime), deci distanta trece de sus: se desparte de
   ultima grupa de modificari, nu de titlul paginii. */
.manual-switch { border: 0; padding: 0; margin: 1.1rem 0 .9rem; }

/* ============================================================================
   LIZIBILITATE TABELE 2026-08-02 (cerinta Xprime: "textele nu sunt aliniate,
   sar pe mai multe randuri").

   Cauza: `.data-table td { overflow-wrap: anywhere }` — regula pusa cand se
   spargeau numele lungi de fisiere. Efectul secundar: cand un tabel are multe
   coloane si spatiu putin, browserul rupe ORICE cuvant caracter cu caracter, iar
   coloanele ajung de 40px cu textul scris pe verticala.

   Solutia: implicit celulele NU se mai rup. Tabelul isi ia latimea naturala, iar
   cardul care il contine capata scroll orizontal. Rup doar celulele care chiar au
   nevoie (nume de fisiere, note, meta), si acolo pe cuvant, nu pe caracter.
   ========================================================================= */

/* 1. anulam ruperea agresiva mostenita */
.data-table td,
.data-table th { overflow-wrap: normal; word-break: normal; hyphens: none; }

/* 2. implicit, o celula sta pe un rand; tabelul se lateste, nu se strange */
.data-table th,
.data-table td { white-space: nowrap; vertical-align: middle; }

/* 3. exceptiile care AU voie sa curga pe mai multe randuri */
.data-table td.wrap,
.data-table .col-file,
.data-table .user-groups,
.data-table .activity-meta,
.data-table .ledger-desc,
.data-table .mfs-note,
.data-table .plan-benefits,
.data-table td ul,
.data-table td p,
.mfs-kv td { white-space: normal; overflow-wrap: break-word; word-break: break-word; }

/* 4. numele de fisier: o singura linie cu taiere eleganta, nu 12 randuri */
.data-table .col-file { max-width: 26rem; }
.data-table .job-file,
.data-table .mono.job-file { display: inline-block; max-width: 22rem; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }

/* 5. cardul care contine un tabel devine scrollabil orizontal.
      Mai bine o bara de scroll decat coloane strivite. */
.card:has(> .data-table),
.card:has(> table.data-table),
.card:has(> form + .data-table),
.report-table-wrap,
.panel-grid .card { overflow-x: auto; }

/* BARA DE DERULARE TREBUIE SA SE VADA 2026-08-21 (raportat de Xprime:
   „nu am scroll orizontal, nu pot sa vad tot textul").
   `overflow-x: auto` exista de mult, dar pe Windows si pe Mac bara e ASCUNSA
   pana incepi sa derulezi — deci pentru cine se uita la pagina pur si simplu
   nu exista. Doua semne care se vad fara sa atingi nimic: bara subtire,
   colorata, mereu prezenta; si o umbra pe marginea din dreapta care spune ca
   mai e continut acolo. */
.card:has(> .data-table),
.card:has(> table.data-table),
.card:has(> form + .data-table),
.report-table-wrap {
  /* `background-image` NU se atinge aici: `.card` isi deseneaza suprafata tot
     cu un degradeu, si l-am fi inlocuit. Bara subtire, colorata, mereu vizibila
     e de ajuns ca semn. */
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
.card:has(> .data-table)::-webkit-scrollbar,
.card:has(> table.data-table)::-webkit-scrollbar,
.report-table-wrap::-webkit-scrollbar { height: 9px; }
.card:has(> .data-table)::-webkit-scrollbar-thumb,
.card:has(> table.data-table)::-webkit-scrollbar-thumb,
.report-table-wrap::-webkit-scrollbar-thumb {
  background: var(--line-strong); border-radius: 999px;
}
.card:has(> .data-table)::-webkit-scrollbar-track,
.card:has(> table.data-table)::-webkit-scrollbar-track,
.report-table-wrap::-webkit-scrollbar-track { background: transparent; }

/* 6. tabelele "cheie / valoare" (2 coloane) nu au nevoie de scroll si trebuie
      sa curga normal */
.mfs-kv, .mfs-hours { min-width: 0; }
.mfs-kv td, .mfs-hours td { white-space: normal; }
.mfs-kv td.num, .mfs-hours td.mono { white-space: nowrap; }

/* 7. emailurile lungi din Users / Orders: o linie, cu taiere */
.data-table .email-cell,
.data-table td > a[href^="mailto:"],
.data-table .user-email { display: inline-block; max-width: 16rem; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }

/* 8. badge-ul Auto/Manual sta langa nume, nu sub el */
.job-kind { white-space: nowrap; }

/* 9. pe ecrane mici pastram scroll-ul pe tabel (regula veche ramane valabila) */
@media (max-width: 640px) {
  .data-table { display: block; overflow-x: auto; }
  .mfs-summary-cols, .admin-two-col { grid-template-columns: 1fr; }
}

/* 10. sidebar-ul si continutul: pe latimi medii, grila de admin nu mai strange
       zona de continut sub minimul lizibil */
.admin-shell { min-width: 0; }
/* `clip`, NU `hidden` (12.09.2026) — si asta e chiar cauza pentru care bara de
   derulare orizontala „nu statea lipita" nicaieri, nici sus, nici jos.
   `overflow-x: hidden` face din element un CONTAINER DE DERULARE (pe cealalta
   axa `overflow-y` devine `auto`), iar un element lipit se raporteaza la cel mai
   apropiat container de derulare — aici `.admin-main`, care nu deruleaza
   niciodata, fiindca creste odata cu continutul. Deci bara n-avea fata de ce sa
   se lipeasca si se plimba cu pagina. `clip` taie la fel ce iese in lateral, dar
   NU creeaza container de derulare: lipirea se raporteaza din nou la fereastra,
   asa cum trebuie. Acelasi invelis e folosit si de panoul clientului. */
.admin-main { min-width: 0; overflow-x: clip; }
.admin-main > * { min-width: 0; }

/* ── Plans: randul de perioada — SINGURA definitie (2026-08-02, curatat 2026-08-21)
   Grila pe 3 coloane (eticheta | pret | butoane) colapsa coloana etichetei cand
   in a treia stau doua butoane, iar pretul (nowrap, aliniat dreapta) se scria
   PESTE eticheta. Deci: flex cu wrap — eticheta si pretul pe un rand, cele doua
   butoane de plata coboara dedesubt, aliniate la dreapta.

   LINKUL VIZITATORULUI („Log in") NU E UN BUTON DE PLATA si nu se poarta ca ele
   (raportat de Xprime, cu captura de pe telefon). Avea `flex: 1 1 100%`, deci
   se intindea pe toata latimea cardului cu textul impins in dreapta — trei pastile
   goale, una sub alta, in care scria marunt intr-un colt. Acum are latimea
   textului si sta pe acelasi rand cu pretul; `margin-left: auto` il tine la
   dreapta si atunci cand nu incape si coboara singur. */
.plan-periods { display: flex; flex-direction: column; gap: .7rem;
  margin-top: auto; border-top: 1px solid rgba(128,128,128,.2); padding-top: .75rem; }
.plan-period-row { display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: .35rem .6rem; }
.plan-period-label { flex: 1 1 auto; min-width: 5rem; font-weight: 600; }
.plan-price { flex: 0 0 auto; text-align: right; white-space: nowrap; }
.plan-buy { flex: 1 1 100%; display: flex; gap: .4rem; justify-content: flex-end; flex-wrap: wrap; }
.plan-period-row > a.btn-small { flex: 0 0 auto; margin-left: auto; }

/* Sub 380px eticheta si pretul raman fata in fata, iar butoanele se aliniaza la
   stanga — pe o latime atat de mica, alinierea la dreapta lasa un gol care se
   citeste ca o greseala. Media query-ul sta AICI, imediat dupa regulile pe care
   le corecteaza, nu la trei mii de linii distanta unde ordinea din fisier decide
   cine castiga. */
@media (max-width: 380px) {
  .plan-period-row { align-items: center; }
  .plan-price { text-align: left; }
  .plan-buy { justify-content: flex-start; }
  .plan-period-row > a.btn-small { margin-left: 0; }
}

/* ── Grafic de gain (pasul 5): putere + cuplu, doua scale ──────────────────── */
.mfs-gain h3 { margin: 0 0 .6rem; font-size: 1rem; }
.mfs-gain .mfs-legend, .mfs-gain .mfs-estimate { max-width: var(--gain-w); }
/* Graficul si tabelul de sub el sunt UN bloc, deci au o singura latime, scrisa
   o data. Pana acum graficul se intindea cat cardul, iar tabelul ramanea la
   34rem — doua latimi diferite una sub alta, pe acelasi subiect. */
/* Latimea se declara si pe CARD, nu doar pe `.mfs-gain`: pe pagina de
   descarcare formularul de PDF e FRATE cu graficul, nu copil, deci o variabila
   pusa numai pe grafic nu ajunge la el — si formularul s-ar intinde cat cardul
   in timp ce graficul de sub el ramane la 680px. Exact cele doua latimi una sub
   alta pe care le-am scos in septembrie. */
.gain-card, .mfs-gain { --gain-w: 680px; }
.mfs-chart { width: 100%; height: auto; max-width: var(--gain-w); display: block; }
/* FORMA, dupa fisa de referinta (22.09.2026, cerinta Xprime): grila pe amandoua
   directiile, chenar inchis, si titlurile de axa scrise pe verticala, fiecare in
   culoarea curbei lui. Fara cifre scrise pe curbe — varfurile stau in tabelul de
   dedesubt, unde se pot si citi, si copia. */
.mfs-chart .grid { stroke: var(--line); stroke-width: 1; opacity: .55; }
.mfs-chart .frame { stroke: var(--line); stroke-width: 1; }
.mfs-chart .tick { fill: var(--ink-soft); font-size: 10px; font-family: inherit; }
.mfs-chart .axis-label { fill: var(--ink-soft); font-size: 10px; font-weight: 700; letter-spacing: .05em; }
.mfs-chart .axis-label.hp { fill: var(--accent-btn); }
.mfs-chart .axis-label.nm { fill: var(--warn); }
/* CIFRELE DE PE GRAFIC, PE CARD INGUST. Desenul e vectorial si se intinde cat
   ii da cardul: de la ~680px pe un ecran lat la ~260px pe telefon. Literele
   scrise in unitatile desenului se micsoreaza odata cu el, si la 260px cele de
   10 unitati ies sub 5 pixeli reali — adica nu se mai citesc, iar reperele de
   turatie se calca in picioare.
   Intrebarea e cat de lat e CARDUL, nu fereastra (pe ecranul de descarcare
   cardul e jumatate de pagina), deci `@container`, nu `@media`. Unde nu e
   sustinut, blocul e ignorat si graficul arata ca inainte — nimic nu se strica. */
.mfs-gain { container-type: inline-size; }
@container (max-width: 430px) {
  .mfs-chart .tick { font-size: 18px; }
  .mfs-chart .axis-label { font-size: 18px; }
  .mfs-chart .tick.alt { display: none; }
}
.mfs-chart .ln { stroke-linejoin: round; stroke-linecap: round; }
.mfs-chart .ln.hp { stroke-width: 2.4; }
.mfs-chart .ln.nm { stroke-width: 2; opacity: .85; }
.mfs-chart .ln.hp.stock  { stroke: var(--chart-stock); stroke-dasharray: 5 4; }
.mfs-chart .ln.hp.tuned  { stroke: var(--accent-btn); }
.mfs-chart .ln.hp.stage2 { stroke: var(--violet); }
.mfs-chart .ln.nm.stock  { stroke: var(--chart-stock-2); stroke-dasharray: 5 4; }
.mfs-chart .ln.nm.tuned  { stroke: var(--warn); }
.mfs-chart .ln.nm.stage2 { stroke: var(--chart-alt); stroke-dasharray: 2 3; }

.mfs-legend { list-style: none; margin: .6rem 0 .9rem; padding: 0;
  display: flex; flex-wrap: wrap; gap: .35rem 1.1rem; font-size: .82rem; color: var(--ink-soft); }
.mfs-legend li { display: inline-flex; align-items: center; gap: .4rem; }
.mfs-legend .key { width: 1.6rem; height: 0; border-top-width: 3px; border-top-style: solid; border-radius: 2px; }
.mfs-legend .key.hp.tuned  { border-color: var(--accent-btn); }
.mfs-legend .key.hp.stock  { border-color: var(--chart-stock); border-top-style: dashed; }
.mfs-legend .key.nm.tuned  { border-color: var(--warn); }
.mfs-legend .key.nm.stock  { border-color: var(--chart-stock-2); border-top-style: dashed; }
.mfs-legend .key.hp.stage2 { border-color: var(--violet); }

.mfs-gain-table { width: 100%; max-width: var(--gain-w); }
.mfs-gain-table td.up { color: var(--ok); font-weight: 600; }
.mfs-gain-table td.strong { font-weight: 700; }
.mfs-gain-stage2 td { color: var(--violet); }

/* ── Catalog: adaugarea unui vehicul de mana ──────────────────────────────── */
/* Pliata, ca sa nu impinga lista de pozitii sub pliu: e o unealta pentru cazuri
   punctuale. Marcajul implicit al browserului e inlocuit, ca la `msg-user-toggle`. */
.mfs-add > .mfs-add-toggle {
  cursor: pointer; list-style: none; padding: .2rem 0;
  font-size: 1rem; font-weight: 600; color: var(--accent-btn);
}
.mfs-add > .mfs-add-toggle::-webkit-details-marker { display: none; }
.mfs-add > .mfs-add-toggle::before { content: "+\00a0"; }
.mfs-add[open] > .mfs-add-toggle { color: var(--ink); }
.mfs-add[open] > .mfs-add-toggle::before { content: "\2212\00a0"; }
.mfs-add .mfs-grid-2 { margin-top: .9rem; }

/* ── Pagina publica „Power Gains" 2026-09-24 ──────────────────────────────── */
/* Pagina informativa: marca -> model -> motor, apoi acelasi grafic si acelasi
   tabel ca pe ecranul de descarcare. Fara fisa Dyno.
   Selectoarele stau pe un rand cat incap; pe ecran ingust se aseaza una sub
   alta si raman TOATE vizibile — nicio bara derulabila care ascunde ce urmeaza. */
.gains-lead { max-width: 60ch; }
.gains-pick-row {
  display: flex; flex-wrap: wrap; gap: .9rem; align-items: end;
}
.gains-pick-row > label { display: grid; gap: .3rem; flex: 1 1 15rem; min-width: 0; }
.gains-pick-row > label > span { color: var(--ink-soft); font-size: .9rem; }
.gains-pick-row select { width: 100%; }
/* Butonul e pentru cand nu merge JavaScript; cu JavaScript se ascunde singur.
   `hidden` are nevoie de ajutor: `display:flex` de mai sus l-ar tine vizibil. */
.gains-pick-row .gains-go { flex: 0 0 auto; }
.gains-pick-row .gains-go[hidden] { display: none; }
.gains-count { margin: .9rem 0 0; }
.gains-result { margin-top: 1rem; }
.gains-veh { margin: 0; font-size: 1.15rem; }
.gains-veh-sub { margin: .2rem 0 1rem; color: var(--ink-soft); }
.gains-empty { margin-top: 1rem; }
.gains-note { max-width: 70ch; margin-top: 1rem; }
/* Desenul e mai lat aici decat pe ecranul de descarcare: acolo imparte randul
   cu cardul de fisier, aici are pagina lui. 900px, nu toata latimea — peste
   atat, curbele se intind si citirea nu castiga nimic. */
.gains-result, .gains-result .mfs-gain { --gain-w: 900px; }
@media (max-width: 560px) { .gains-pick-row > label { flex: 1 1 100%; } }

/* ── Ecranul de descarcare: fisierul si castigul, unul langa altul ────────── */
/* Cardul de descarcare are note de montaj, valabilitate, cod de exemplar si
   raportare — pe un laptop ocupa tot ce se vede, iar graficul asezat sub el
   incepea pe la 900px in jos. Omul lua fisierul si pleca fara sa-l vada.
   Doua coloane, deci; pe ecran ingust se aseaza una sub alta, in aceeasi
   ordine (fisierul primul — pentru el a venit). */
.paid-split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1rem; align-items: start; margin-bottom: 1rem;
}
.paid-split.is-single { grid-template-columns: minmax(0, 1fr); }
/* `min-width: 0` ca un card sa nu poata umfla coloana. Marginea de sus a celui
   de-al doilea card o anuleaza regula generala de aliniere din grile (cauta
   „ALINIEREA CARDURILOR IN GRILE"), unde `.paid-split` e in lista. */
.paid-split > .card { min-width: 0; }
/* ASEZARE EXPLICITA, nu curgere automata (22.09.2026, cerinta Xprime: „File
   identified in partea stanga sub chenarul plata confirmata"). Sunt trei
   carduri, iar curgerea automata a grilei le-ar pune pe primul rand: plata |
   masina, si graficul singur pe randul doi. Deci: coloana 1 tine plata si
   masina, una sub alta; graficul tine coloana 2 pe amandoua randurile.
   Distantele dintre ele sunt ale grilei (`gap`), nu margini de card — de asta
   marginile raman anulate de regula generala de aliniere. */
.paid-split > .ready-card   { grid-column: 1; grid-row: 1; }
.paid-split > .vehicle-card { grid-column: 1; grid-row: 2; margin: 0; }
.paid-split > .gain-card    { grid-column: 2; grid-row: 1 / span 2; }
/* Fara grafic ramane o coloana si doua randuri, in ordinea din HTML. */
.paid-split.is-single > .card { grid-column: 1; grid-row: auto; }
/* Pe ecran ingust, un singur sir — si GRAFICUL TRECE INAINTEA MASINII. Tabelul
   de identificare are noua randuri; lasat intre fisier si grafic, ar fi impins
   graficul cu vreo 500px mai jos pe telefon, adica fix ce s-a reparat pe
   desktop. Fisierul ramane primul: pentru el a venit omul. */
@media (max-width: 1080px) {
  .paid-split { grid-template-columns: minmax(0, 1fr); }
  .paid-split > .card         { grid-column: 1; grid-row: auto; }
  .paid-split > .ready-card   { order: 1; }
  .paid-split > .gain-card    { order: 2; }
  .paid-split > .vehicle-card { order: 3; }
}

/* Blocul care spune CE face butonul. Fara el, formularul de sub grafic arata a
   setare de grafic, nu a „iti scot o fisa pe care o dai clientului tau". */
.dyno-cta {
  margin-top: 1.2rem; padding-top: 1.1rem; border-top: 1px solid var(--line);
}
.dyno-cta-title { margin: 0 0 .25rem; font-size: 1rem; }
.dyno-cta-what { margin: 0 0 .9rem; color: var(--ink-soft); font-size: .9rem; max-width: 52ch; }
.dyno-cta .gain-sheet { margin: 0; padding: 0; border-bottom: 0; }

/* ── Foaia de putere in PDF: campurile de deasupra graficului ─────────────── */
/* Stau SUS in card, inaintea graficului: omul scrie intai ce vrea pe foaie si
   abia apoi apasa. Un buton despartit de campurile lui e un buton apasat prea
   devreme. Latimea e aceeasi cu a graficului, ca blocul sa fie unul singur. */
.gain-sheet {
  max-width: var(--gain-w); margin: 0 0 1.2rem;
  padding: 0 0 1.1rem; border-bottom: 1px solid var(--line);
}
.gain-sheet-fields { display: flex; flex-wrap: wrap; gap: .8rem; }
.gain-sheet-fields > label { flex: 1 1 18rem; margin: 0; }
.gain-sheet-fields > label.gain-sheet-plate { flex: 0 1 12rem; }
.gain-sheet-fields input { width: 100%; }
.gain-sheet .opt { margin: 0; }
.gain-sheet .hint { margin: 0; }
/* Bifa si butonul pe acelasi rand: pe un laptop de 800px inaltime, butonul pus
   sub indiciu cadea sub pliu — exact defectul pentru care s-au facut coloanele. */
.gain-sheet-go {
  display: flex; align-items: center; justify-content: space-between;
  gap: .9rem 1.2rem; flex-wrap: wrap; margin-top: .9rem;
}
.gain-sheet-btn { margin: 0; }
.gain-sheet-hint { margin-top: .55rem !important; }

/* Sigla din profil: previzualizarea sta pe un fundal in carouri discrete, ca
   sa se vada si o sigla alba pe fond transparent — altfel omul crede ca s-a
   pierdut incarcarea. */
.logo-card .logo-preview {
  margin: .2rem 0 1rem; padding: .8rem; border: 1px solid var(--line);
  border-radius: 8px; background: #fff; display: flex; justify-content: center;
}
.logo-card .logo-preview img { max-width: 100%; max-height: 90px; display: block; }
.logo-card .logo-remove { margin-top: .7rem; }
/* Indiciul cu formatele sta SUB campul de fisier, nu langa el: butonul „Choose
   file" al browserului nu are latime fixa si nu si-o spune, iar pe un rand
   comun textul se rupe altfel in fiecare limba. */
.logo-card label .hint { display: block; margin-top: .35rem; }

/* ── Admin: taburi si formulare de pret pentru modulul manual ─────────────── */
.admin-tabs { display: flex; gap: .3rem; flex-wrap: wrap; margin: 0 0 1.1rem; }
.admin-tab { padding: .45rem .9rem; border-radius: 999px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink-soft); text-decoration: none; font-size: .88rem; }
.admin-tab:hover { border-color: var(--accent); color: var(--ink); }
.admin-tab.is-active { background: var(--accent-btn); border-color: var(--accent-btn); color: var(--accent-ink); font-weight: 600; }
.mfs-price-head { display: flex; gap: 1.2rem; align-items: flex-end; flex-wrap: wrap; margin-bottom: 1rem; }
.price-input { width: 6.5rem; text-align: right; font-variant-numeric: tabular-nums; }
.desc-input { width: 100%; min-width: 14rem; }
.data-table tr.is-off td { opacity: .5; }
.btn-danger { color: var(--error); border-color: var(--error); }
.pager { display: flex; gap: .8rem; align-items: center; justify-content: center; margin-top: .9rem; }
.mfs-import-preview { border-left: 3px solid var(--accent); }
.admin-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.admin-card-head h2 { margin: 0 0 .6rem; }

/* Matricea de preturi: pretul e coloana care conteaza — nu are voie sa cada in
   afara ecranului. Numele curge pe doua randuri, codul dispare pe ecrane mici. */
.mfs-price-table { min-width: 0; width: 100%; }
.mfs-price-table td.wrap { white-space: normal; max-width: 22rem; }
.mfs-price-table .col-code { font-size: .78rem; }
@media (max-width: 1300px) { .mfs-price-table .col-code { display: none; } }

/* Pe telefon, editorul de catalog devine ilizibil daca il inghesuim: pastram
   scroll orizontal si campuri de latime minima. */
@media (max-width: 560px) {
  .data-table input[type=number], .data-table input[type=text] { min-width: 4.5rem; }
  .admin-tabs { overflow-x: auto; flex-wrap: nowrap; padding-bottom: .3rem; }
  .admin-tab { white-space: nowrap; }
}
/* O celula care are voie sa curga pe mai multe randuri nu are voie sa se
   stranga sub o latime citibila — altfel textul cade pe verticala. */
.data-table td.wrap, .data-table th.wrap { min-width: 9rem; }

/* Avertisment "baza de date e in urma codului" — apare doar cand o migrare
   nu a fost rulata pe server. */
.mfs-migration-notice ul { margin: .5rem 0; padding-left: 1.2rem; }
.mfs-migration-notice pre { margin: .5rem 0 0; padding: .6rem .8rem; border-radius: 8px;
  background: rgba(0,0,0,.06); font-size: .82rem; overflow-x: auto; white-space: pre; }
.mfs-migration-notice code { font-size: .85rem; }

/* Iesirea catre procesarea manuala din ecranele fara iesire ale fluxului automat */
.manual-fallback { border-left: 3px solid var(--accent); }
.manual-fallback h2 { margin-top: 0; }
/* „Raporteaza fisierul" (12.10.2026): card simplu pe fundaturi, fara tichet. */
.flag-file h2 { margin-top: 0; }
.flag-file .custom-form { margin-top: .6rem; }
.flag-file .manual-fallback-actions { margin-top: .6rem; }
.manual-fallback-actions { display: flex; gap: .6rem; flex-wrap: wrap; margin-top: 1rem; }
/* In cardul de asteptare totul e centrat — butoanele lipite la stanga ar arata
   ca si cum ar apartine altei sectiuni. */
.wait-card .manual-fallback-actions { justify-content: center; }

/* ==========================================================================
   TICHETE SERIOASE 2026-08-03 (cerinta Xprime: "sistem serios de ticketing,
   atat pe automat cat si pe manual processing").

   Regula de baza a paginii: un tichet trebuie citit dintr-o privire — de unde
   vine, in ce stare e, cat de urgent e. De aceea etichetele sunt mici, cu
   contrast real, si nu se rup niciodata pe doua randuri.
   ========================================================================== */

/* --- etichete: sursa / stare / prioritate ------------------------------- */
.tk-badge {
  display: inline-block;
  padding: 0.16rem 0.55rem;
  border-radius: 999px;
  font-size: 0.74rem;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.02em;
  white-space: nowrap;
  vertical-align: middle;
}
.tk-badge + .tk-badge { margin-left: 0.3rem; }

/* sursa — de unde a venit tichetul */
.tk-src--auto    { background: var(--accent-soft); color: var(--accent-dark); }
.tk-src--manual  { background: var(--violet-bg); color: var(--violet-ink); }
.tk-src--general { background: var(--neutral-bg); color: var(--ink-soft); }
/* Raportare de fisier: rosu, ca sa se vada din lista fara sa citesti. Nu e
   „urgent" in sens de prioritate — e altfel de treaba: cere deschiderea
   ecranului de trasare inainte de orice raspuns. */
.tk-src--file_report { background: var(--error-bg); color: var(--error); font-weight: 600; }

/* stare */
.tk-st--open           { background: var(--accent-soft); color: var(--accent-dark); }
.tk-st--answered       { background: var(--ok-bg); color: var(--ok); }
.tk-st--waiting_client { background: var(--warn-bg); color: var(--warn-ink); }
.tk-st--offer_pending  { background: var(--warn-bg); color: var(--warn-ink); }
.tk-st--closed         { background: var(--neutral-bg); color: var(--ink-soft); }

/* prioritate — normal nu se afiseaza deloc, ca sa nu faca zgomot */
.tk-pr--low    { background: var(--neutral-bg); color: var(--ink-soft); }
.tk-pr--normal { background: var(--neutral-bg); color: var(--ink-soft); }
.tk-pr--high   { background: var(--warn-bg); color: var(--warn-ink); }
.tk-pr--urgent { background: var(--error-bg); color: var(--error); }

.tk-internal {
  background: var(--warn-bg);
  color: var(--warn-ink);
  text-transform: none;
  letter-spacing: 0;
}

.tk-badges { white-space: nowrap; }

/* --- lista de tichete a clientului ------------------------------------- */
.tk-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.9rem;
}
.tk-filter {
  display: inline-block;
  padding: 0.32rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  font-size: 0.88rem;
  text-decoration: none;
  color: var(--ink-soft);
}
.tk-filter:hover { border-color: var(--accent-btn); color: var(--accent-btn); }
.tk-filter.is-active {
  background: var(--accent-btn);
  border-color: var(--accent-btn);
  color: var(--accent-ink);
  font-weight: 600;
}
.tk-new-link { margin-left: auto; text-decoration: none; }

.tk-table th, .tk-table td { vertical-align: middle; }
.tk-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }

/* --- firul de conversatie ---------------------------------------------- */
.tk-thread { margin-bottom: 1.1rem; }
.msg-who {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 0.45rem;
  font-size: 0.9rem;
}
.msg-body {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  line-height: 1.65;
}
.msg-user  { border-left: 5px solid var(--line); }
.msg-admin { border-left: 5px solid var(--accent-btn); }

/* nota interna: galben, evident, imposibil de confundat cu un raspuns */
.msg-internal {
  border-left: 5px solid var(--warn);
  background: var(--warn-bg);
}

.tk-files { list-style: none; margin: 0.7rem 0 0; padding: 0; }
.tk-files li {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.28rem 0;
  border-top: 1px solid var(--line);
}
.tk-files li:first-child { border-top: 0; }
.tk-files a {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 32rem;
}

.tk-reply-actions { margin-top: 0.5rem; }
.tk-close-form {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.6rem;
  margin: 0.2rem 0 1.4rem;
}

.tk-closed p { margin-top: 0; }

/* --- evaluare: stele in ordine inversa, colorate la hover --------------- */
.tk-rate .tk-stars {
  display: inline-flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  gap: 0.15rem;
  margin: 0.2rem 0 0.9rem;
}
.tk-rate .tk-stars input { position: absolute; opacity: 0; width: 0; height: 0; }
.tk-rate .tk-stars label {
  cursor: pointer;
  font-size: 1.9rem;
  line-height: 1;
  /* STEAUA NEAPRINSA TREBUIE SA SE VADA CA STEA, nu ca o pata.
     `--line` disparea de tot (1.32:1); `--line-strong` a ramas la 1.95:1 pe
     fundalul cardului — sub pragul de 3:1 pentru un element de interfata, deci
     pe un ecran mai putin contrastant omul nu vede ce are de apasat. Culoarea
     de aici e aceeasi familie, doar mai apasata: 3.63:1, si ramane vizibil mai
     stinsa decat steaua aprinsa, ca sa se citeasca in continuare nota. */
  color: rgba(159, 190, 207, .55);
  transition: color 0.12s ease;
  margin: 0;
}
.tk-rate .tk-stars label:hover,
.tk-rate .tk-stars label:hover ~ label,
.tk-rate .tk-stars input:checked ~ label { color: var(--warn-bright); }
.tk-rate .tk-stars input:focus-visible + label { outline: 2px solid var(--accent-btn); outline-offset: 2px; }
.tk-stars-static { font-size: 1.5rem; color: var(--warn-bright); letter-spacing: 0.1rem; margin: 0.2rem 0; }

/* --- consola de suport (admin) ----------------------------------------- */
.tk-counters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 0 1rem;
}
.tk-counter {
  flex: 1 1 8.5rem;
  min-width: 8.5rem;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--panel);
  text-decoration: none;
  color: inherit;
}
.tk-counter:hover { border-color: var(--accent-btn); }
.tk-counter-n {
  display: block;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.15;
  color: var(--accent-btn);
}
.tk-counter-l {
  display: block;
  font-size: 0.8rem;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tk-counter--hot .tk-counter-n { color: var(--error); }

.tk-filter-bar { flex-wrap: wrap; gap: 0.4rem; }
.tk-filter-bar input[type="search"] { min-width: 15rem; }

.tk-row--urgent td:first-child { box-shadow: inset 3px 0 0 var(--error); }
.tk-row--high   td:first-child { box-shadow: inset 3px 0 0 var(--warn); }

.tk-admin-head { padding-bottom: 0.9rem; }
.tk-admin-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.8rem;
}
.tk-ref { font-weight: 700; font-size: 1.05rem; }

.tk-admin-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.3rem 1rem;
  margin: 0 0 0.9rem;
}
.tk-admin-facts dt {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  white-space: nowrap;
  align-self: baseline;
}
.tk-admin-facts dd { margin: 0; overflow-wrap: break-word; }

.tk-admin-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.6rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--line);
}
.tk-admin-controls label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin: 0;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.tk-admin-controls select { min-width: 10rem; }

.tk-reply-flags {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0.6rem 0 0.9rem;
}
/* cand e bifata nota interna, tot formularul se coloreaza — greu de gresit */
.tk-reply.is-internal { border-left: 5px solid var(--warn); background: var(--warn-bg); }

@media (max-width: 640px) {
  .tk-admin-facts { grid-template-columns: 1fr; gap: 0.1rem 0; }
  .tk-admin-facts dd { margin-bottom: 0.5rem; }
  .tk-admin-controls label { flex: 1 1 100%; }
  .tk-admin-controls select { width: 100%; min-width: 0; }
  .tk-new-link { margin-left: 0; }
  .tk-files a { max-width: 100%; }
}

/* Coada de suport: subiectul si e-mailul au nevoie de mai mult loc decat
   min-width-ul generic de 9rem, altfel se rup in coloane de 3 cuvinte. */
.tk-table td.wrap, .tk-table th.wrap { min-width: 10rem; }
.tk-table td:nth-child(3) { min-width: 15rem; }
.tk-table td.mono, .tk-table th:first-child { white-space: nowrap; }
@media (max-width: 900px) {
  .tk-table td.wrap, .tk-table th.wrap { min-width: 9rem; }
  .tk-table td:nth-child(3) { min-width: 12rem; }
}

/* `hidden` trebuie sa bata orice display: */
/* `.opt { display:flex }` invingea atributul [hidden], asa ca declaratia de
   proprietate ramanea pe ecran chiar si cand nu era ales niciun fisier — o
   bifa fara obiect, exact genul de detaliu care face pagina sa para neterminata. */
[hidden] { display: none !important; }

/* col-file: numele de fisier nu se mai scrie pe verticala */
/* `.col-file` mostenea `overflow-wrap: anywhere` fara nicio latime minima, asa
   ca intr-o coloana ingusta "test4.bin" se rupea litera cu litera pe verticala
   — acelasi defect reclamat pe /admin/catalog, ramas doar pe coloana asta.
   Solutia e aceeasi ca la restul tabelelor: o singura linie, taiata elegant,
   cu o latime minima sub care coloana nu mai coboara. */
.data-table .col-file {
  min-width: 10rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  overflow-wrap: normal;
  word-break: normal;
}
.data-table th.col-file { min-width: 10rem; white-space: nowrap; }
@media (max-width: 640px) { .data-table .col-file { min-width: 8rem; } }

/* DIAGNOSTIC 2026-08-03 (cerinta Xprime): pagina care spune de ce s-a
   oprit coada. Concluzia sus, cu contrast real; detaliile dedesubt, citibile
   pe verticala fara sa fie un perete de text. */
.diag-verdict { border-left: 5px solid var(--line); }
.diag-verdict h2 { margin-top: 0; }
.diag-verdict--ok  { border-left-color: var(--ok); background: var(--ok-bg); }
.diag-verdict--bad { border-left-color: var(--error); background: var(--error-bg); }
.diag-verdict-list { margin: .6rem 0 0; padding-left: 1.3rem; }
.diag-verdict-list li { margin-bottom: .5rem; line-height: 1.55; }

.diag-actions h2 { margin-top: 0; }
.diag-actions code { white-space: nowrap; }

.diag-section h2 { margin-top: 0; font-size: 1rem; letter-spacing: .02em; }
.diag-list { list-style: none; margin: 0; padding: 0; }
.diag-item {
  display: flex;
  gap: .6rem;
  align-items: baseline;
  padding: .32rem 0;
  border-top: 1px solid var(--line);
  line-height: 1.55;
}
.diag-item:first-child { border-top: 0; }
.diag-icon {
  flex: 0 0 1.1rem;
  text-align: center;
  font-weight: 700;
  font-size: .82rem;
}
/* Textul vine din diagnostic aliniat cu spatii — il pastram monospace ca sa
   ramana in coloane, dar lasam randurile lungi sa curga normal. */
.diag-text { white-space: pre-wrap; overflow-wrap: anywhere; }
.diag-item--ok   .diag-icon { color: var(--ok); }
.diag-item--warn .diag-icon { color: var(--warn-ink); }
.diag-item--bad  .diag-icon { color: var(--error); }
.diag-item--info .diag-icon { color: var(--ink-soft); }
.diag-item--bad  .diag-text { font-weight: 600; }
.diag-item--info .diag-text { color: var(--ink-soft); font-size: .9rem; }

/* SIDEBAR ADMIN 2026-08-03 — meniul a crescut peste inaltimea ecranului
   (ultimul item, Storage, cadea sub linia de jos). Acum lista de link-uri e
   singura care se deruleaza; sigla si zona de logout raman fixate, ca sa nu
   trebuiasca sa derulezi ca sa gasesti butonul de iesire. */
.admin-side { overflow: hidden; }
.admin-brand { flex: 0 0 auto; }
.admin-nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: .2rem; }
.admin-side-foot { flex: 0 0 auto; margin-top: .8rem; }
/* bara de derulare discreta, nu o dunga groasa peste meniu */
.admin-nav::-webkit-scrollbar { width: 6px; }
.admin-nav::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }
.admin-nav { scrollbar-width: thin; }

.diag-buttons { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; }
.diag-buttons .btn-primary, .diag-buttons .btn-secondary { margin-top: .4rem; }

/* ============================================================================
   ORDERS + ORDER DETAIL 2026-08-04 (cerinta Xprime)
   Coloanele ECU / Operation din lista de comenzi si dosarul unei comenzi:
   sumar, cronometre, cronologie in cuvinte, date brute pliate.
   ========================================================================== */

/* --- coloana ECU ---------------------------------------------------------- */
.col-ecu { white-space: nowrap; }
.ecu-chip {
  display: inline-block;
  padding: .12rem .5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--neutral-bg);
  color: var(--ink);
  font-weight: 600;
  font-size: .82rem;
  letter-spacing: .01em;
}
.ecu-maker { display: block; font-size: .72rem; color: var(--ink-soft); margin-top: .12rem; }

/* --- coloana Operation ---------------------------------------------------- */
.col-op { white-space: normal; min-width: 9rem; }
.op-list { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .25rem; }
.op-chip {
  display: inline-block;
  padding: .12rem .5rem;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-dark);
  font-size: .78rem;
  font-weight: 600;
  white-space: nowrap;
}
.op-chip.is-big { font-size: .95rem; padding: .28rem .8rem; }
.op-plus { color: var(--ink-soft); font-size: .78rem; }
/* fisier livrat: aceleasi etichete, dar cu greutatea unui fapt implinit */
.op-list.is-delivered .op-chip { background: var(--ok-bg); color: var(--ok); }
.cell-empty { color: var(--ink-soft); opacity: .6; }
.user-ref { display: block; font-size: .72rem; color: var(--ink-soft); }
.col-user { min-width: 11rem; }

/* --- pager (Orders, Payments) --------------------------------------------- */
.pager {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .8rem; margin-top: .9rem;
}
.pager-links { display: flex; gap: 1rem; }
.pager-links a { font-weight: 600; }

/* --- antetul comenzii ----------------------------------------------------- */
.order-head { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem; margin-bottom: .3rem; }
.order-head h1 { margin: 0; }
.order-head-type { color: var(--ink-soft); font-size: .82rem; }

/* --- cele trei casete de sumar -------------------------------------------- */
.order-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1rem;
  margin: 1rem 0;
  align-items: start;
}
.order-card { margin: 0; min-width: 0; }
.order-card-title {
  margin: 0 0 .6rem; font-size: .78rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-soft); font-weight: 600;
}
.order-lead { margin: 0 0 .4rem; font-size: 1.05rem; font-weight: 600; }
.order-ecu { margin: 0 0 .7rem; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.order-ecu-full { color: var(--ink-soft); font-size: .85rem; min-width: 0; overflow-wrap: anywhere; }
.order-ops { margin: 0 0 .8rem; display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }
.order-filename {
  margin: 0 0 .7rem; font-size: .9rem; line-height: 1.45;
  overflow-wrap: anywhere;   /* numele de fisier sunt lungi si fara spatii */
}
.order-error { color: var(--error); }

/* Cele doua fisiere ale comenzii, descarcabile (2026-09-14, cerinta Xprime).
   Stau sub numele fisierului, in cardul care vorbeste despre el. Se rup pe doua
   randuri pe ecran ingust, nu se strang unul in altul. */
.order-files { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0 0 .8rem; }
.order-files-gone { margin: 0 0 .8rem; }

/* „Am rezolvat problema" (2026-09-14, cerinta Xprime). Nu e un card oarecare:
   apasarea lui trimite o promisiune unui client. Banda de sus il deosebeste de
   restul dosarului, fara sa-l faca sa arate a eroare — eroarea e deja anuntata
   de insigna comenzii. */
.reopen-box { border-top: 3px solid var(--accent-btn); }
.reopen-lead { margin: 0 0 .6rem; font-size: .95rem; line-height: 1.5; }
.reopen-note { margin: 0 0 1rem; }
/* Mesajul liber catre client. Casuta mosteneste stilul de camp al panoului
   (latime, chenar, fundal) — aici se regleaza doar ce e specific: se trage
   numai pe verticala, fiindca un textarea tras lateral iese din card si rupe
   coloana din dreapta pe ecrane inguste. */
.reopen-msg { resize: vertical; margin-bottom: .9rem; }
/* Cele doua actiuni, una langa alta pe desktop si una sub alta pe telefon.
   Fiecare isi poarta explicatia sub buton: cele doua fac lucruri diferite
   (instiintare vs. discutie), si diferenta trebuie citita INAINTE de apasare,
   nu dedusa din ce a primit clientul. */
.reopen-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem 1.4rem; }
@media (max-width: 720px) { .reopen-actions { grid-template-columns: 1fr; } }
.reopen-action { display: flex; flex-direction: column; align-items: flex-start; gap: .45rem; }
.reopen-action .hint { margin: 0; }
.reopen-action button { margin: 0; }

/* perechi eticheta/valoare: eticheta la stanga, valoarea la dreapta, cu o
   latime minima pe valoare ca sa nu se rupa litera cu litera */
.order-facts { margin: 0; display: grid; gap: .3rem; }
.order-facts > div {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; border-bottom: 1px dashed var(--line); padding-bottom: .25rem;
}
.order-facts > div:last-child { border-bottom: 0; }
.order-facts dt { color: var(--ink-soft); font-size: .82rem; flex: 0 0 auto; }
/* `anywhere`, nu `break-word`: doar `anywhere` micsoreaza si LATIMEA MINIMA
   DE CONTINUT a elementului. Cu `break-word`, un hash de 64 de caractere sau o
   cale `store://…` isi impunea latimea intreaga, randul flex refuza sa se
   stranga si depasea coloana — asa ajungeau datele tehnice desenate peste
   panoul vecin (2026-09-12). `min-width: 0` scoate si pragul implicit al
   elementului flex. */
.order-facts dd {
  margin: 0; text-align: right; min-width: 0;
  overflow-wrap: anywhere; word-break: break-word;
}

/* --- cronometre ----------------------------------------------------------- */
.order-timings { display: flex; flex-wrap: wrap; gap: 1.6rem; margin: 0 0 1.4rem; }
.timing { display: flex; flex-direction: column; gap: .1rem; }
.timing-label { font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); }
.timing-value { font-size: 1.05rem; font-weight: 600; }

/* --- cronologia ----------------------------------------------------------- */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline-item {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr) auto;
  gap: .8rem;
  align-items: baseline;
  padding: .5rem 0 .5rem .9rem;
  border-left: 3px solid var(--line);
  position: relative;
}
.timeline-item + .timeline-item { border-top: 1px solid var(--line); }
.timeline-time { color: var(--ink-soft); font-size: .82rem; }
.timeline-body { min-width: 0; }
.timeline-label { font-weight: 600; }
.timeline-detail { display: block; color: var(--ink-soft); font-size: .85rem; overflow-wrap: anywhere; }
.timeline-date { color: var(--ink-soft); font-size: .76rem; white-space: nowrap; }
/* culoarea benzii spune din ce familie e evenimentul, fara sa adauge text */
.timeline-item.is-create   { border-left-color: var(--ink-soft); }
.timeline-item.is-work     { border-left-color: var(--accent); }
.timeline-item.is-money    { border-left-color: var(--warn-ink); }
.timeline-item.is-delivery { border-left-color: var(--ok); }
.timeline-item.is-error    { border-left-color: var(--error); }
.timeline-item.is-error .timeline-label { color: var(--error); }

/* --- datele tehnice, citibile 2026-09-12 (cerinta Xprime) ------------------
   Inainte: patru coloane egale de JSON brut, intr-o grila `auto-fit
   minmax(18rem, 1fr)`. Doua defecte:
     · o pista de 307px primea 874px de continut care nu se rupea, deci
       valorile se desenau peste panoul vecin (cauza reala — vezi
       `.order-facts dd` mai sus);
     · chiar asezate corect, tot JSON brut ramaneau.
   Acum: carduri pe toata latimea, un rand = o eticheta + o valoare care are
   VOIE sa fie lunga, fiindca sta pe randul ei sub eticheta cand nu incape. */
.tech-card { margin-bottom: 1rem; }
.tech-title {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-soft); margin: 0 0 .8rem;
}
.tech-sub {
  font-size: .8rem; font-weight: 600; color: var(--ink-soft);
  margin: 1.1rem 0 .5rem;
}
.tech-sub:first-of-type { margin-top: 0; }

/* Doua coloane cat incap; fiecare rand isi tine eticheta sus si valoarea
   dedesubt, deci o cale de 200 de caractere nu mai impinge nimic. */
.tech-rows {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: .1rem 1.6rem;
}
.tech-rows--tight { margin-top: 1rem; }
.tech-row {
  display: flex; flex-direction: column; gap: .1rem; min-width: 0;
  padding: .45rem 0; border-bottom: 1px dashed var(--line);
}
.tech-key {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-soft);
}
.tech-val {
  font-size: .88rem; line-height: 1.45; min-width: 0;
  overflow-wrap: anywhere; word-break: break-word;
}
/* Cheie pe care clientul NU o vede niciodata. Discreta, dar prezenta: fara ea
   un operator poate raspunde pornind de la ce omul n-a vazut. */
.tech-flag {
  display: inline-block; margin-left: .4rem; padding: .05rem .35rem;
  border-radius: var(--radius-s); background: var(--neutral-bg);
  color: var(--ink-soft); font-size: .62rem; letter-spacing: .03em;
}
.tech-chips { display: flex; flex-wrap: wrap; gap: .35rem; margin: 0 0 .5rem; }
.tech-codes { margin: 0; font-size: .78rem; color: var(--ink-soft); overflow-wrap: anywhere; }

/* Tabelele tehnice au voie sa se rupa pe randuri — spre deosebire de listele
   din admin, aici nu numeri randuri, citesti un rand anume. */
.tech-scroll { overflow-x: auto; }

/* ── ADMIN → ECU NOTES 2026-09-15 ─────────────────────────────────────────
   Tabela regulilor. Coloana de text e cea care conteaza, deci ea primeste
   latimea; cele de potrivire raman inguste si monospace, ca sa se citeasca pe
   verticala. Randurile stinse se vad ca stinse fara sa devina ilizibile: 62%
   opacitate, nu culoare de eroare — o regula oprita nu e o greseala. */
.ecunote-table th { text-align: left; }
.ecunote-table td { vertical-align: top; }
.ecunote-table th:nth-child(1), .ecunote-table td:nth-child(1),
.ecunote-table th:nth-child(2), .ecunote-table td:nth-child(2),
.ecunote-table th:nth-child(3), .ecunote-table td:nth-child(3) { white-space: nowrap; }
.ecunote-body { min-width: 18rem; line-height: 1.5; overflow-wrap: anywhere; }
.ecunote-off { opacity: .62; }
/* Butoanele de pe rand: formularele sunt blocuri, deci fara asta fiecare
   actiune ar coborî pe randul ei si randul tabelei ar creste de trei ori. */
.ecunote-actions { display: flex; flex-wrap: nowrap; gap: .35rem; align-items: center; white-space: nowrap; }
.ecunote-actions form { display: inline; margin: 0; }
/* Coloana de text primeste latimea; restul raman cat le trebuie. Fara asta,
   tabela imparte egal si nota — singurul lucru pentru care se deschide pagina —
   iese pe patru randuri langa trei coloane goale. */
.ecunote-table th:nth-child(4), .ecunote-table td:nth-child(4) { width: 46%; }
/* Bifele folosesc conventia casei (`label.opt` din formularul de furnizor);
   aici se regleaza doar distanta dintre ele si alinierea pe randuri lungi, unde
   textul trece pe doua randuri si bifa trebuie sa ramana la primul. */
/* Selectorul poarta si `.form-grid` fiindca regula casei (`.form-grid
   label.opt { align-items: center }`) e scrisa mai jos in fisier: la
   specificitate egala ar castiga ea, si bifa ar sta la mijlocul unei etichete
   de trei randuri in loc de langa primul cuvant. */
.ecunote-checks { gap: .45rem; }
.form-grid .ecunote-checks label.opt { align-items: flex-start; gap: .5rem; }
.form-grid .ecunote-checks label.opt input { width: auto; margin-top: .2rem; flex: 0 0 auto; }
.ecunote-intro p { margin: 0 0 .6rem; font-size: .95rem; line-height: 1.55; }
.ecunote-intro p:last-child { margin-bottom: 0; }
/* `min-width` NU e decor. `.data-table` are `width: 100%`, deci pe ecran
   ingust tabelul se stranges la latimea cutiei si continutul iesea din celule
   in loc ca CUTIA sa se deruleze — adica exact defectul reparat mai sus, mutat
   cu un nivel mai jos. Cu un prag, tabelul depaseste cutia, cutia se deruleaza
   si bara orizontala lipita de jos (partials/hscroll.php) o prinde singura. */
.tech-table { margin-top: .2rem; min-width: 32rem; }
.tech-table th, .tech-table td { white-space: normal; vertical-align: top; }
.tech-table td { font-size: .84rem; }
.tech-names { color: var(--ink-soft); font-size: .8rem; overflow-wrap: anywhere; }
.tech-events .tech-when { white-space: nowrap; }

/* meta unui eveniment: perechi, nu acolade */
.meta-pairs { display: flex; flex-wrap: wrap; gap: .3rem .45rem; }
.meta-pair {
  display: inline-flex; align-items: baseline; gap: .3rem; min-width: 0;
  padding: .1rem .45rem; border: 1px solid var(--line);
  border-radius: var(--radius-s); background: var(--panel-2);
}
.meta-k { font-size: .68rem; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-soft); }
.meta-v { font-size: .8rem; overflow-wrap: anywhere; }

/* verdictul portii, cu aceleasi culori ca peste tot */
.ui-badge.gate-allow  { background: var(--ok-bg); color: var(--ok); }
.ui-badge.gate-refuse { background: var(--error-bg); color: var(--error); }
.ui-badge.gate-review { background: var(--warn-bg); color: var(--warn-ink); }

/* JSON-ul brut n-a disparut: sta pliat, sub datele citibile. */
.raw-drop { margin-top: 1rem; }
.raw-drop > summary {
  cursor: pointer; color: var(--ink-soft); font-size: .78rem; list-style: revert;
}
.raw-drop[open] > summary { margin-bottom: .6rem; }
.raw-json {
  margin: 0; padding: .7rem .8rem; background: var(--neutral-bg);
  border-radius: var(--radius-s); font-size: .78rem; line-height: 1.5;
  max-height: 22rem; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere;
}

@media (max-width: 720px) {
  .timeline-item { grid-template-columns: 4.6rem minmax(0, 1fr); }
  .timeline-date { grid-column: 2; }
  .order-timings { gap: 1.1rem; }
}

/* ============================================================================
   PROFIL CLIENT 2026-08-04 (cerinta Xprime)
   ========================================================================== */
.ident-card { display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem 1.4rem; }
.ident-label { display: block; font-size: .74rem; text-transform: uppercase;
               letter-spacing: .06em; color: var(--ink-soft); }
.ident-value { font-size: 1.5rem; font-weight: 700; letter-spacing: .08em; color: var(--accent-dark); }
.ident-hint { margin: 0; flex: 1 1 16rem; min-width: 0; }

.profile-grid {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: 1.2rem;
  align-items: start;
}
.profile-grid > * { min-width: 0; }
.profile-grid .card { margin-bottom: 0; }
.profile-grid h2 { margin-top: 0; font-size: 1.15rem; }
.form-section {
  margin: 1.4rem 0 .4rem; font-size: .78rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-soft); font-weight: 600;
  border-top: 1px solid var(--line); padding-top: 1rem;
}
/* randuri de campuri care se aseaza pe verticala cand nu mai incap, cu
   min-width:0 ca inputurile sa poata chiar sa se micsoreze in grila */
.field-row { display: flex; flex-wrap: wrap; gap: 0 1rem; }
.field-row > label { flex: 1 1 12rem; min-width: 0; }
.field-row > label.field-narrow { flex: 0 1 7rem; }

/* Selectorul de limba din bara laterala a panoului.
   2026-08-04 (a doua trecere, observatie Xprime): arata ca un camp de formular
   gol si dezactivat, pentru ca imprumuta `.lang-switch` din antetul public —
   acolo e o pastila cu chenar, buna pe un rand orizontal, dar `<details>` e
   element de tip bloc, deci in bara laterala se intindea pe toata latimea.
   Acum e un rand de meniu ca celelalte: eticheta discreta, limba curenta ca
   pastila mica, sageata care se roteste la deschidere. */
.panel-lang { margin-bottom: .35rem; }
.panel-lang > summary {
  display: flex; align-items: center; gap: .5rem;
  cursor: pointer; list-style: none;
  padding: .4rem .55rem; margin: 0 -.55rem;
  border-radius: var(--radius-s);
  font-size: .85rem; color: var(--ink-soft);
  transition: background .15s ease, color .15s ease;
}
.panel-lang > summary::-webkit-details-marker { display: none; }
.panel-lang > summary:hover { background: var(--neutral-bg); color: var(--ink); }
.panel-lang[open] > summary { color: var(--ink); }
.panel-lang-label { flex: 1 1 auto; min-width: 0; }
.panel-lang-current {
  flex: 0 0 auto; font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  padding: .1rem .4rem; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-dark);
}
/* sageata desenata din chenare — fara imagini si fara font de pictograme */
.panel-lang-caret {
  flex: 0 0 auto; width: 0; height: 0;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid var(--ink-soft);
  transition: transform .15s ease;
}
.panel-lang[open] .panel-lang-caret { transform: rotate(180deg); }

/* LISTA DE LIMBI (2026-08-20, Xprime). Era o grila de pastile de cate doua
   litere. Cu douazeci de limbi devine un perete de abrevieri, si cauti in el
   litera cu litera. Acum e o lista verticala cu numele nativ; codul ramane, mic
   si in dreapta, pentru cine il stie pe al lui.

   `max-height` + derulare: fara ele, meniul deschis ar impinge in jos tot ce e
   sub el in panou si ar iesi din ecran pe laptop. */
.panel-lang ul {
  list-style: none; margin: .35rem 0 .2rem; padding: 0;
  display: block; max-height: 15rem; overflow-y: auto;
  border: 1px solid var(--line); border-radius: var(--radius-s);
  background: var(--panel);
}
/* `text-decoration: none` nu e cosmetica: intr-o lista in care fiecare rand e
   un link, sublinierea pe toate randurile o transforma intr-un desis de linii.
   Randul intreg e zona de clic, deci nu se pierde nimic din "e clicabil". */
.panel-lang li a {
  display: flex; align-items: baseline; justify-content: space-between; gap: .6rem;
  padding: .38rem .6rem; border-radius: 0; text-decoration: none;
  font-size: .82rem; color: var(--ink-soft);
  transition: background .15s ease, color .15s ease;
}
.panel-lang li + li a { border-top: 1px solid var(--line); }
.panel-lang li a .lang-code,
.lang-switch li a .lang-code {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .04em;
  color: var(--muted); flex: none;
}
.panel-lang li a:hover { background: var(--accent-soft); color: var(--accent-dark); }
.panel-lang li a.current { background: var(--accent-btn); color: var(--accent-ink); font-weight: 600; }
.panel-lang li a.current .lang-code { color: rgba(255,255,255,.75); }
.panel-lang-current { max-width: 8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Acelasi tratament in antetul public: lista se deschide cu numele native, si
   se deruleaza daca sunt multe. */
.lang-switch ul { max-height: 16rem; overflow-y: auto; min-width: 11rem; }
.lang-switch li a {
  display: flex; align-items: baseline; justify-content: space-between; gap: .8rem;
  font-family: inherit; font-size: .85rem; text-decoration: none;
}
.panel-cookie { font-size: .8rem; }

@media (max-width: 900px) {
  .profile-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================================
   REPARATII DE PREZENTARE 2026-08-04 (gasite la auditul paginilor)
   ========================================================================== */

/* 1. Bara de cookie e position:fixed peste subsol si nimic nu compensa
      inaltimea ei: pana la acceptare acoperea Termeni / Confidentialitate /
      Setari cookie — exact link-urile pe care le cere legea sa fie accesibile. */
body.cookie-open { padding-bottom: 12rem; }
@media (min-width: 720px) { body.cookie-open { padding-bottom: 8rem; } }

/* 2. .col-file primea overflow:hidden dintr-o regula ulterioara, iar celula
      contine numele fisierului SI eticheta Auto/Manual — pe nume lungi
      eticheta era pur si simplu taiata. Celula devine flex, cu numele
      trunchiat si eticheta pastrata intreaga. */
/* Doar celulele care chiar au eticheta Auto/Manual devin flex; restul isi
   pastreaza trunchierea cu "…" (altfel numele lungi de fisier ar impinge
   tabelul din Orders in afara cardului). */
/* CORECTAT 2026-08-21: flexul sta pe un INVELIS din interiorul celulei, nu pe
   celula. Un `<td>` cu `display: flex` inceteaza sa mai fie celula de tabel:
   coloana lui nu mai poate fi masurata, iar restul randului se desprinde de
   capul de tabel — statusul ajungea peste data, si data peste total. */
.data-table td.col-file { min-width: 0; }
.job-file-line { display: flex; align-items: baseline; gap: .35rem; min-width: 0; }
.job-file-line > .job-file { flex: 0 1 auto; }
.job-file-line > .job-kind { flex: 0 0 auto; }

/* 3. A FOST SCOASA 2026-08-21. Era a treia copie a regulilor pentru randul de
      perioada, pusa aici ca sa bata a doua, care batea prima. Acum exista o
      singura definitie, cu media query-ul ei lipit dedesubt — deci nu mai are
      cine pe cine sa bata. */

/* 4. .vehicle-data dd avea overflow-wrap:anywhere + min-width:0 intr-o coloana
      de 14rem: numerele SW/HW se rupeau literă cu literă. Un prag de latime
      opreste asta; ce nu incape curge pe randul urmator, ca la un text normal. */
.vehicle-data dd { min-width: 6rem; overflow-wrap: break-word; }

/* 5. .eyebrow gol (cheia 'home.eyebrow' e sir vid in toate cele 9 limbi)
      lasa ~44px de spatiu fantoma deasupra fiecarui titlu de hero. */
.eyebrow:empty { display: none; }

/* --- selector de utilizator in Reports 2026-08-04 -------------------------- */
.user-picker-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.user-picker-head h2 { margin: 0; font-size: 1.05rem; }
.user-filter { width: 100%; margin: .7rem 0 .6rem; }
.user-picker-list { max-height: 22rem; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--radius-s); }
.user-pick {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .55rem .8rem; border-bottom: 1px solid var(--line); color: inherit; text-decoration: none;
}
.user-pick:last-child { border-bottom: 0; }
.user-pick:hover { background: var(--neutral-bg); }
.user-pick.is-current { background: var(--accent-soft); }
.user-pick[hidden] { display: none; }
.user-pick-main { display: flex; flex-direction: column; min-width: 0; }
.user-pick-email { font-weight: 600; overflow-wrap: anywhere; }
.user-pick-name { font-size: .82rem; color: var(--ink-soft); overflow-wrap: anywhere; }
.user-pick-meta { display: flex; align-items: center; gap: .8rem; flex: 0 0 auto; text-align: right; }
.user-pick-meta .user-ref { display: inline; font-weight: 600; color: var(--accent-dark); }
@media (max-width: 620px) {
  .user-pick { flex-direction: column; align-items: flex-start; gap: .3rem; }
  .user-pick-meta { text-align: left; }
}


/* Orders: cu doua coloane in plus, tabelul trebuie sa incapa in card la 1100px.
   Numele fisierului se trunchiaza cu "…" si se citeste intreg la hover
   (title), in loc sa impinga User / OLS / Created in afara ecranului. */
.cell-clip {
  display: inline-block; max-width: 20rem; vertical-align: bottom;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.col-user .cell-clip { max-width: 12rem; }
@media (max-width: 1300px) {
  .cell-clip { max-width: 12rem; }
  .col-user .cell-clip { max-width: 9rem; }
}
.col-user { min-width: 0; }

/* Orders, la latimi mici: coloanele secundare se retrag ca sa incapa cele care
   conteaza (ECU, Operation, File). Datele nu se pierd — sunt pe pagina comenzii. */
.col-type { text-transform: uppercase; font-size: .74rem; color: var(--ink-soft); letter-spacing: .04em; }
.col-when { line-height: 1.25; }
.col-when .when-date { display: block; }
.col-when .when-time { display: block; font-size: .76rem; color: var(--ink-soft); }
@media (max-width: 1300px) {
  .data-table th.col-ols, .data-table td.col-ols { display: none; }
}
@media (max-width: 1100px) {
  .data-table th.col-type, .data-table td.col-type { display: none; }
}
/* Sub 1300px tabelul de comenzi trebuie sa incapa fara derulare orizontala:
   spatiere mai stransa si limite mai mici pe textele lungi. */
@media (max-width: 1300px) {
  body.admin .data-table th, body.admin .data-table td { padding: .55rem .5rem; }
  .cell-clip { max-width: 10rem; }
  .col-user .cell-clip { max-width: 8rem; }
  .col-op { min-width: 7rem; }
}

/* FIX 2026-08-04: tipurile de input `tel`, `search`, `number`, `url` si `date`
   nu erau in lista de la linia 177, deci ramaneau cu stilul implicit al
   browserului — un chenar subtire, de alta marime, lipit de eticheta. Se vedea
   pe campul Telefon din profil si pe casetele de cautare. */
input[type="tel"], input[type="search"], input[type="number"], input[type="url"] {
  width: 100%; padding: 0.68rem 0.95rem;
  border: 1px solid var(--line); border-radius: var(--radius-s);
  background: var(--bg); color: var(--ink);
  font: inherit;
  transition: border-color 0.15s ease, background 0.15s ease;
}

/* FIX 2026-08-04 (telefon): sub 900px meniul panoului devine `flex-wrap`, iar
   grupurile ajungeau unul langa altul — pe un ecran de 390px "Dashboard" statea
   lipit de coloana "File service", ca doua meniuri suprapuse. Sub 620px fiecare
   grup ocupa toata latimea si se citeste ca o lista, nu ca un puzzle. */
@media (max-width: 900px) {
  .admin-nav-group { flex: 1 1 13rem; min-width: 0; }
}
@media (max-width: 620px) {
  .admin-nav { flex-direction: column; gap: .1rem; }
  .admin-nav-group { flex: 1 1 auto; width: 100%; margin-bottom: .8rem; }
  .admin-side { padding-bottom: .8rem; }
  .panel-topbar { flex-wrap: wrap; gap: .5rem; }
}


/* ============================================================================
   SPATIERE INTRE CARDURI 2026-08-04 (observatie Xprime: "sectiunile sunt lipite")
   `.card` nu are NICIO margine, deci doua carduri unul sub altul se ating —
   se vedea limpede in Profil, intre caseta cu ID-ul clientului si formularele
   de dedesubt, dar problema era generala, nu doar acolo. Un card care urmeaza
   imediat dupa alt card (sau dupa o grila de carduri) primeste acum distanta.
   Regula atinge doar fratii adiacenti, deci nu strica nimic din ce era deja
   asezat in grile cu `gap`.
   ========================================================================== */
.card + .card,
.card + .profile-grid,
.profile-grid + .card,
.card + .order-summary,
.order-summary + .card { margin-top: 1.2rem; }

/* Coloana din dreapta a profilului: cardurile stivuite pe verticala. */
.profile-grid > div > .card + .card { margin-top: 1.2rem; }

/* Caseta cu ID-ul clientului: aceeasi distanta fata de formularele de dedesubt. */
.ident-card { margin-bottom: 1.2rem; }

/* ============================================================================
   IESIREA CATRE PROCESAREA MANUALA 2026-08-04 (cerinta Xprime)
   Un singur buton pe ecranele fara iesire ale fluxului automat, plus confirmarea
   ca fisierul deja urcat merge mai departe singur.
   ========================================================================== */
.manual-fallback-note { margin: .7rem 0 0; }

/* Confirmarea de la pasul 2: fisierul a venit din fluxul automat. */
.carried-file {
  display: flex; align-items: flex-start; gap: .8rem;
  border-left: 3px solid var(--ok);
}
.carried-file-check {
  flex: 0 0 auto; width: 1.5rem; height: 1.5rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--ok-bg); color: var(--ok); font-weight: 700; font-size: .85rem;
}
.carried-file-body { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.carried-file-title { font-weight: 600; }
.carried-file-name { color: var(--ink-soft); font-size: .88rem; overflow-wrap: anywhere; }

/* ============================================================================
   MANUAL · optiuni fara pret + lista de DTC-uri 2026-08-04 (cerinta Xprime)
   ========================================================================== */

/* "Price on request": nu e gratis, deci nu poarta verdele de la "inclus". */
.mfs-option-price.is-quote {
  color: var(--warn-ink); font-weight: 600;
  /* Eticheta e mai lunga decat o suma, iar coloana de pret e ingusta: o lasam
     sa treaca pe doua randuri in loc sa iasa din caseta. */
  white-space: normal; text-align: right; line-height: 1.25; font-size: .78rem;
}

/* FIX 2026-08-04, observat la aceeasi trecere: `white-space: nowrap` pe pretul
   optiunii taia sumele lungi ("300.00 credits" -> "300.00 cred…") in casetele
   inguste, fiindca a treia coloana a grilei nu are voie sa creasca. Textul are
   voie sa curga pe doua randuri; cifrele raman aliniate la dreapta. */
.mfs-option-price { white-space: normal; text-align: right; }

/* Zona de DTC-uri, sub lista de optiuni. Apare cand se bifeaza ceva. */
.mfs-dtc {
  margin: 1.1rem 0 0; padding: 1rem 1.1rem;
  background: var(--neutral-bg); border-radius: var(--radius-s);
  border-left: 3px solid var(--accent);
}
.mfs-dtc[hidden] { display: none; }
.mfs-dtc .fld-label { font-weight: 600; }
.mfs-dtc .hint { display: block; margin: .15rem 0 .5rem; }
.mfs-dtc textarea {
  width: 100%; padding: .6rem .8rem; font: inherit;
  border: 1px solid var(--line); border-radius: var(--radius-s);
  background: var(--panel); color: var(--ink); resize: vertical;
}
.mfs-dtc textarea:focus { outline: none; border-color: var(--accent-btn); }

/* Fisa comenzii, in admin: DTC-urile sunt instructiuni de lucru. */
.mfs-dtc-note {
  background: var(--warn-bg); border-left: 3px solid var(--warn-ink);
  padding: .6rem .8rem; border-radius: var(--radius-s);
  white-space: pre-wrap; overflow-wrap: anywhere;
}

/* Formularul de pret final din admin. */
.mfs-price-set { display: flex; flex-wrap: wrap; gap: .5rem; margin: .6rem 0; }
.mfs-price-set input { flex: 1 1 14rem; min-width: 0; }

/* ============================================================================
   VALIDARE ARATATA PE CAMPURI 2026-08-04 (cerinta Xprime)
   Mesajul rosu de sus spunea ce lipseste, dar niciun camp nu era marcat — omul
   citea "spune-ne macar marca si motorul" si se uita la un formular fara niciun
   semn. Acum: asterisc pe minimul necesar, chenar rosu si mesaj sub campul
   respins, si sarim cu focusul acolo.
   ========================================================================== */
.req { color: var(--error); font-weight: 700; }
.form-required-note { margin: -.3rem 0 1rem; }

.fld.is-invalid input,
.fld.is-invalid select,
.fld.is-invalid textarea {
  border-color: var(--error);
  background: var(--error-bg);
}
.fld.is-invalid input:focus,
.fld.is-invalid select:focus,
.fld.is-invalid textarea:focus {
  border-color: var(--error);
  box-shadow: 0 0 0 3px rgba(192, 57, 43, .15);
}
.field-error {
  display: block; margin-top: .25rem;
  color: var(--error); font-size: .82rem; font-weight: 600;
}
/* Cand lipseste alegerea din liste, marcam intreg grupul, nu un singur camp. */
.mfs-grid-2.has-error { outline: 2px solid var(--error-bg); outline-offset: .5rem; border-radius: var(--radius-s); }
#mfs-cascade-error { margin: 0 0 .8rem; }

/* ==========================================================================
   2026-08-04 (a treia trecere, raportari Xprime)
   ========================================================================== */

/* "I can't find my vehicle in the list" — buton, nu nota de subsol.
   Era un .link-button (text subliniat) intr-un <p class="hint">: adica scris
   mic, sters, exact ca o precizare pe care ochiul o sare. Numai ca e singura
   iesire pentru omul al carui vehicul chiar nu e in liste — daca n-o vede,
   ramane blocat la pasul 2. Acum e un buton pe toata latimea, cu chenar. */
.mfs-notfound { margin: 1rem 0 0; }
.mfs-notfound button {
  display: block; width: 100%; box-sizing: border-box;
  padding: .8rem 1rem; border: 1px dashed var(--line); border-radius: 10px;
  background: var(--neutral-bg); color: var(--ink);
  font: inherit; font-weight: 600; text-align: center; text-decoration: none;
  cursor: pointer; transition: border-color .15s, background .15s, color .15s;
}
.mfs-notfound button:hover,
.mfs-notfound button:focus-visible {
  border-color: var(--accent); border-style: solid;
  background: var(--panel); color: var(--accent);
}
.mfs-notfound .mfs-notfound-hint {
  display: block; margin-top: .25rem;
  font-weight: 400; font-size: .84rem; color: var(--ink-soft);
}

/* Politica de nerambursare, cand se ajunge la ea din link (pasul 5). */
.mfs-policy.is-highlight {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(20, 147, 205, .18);
}
.mfs-policy[open] summary { margin-bottom: .2rem; }

/* Banda de avertizare din panou cand exista migrari nerulate. */
.admin-migrate-warning { line-height: 1.6; }
.admin-migrate-warning code {
  display: inline-block; background: rgba(255, 255, 255, .55);
  border-radius: 6px; padding: .05rem .4rem; font-size: .9em;
}

/* Admin -> Migrations (2026-08-04). */
.migrate-table td { vertical-align: top; }
.migrate-table tr.is-pending td { background: var(--warn-bg); }
.migrate-actions { display: flex; gap: .45rem; flex-wrap: wrap; }
.btn-quiet { background: transparent; border: 1px solid var(--line); color: var(--ink-soft); }
.btn-quiet:hover { border-color: var(--accent); color: var(--accent); }
.mfs-badge.warn-badge { background: var(--warn-bg); color: var(--warn-ink); }
.migrate-danger { margin-top: .5rem; }
.migrate-danger summary { cursor: pointer; font-size: .85rem; color: var(--warn-ink); font-weight: 600; }
.migrate-danger pre {
  margin: .4rem 0 0; padding: .5rem .7rem; background: var(--error-bg);
  border: 1px solid var(--error-line); border-radius: 8px;
  font-size: .8rem; white-space: pre-wrap; word-break: break-word;
}
.migrate-log-head { margin: .9rem 0 .2rem; font-weight: 600; }
.migrate-log-head.is-ok { color: var(--ok); }
.migrate-log-head.is-bad, .migrate-log .is-bad { color: var(--error); }
.migrate-log { margin: 0 0 .3rem; padding-left: 1.3rem; font-size: .86rem; color: var(--ink-soft); }
.admin-migrate-warning .btn-small { margin-left: .5rem; vertical-align: baseline; }
.migrate-verdict { border-left: 3px solid var(--line); padding-left: .8rem; }
.migrate-verdict.is-ok { border-left-color: var(--ok); }
.migrate-verdict.is-bad { border-left-color: var(--error); }
.migrate-state { display: block; margin-top: .2rem; font-size: .8rem; }
.migrate-state.is-ok { color: var(--ok); }
.migrate-state.is-bad { color: var(--error); }

/* Pagini juridice — sablon unic (2026-08-04). */
.legal-stamp { font-size: .85rem; color: var(--ink-soft); margin-top: .4rem; }
/* Versiunea si data stau in interiorul benzii albastre, unde --ink-soft (gri
   inchis, gandit pentru fundal alb) devenea aproape ilizibil. In hero scriem
   cu alb translucid; in restul paginii ramane cum era. */
.hero .legal-stamp { color: rgba(255,255,255,.82); }
.legal-section { margin-bottom: 1.8rem; scroll-margin-top: 1.5rem; }
.legal-section:last-child { margin-bottom: 0; }
.legal-section h2 { margin: 0 0 .5rem; font-size: 1.12rem; }
.legal-section p { margin: 0 0 .7rem; line-height: 1.65; }
.legal-list { margin: .2rem 0 .8rem; padding-left: 1.25rem; }
.legal-list li { margin-bottom: .4rem; line-height: 1.6; }
/* Caseta de atentionare dintr-o sectiune: se citeste inainte de restul ei. */
.legal-note {
  border-left: 3px solid var(--accent); background: var(--neutral-bg);
  padding: .6rem .9rem; border-radius: 0 8px 8px 0; font-weight: 500;
}
/* Documentul cu datele de firma necompletate. Intentionat greu de ignorat. */
.legal-incomplete { border: 2px solid var(--warn); background: var(--warn-bg); }
.legal-incomplete h2 { margin-top: 0; color: var(--warn-ink); }
.legal-incomplete ul { margin: .4rem 0; padding-left: 1.25rem; }
/* Tabelul din politica de cookie-uri.
   Latimile sunt fixate pentru ca altfel coloana "la ce foloseste" — care e cea
   lunga — impinge "cat durata" si "categorie" in afara cardului, si exact alea
   doua sunt informatia pe care o cauta cineva intr-o politica de cookie-uri.
   Pe telefon tabelul se poate trage lateral. */
.legal-table-wrap { overflow-x: auto; margin: .6rem 0 .9rem; -webkit-overflow-scrolling: touch; }
.legal-table { width: 100%; min-width: 34rem; table-layout: fixed; font-size: .86rem; }
.legal-table th { white-space: nowrap; }
.legal-table td { vertical-align: top; line-height: 1.5; word-break: break-word; }
.legal-table th:nth-child(1), .legal-table td:nth-child(1) { width: 22%; }
.legal-table th:nth-child(2), .legal-table td:nth-child(2) { width: 42%; }
.legal-table th:nth-child(3), .legal-table td:nth-child(3) { width: 19%; }
.legal-table th:nth-child(4), .legal-table td:nth-child(4) { width: 17%; }

/* Politica de cookie-uri pe ecran ingust: tabelul devine o lista de fise.
   Derularea laterala ascundea tocmai coloanele "cat durata" si "categorie". */
@media (max-width: 620px) {
  .legal-table-wrap { overflow-x: visible; }
  .legal-table { min-width: 0; table-layout: auto; display: block; }
  .legal-table thead { display: none; }
  .legal-table tbody, .legal-table tr, .legal-table td { display: block; width: auto; }
  .legal-table tr {
    border: 1px solid var(--line); border-radius: 10px;
    padding: .6rem .8rem; margin-bottom: .6rem; background: var(--panel);
  }
  .legal-table td { border: 0; padding: .2rem 0; }
  .legal-table td:first-child { font-weight: 600; font-size: .95rem; }
  /* Numele coloanei, in fata valorii — dar nu si la prima celula, unde
     valoarea (numele cookie-ului) e deja titlul fisei. */
  .legal-table td:not(:first-child)::before {
    content: attr(data-label) ": ";
    color: var(--ink-soft); font-weight: 600;
  }
}

/* Mass mailer (2026-08-04). */
.camp-count { margin: .2rem 0 1rem; color: var(--ink-soft); }
.camp-count strong { color: var(--ink); font-size: 1.1rem; }
.camp-tabs { margin-bottom: .8rem; flex-wrap: wrap; }
.camp-tab { cursor: pointer; font: inherit; }
.camp-pane textarea { width: 100%; font-family: inherit; line-height: 1.55; }
/* Starea de newsletter in liste. Trei stari distincte, nu doua — vezi
   Mail\Unsubscribe::state. */
.news-badge { display: inline-block; padding: .12rem .5rem; border-radius: 999px; font-size: .75rem; font-weight: 600; }
.news-subscribed   { background: var(--ok-bg); color: var(--ok); }
.news-unsubscribed { background: var(--error-bg); color: var(--error); }
.news-never        { background: var(--neutral-bg); color: var(--ink-soft); }
.marketing-opt { margin-top: .3rem; }
.reg-consent { display: flex; gap: .6rem; align-items: flex-start; margin: .8rem 0; line-height: 1.5; }
.reg-consent input { margin-top: .25rem; flex: 0 0 auto; }
.unsub-card { max-width: 640px; }

/* ===========================================================================
   IDENTIFICARE VIZIBILA IN ISTORIC — 2026-08-20 (cerinta Xprime)
   ========================================================================= */

/* Randul cu masina si calculatorul, sub numele fisierului, in listele de
   comenzi. Celula .col-file e `display:flex` cand are eticheta Auto/Manual
   (regula de mai sus, pusa ca sa nu iasa numele lungi din card) — deci fara
   `flex-basis:100%` + `flex-wrap` randul nostru s-ar aseza pe ACEEASI linie,
   in continuarea etichetei, si ar fi taiat imediat. */
.data-table td.col-file:has(> .job-identity) { flex-wrap: wrap; }
.job-identity {
  display: block;
  flex: 0 0 100%;
  margin-top: .15rem;
  font-size: .82rem;
  line-height: 1.35;
  /* Numele complet al masinii + ECU + HW + SW poate depasi latimea coloanei;
     il taiem cu "…" in loc sa latim tabelul. Randul complet ramane la un click
     distanta, pe pagina fisierului. */
  max-width: 32rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Cardul de identificare afisat DUPA livrare (platit / descarcat / expirat).
   Vine la finalul paginii, sub cardul de download, deci are nevoie de aer
   deasupra — spre deosebire de cel din ecranul de alegere a optiunilor, care
   e primul element din pagina. */
.vehicle-card--history { margin-top: 1.3rem; }

/* ===========================================================================
   ANUNT LA INTRAREA IN PROCESAREA MANUALA — 2026-08-20 (cerinta Xprime)
   ========================================================================= */

/* Cerinta a fost "sa scrie mare". Deci nu e un `.hint` si nu e un flash:
   e o banda proprie, cu text mai mare decat al paginii, asezata intre titlu si
   primul card. Conditiile comerciale ("nu e inclus in pachetul dvs.") se citesc
   inainte de completarea comenzii, nu dupa. */
.mfs-entry-notice {
  margin: 1rem 0 1.4rem;
  padding: 1rem 1.2rem;
  border-radius: 10px;
  border: 1px solid;
  border-left-width: 4px;
  font-size: 1.08rem;
  font-weight: 500;
  line-height: 1.5;
}
.mfs-entry-notice--warn {
  border-color: var(--warn-line);
  border-left-color: var(--warn);
  background: var(--warn-bg);
  color: var(--warn-ink);
}
.mfs-entry-notice--info {
  border-color: var(--accent-line);
  border-left-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-dark);
}
@media (max-width: 640px) {
  .mfs-entry-notice { font-size: 1rem; padding: .85rem 1rem; }
}

/* ===========================================================================
   PICTOGRAME LA PROCESAREA MANUALA — 2026-08-20 (cerinta Xprime)
   ========================================================================= */

/* Desenele vin inline din `ManualService\Icons`, cu `stroke: currentColor` —
   deci mostenesc culoarea randului si se sting singure cand optiunea e
   indisponibila. Nu au culori proprii, ca sa nu concureze cu accentul paginii. */
.mfs-icon {
  width: 26px;
  height: 26px;
  color: var(--ink-soft);
  transition: color .12s ease;
}

/* Randurile erau `auto 1fr auto` (bifa, titlu, pret). Cu desenul intre bifa si
   titlu devin patru coloane — fara asta, pictograma ar fi impins pretul afara
   din card sau ar fi fost strivita de coloana `1fr`. */
.mfs-type,
.mfs-option { grid-template-columns: auto auto 1fr auto; }

/* Selectat: desenul preia accentul, ca alegerea sa se vada dintr-o privire pe
   toata grila, nu doar dupa chenar. */
.mfs-option:has(input:checked) .mfs-icon,
.mfs-type:has(input:checked) .mfs-icon { color: var(--accent); }

/* Pe tipuri desenul e mai mare si aliniat cu titlul, nu centrat pe card:
   cardul de tip are si descriere sub titlu, deci creste in inaltime. */
.mfs-type-icon { width: 30px; height: 30px; align-self: start; margin-top: .1rem; }

@media (max-width: 560px) {
  /* Pe ecran ingust cele patru coloane trebuie sa incapa intr-o pista de ~260px.
     Desenul e primul lucru care poate ceda din latime: eticheta si pretul
     trebuie sa ramana citibile, forma se recunoaste si mai mica. */
  .mfs-icon { width: 22px; height: 22px; }
}

.icon-cell { white-space: nowrap; }
.icon-cell .icon-preview { display: inline-flex; vertical-align: middle; margin-right: .4rem; color: var(--accent-dark); }
.icon-cell .icon-input { width: 10rem; vertical-align: middle; }
/* Nume inexistent in registru, marcat pe loc: altfel operatorul salveaza o
   greseala de tastare, serverul o respinge tacut (o transforma in "fara
   pictograma") si el afla abia deschizand pagina clientului. */
.icon-cell .icon-input.is-bad { border-color: var(--error); background: var(--error-bg); }

/* Pictograma in listele de rezumat (sumar comanda, dosar client, fisa
   inginerului): mai mica si asezata pe linia de text, ca sa insoteasca
   eticheta, nu s-o inlocuiasca. */
.mfs-icon-inline { width: 18px; height: 18px; vertical-align: -3px; margin-right: .2rem; }

/* ===========================================================================
   GREEN / RED COINS — 2026-08-20 (cerinta Xprime)
   ========================================================================= */

:root {
  /* Verdele si rosul sunt SEMANTICE aici, nu decorative: spun pe ce se poate
     cheltui suma. De-aia sunt tokenuri proprii si nu nuante alese pe loc —
     aceeasi culoare trebuie sa insemne acelasi lucru pe toate ecranele. */
  --coin-green: #54e99a;
  --coin-green-soft: rgba(84,233,154,.13);
  --coin-green-ink: #6be7a5;
  --coin-red: #ff796f;
  --coin-red-soft: rgba(255,121,111,.13);
  --coin-red-ink: #ff8f85;
}

/* ---- bara de sus a panoului ------------------------------------------------ */
.panel-topbar { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.panel-coins {
  display: inline-flex; align-items: baseline; gap: .35rem;
  padding: .3rem .7rem; border-radius: 999px; text-decoration: none;
  border: 1px solid; font-variant-numeric: tabular-nums;
}
.panel-coins-value { font-weight: 600; }
.panel-coins-label { font-size: .78rem; opacity: .8; }
.panel-coins--green { border-color: var(--ok-line); background: var(--coin-green-soft); color: var(--coin-green-ink); }
.panel-coins--red   { border-color: var(--error-line); background: var(--coin-red-soft);   color: var(--coin-red-ink); }

/* Bulina de culoare: pentru cine nu distinge verde de rosu, eticheta text de
   langa ea ("green" / "red") ramane purtatorul informatiei. Culoarea intareste,
   nu inlocuieste. */
.coin-dot { width: .6rem; height: .6rem; border-radius: 50%; flex: 0 0 auto; align-self: center; }
.panel-coins--green .coin-dot, .coin-card--green .coin-dot { background: var(--coin-green); }
.panel-coins--red   .coin-dot, .coin-card--red   .coin-dot { background: var(--coin-red); }

/* ---- cardurile portofelelor ------------------------------------------------ */
.coin-wallets { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 1rem; margin-bottom: 1.6rem; }
.coin-card { border-top: 4px solid transparent; }
.coin-card--green { border-top-color: var(--coin-green); }
.coin-card--red   { border-top-color: var(--coin-red); }
.coin-card-head { display: flex; align-items: center; gap: .5rem; }
.coin-card-head h2 { margin: 0; }
.coin-card-what { margin: .3rem 0 1rem; }

.coin-total { display: flex; align-items: baseline; gap: .5rem; margin-bottom: .9rem; }
.coin-total-value { font-size: 2.1rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.coin-card--green .coin-total-value { color: var(--coin-green-ink); }
.coin-card--red   .coin-total-value { color: var(--coin-red-ink); }
.coin-total-label { color: var(--ink-soft); font-size: .9rem; }

/* Alocatia si coins-ii cumparati stau SEPARAT, nu insumati. Suma singura ar
   ascunde exact ce conteaza: o parte expira diseara, cealalta nu. */
.coin-breakdown { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem 1rem; margin: 0 0 .8rem; }
.coin-breakdown div { border-top: 1px solid var(--line); padding-top: .45rem; }
.coin-breakdown dt { font-size: .82rem; color: var(--ink-soft); }
.coin-breakdown dd { margin: .15rem 0 0; font-family: var(--mono); font-size: 1rem; }
.coin-reset, .coin-rate { margin: .2rem 0 0; font-size: .82rem; }

/* ---- pachete si cumparare -------------------------------------------------- */
/* ALINIEREA CARDURILOR. Regula generala `.card + .card { margin-top: 1.2rem }`
   (mai sus in fisier) e scrisa pentru carduri STIVUITE. Intr-o grila, al doilea
   card e tot un frate adiacent, deci primea 19px de margine sus si statea mai
   jos decat primul — exact decalajul raportat. Il anulam doar aici, unde
   asezarea o face grila. */
.coin-wallets > .card + .card { margin-top: 0; }

/* ---- pachete ---------------------------------------------------------------
   Randul e DOUA blocuri (identitate | cumparare), nu cinci coloane egale.
   Cu cinci coloane pe un card lat, spatiul liber se imparea intre ele: numele
   ramanea lipit de marginea stanga, butoanele tocmai in dreapta, si un gol
   imens la mijloc — "aruncate din avion". Acum golul e unul singur, intre cele
   doua grupuri, iar fiecare grup isi tine bucatile lipite. */
.coin-packages { display: grid; gap: .6rem; }
.coin-package {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .8rem 1.2rem; padding: .8rem 1rem; border: 1px solid var(--line); border-radius: 8px;
}
.coin-package-main { display: flex; align-items: baseline; gap: .7rem; min-width: 0; }
.coin-package-buy  { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap; }
.coin-package-name { font-weight: 500; }
.coin-package-coins { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--ink-soft); }
.coin-package-price { font-weight: 600; font-variant-numeric: tabular-nums; font-size: 1.05rem; white-space: nowrap; }
.coin-package-save { font-size: .82rem; white-space: nowrap; color: var(--coin-green-ink); }
.coin-package--red .coin-package-save { color: var(--coin-red-ink); }
.coin-package-actions { display: flex; gap: .4rem; }

.coin-topup { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: .8rem 1rem; align-items: end; }
.coin-topup-actions { display: flex; gap: .5rem; align-items: center; }

/* ---- cum functioneaza fiecare portofel ------------------------------------
   Explicatia sta LANGA cifra pe care o explica. Intr-o sectiune de ajutor la
   subsol n-ar citi-o nimeni, si tocmai necitirea ei produce reclamatia
   ("de ce nu pot plati manual cu ce am cumparat?"). */
.coin-rules { list-style: none; margin: .9rem 0 .6rem; padding: 0; }
.coin-rules li {
  position: relative; padding-left: 1.1rem; margin-bottom: .3rem;
  font-size: .86rem; line-height: 1.45; color: var(--ink-soft);
}
.coin-rules li::before {
  content: ''; position: absolute; left: 0; top: .55em;
  width: .35rem; height: .35rem; border-radius: 50%;
}
.coin-card--green .coin-rules li::before { background: var(--coin-green); }
.coin-card--red   .coin-rules li::before { background: var(--coin-red); }

.coin-breakdown--single { grid-template-columns: 1fr; }

/* Regula de separare: singurul lucru de pe pagina care, neinteles, produce o
   reclamatie. De-aia are banda lui, cu ambele culori pe margine. */
.coin-separation {
  display: flex; flex-wrap: wrap; gap: .2rem .6rem; align-items: baseline;
  margin: 0 0 1.6rem; padding: .85rem 1.1rem; border-radius: 10px;
  background: linear-gradient(90deg, var(--coin-green-soft), var(--coin-red-soft));
  border: 1px solid var(--line);
  border-left: 4px solid var(--coin-green); border-right: 4px solid var(--coin-red);
  line-height: 1.5;
}
.coin-separation strong { color: var(--ink); }
/* Cifra "cat pot cheltui de fapt pe automat", pusa pe rand propriu la capatul
   benzii: e concluzia celor doua carduri, nu inca o propozitie din explicatie. */
.coin-separation-total {
  flex-basis: 100%; margin-top: .35rem; padding-top: .5rem;
  border-top: 1px solid var(--line); font-size: .92rem; color: var(--muted);
}
.coin-separation-total strong { font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.coin-topup-total { display: flex; flex-direction: column; }
#coin-topup-price { font-size: 1.5rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.coin-tiers { max-width: 22rem; }

/* ---- istoric --------------------------------------------------------------- */
.coin-badge {
  display: inline-block; padding: .05rem .45rem; border-radius: 999px;
  font-size: .74rem; font-weight: 600; border: 1px solid;
}
.coin-badge--green { border-color: var(--ok-line); background: var(--coin-green-soft); color: var(--coin-green-ink); }
.coin-badge--red   { border-color: var(--error-line); background: var(--coin-red-soft);   color: var(--coin-red-ink); }
.coin-source { display: block; font-size: .74rem; }
.data-table td.is-in  { color: var(--coin-green-ink); font-weight: 600; }
.data-table td.is-out { color: var(--ink); }

@media (max-width: 700px) {
  .coin-package { grid-template-columns: 1fr auto; row-gap: .4rem; }
  .coin-package-actions { grid-column: 1 / -1; }
}

/* ============================================================================
   MANUAL · PASUL 3 — cardurile de tuning si de optiuni, rearanjate
   2026-08-20 (raportat de Xprime: "scrisu se imprastie peste tot")
   ---------------------------------------------------------------------------
   Cardurile erau un singur RAND de grila: bifa · desen · titlu · pret. Cu patru
   coloane intr-o pista de ~200px, coloana titlului ramanea cu vreo 90px, iar
   "Stergere coduri de eroare (DTC off)" cobora pe cinci randuri in timp ce
   pretul, pe coloana lui, cobora pe trei — doua blocuri de text alunecate unul
   pe langa altul, la inaltimi diferite, in fiecare card altfel. De la departare
   nu se mai citea nici titlul, nici pretul: se citea zgomot.

   Acum sunt DOUA randuri, si asta rezolva problema din radacina, nu prin
   latimi mai mari: titlul primeste toata latimea cardului, pretul are randul
   lui dedesubt. Un card mai ingust inseamna de acum un titlu pe doua randuri,
   nu o coloana de trei litere.

   Cardurile raman de aceeasi inaltime pe rand (grila le intinde) si tot
   continutul se lipeste de sus, ca pretul sa nu pluteasca la mijloc.
   ========================================================================== */

/* ---- optiuni ------------------------------------------------------------- */
.mfs-options { grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); gap: .5rem; }

.mfs-option {
  grid-template-columns: auto auto 1fr;
  grid-template-areas:
    "check icon  title"
    "price price price";
  align-items: start;
  align-content: start;
  row-gap: .4rem;
  padding: .65rem .8rem .6rem;
}
.mfs-option > input[type="checkbox"] { grid-area: check; margin-top: .15rem; }
.mfs-option > .mfs-icon             { grid-area: icon; margin-top: .05rem; }
.mfs-option-title                   { grid-area: title; line-height: 1.35; overflow-wrap: anywhere; }

/* Pretul, pe randul lui: aliniat la dreapta, ca ochiul sa-l gaseasca in acelasi
   loc pe toate cardurile, si impins in josul cardului ca sa stea pe o linie cu
   preturile vecinilor chiar cand titlurile au inaltimi diferite. */
.mfs-option-price {
  grid-area: price; align-self: end; justify-self: end;
  text-align: right; white-space: nowrap; font-size: .82rem;
}
.mfs-option-price.is-quote { white-space: normal; }

/* ---- tipuri de tuning ---------------------------------------------------- */
.mfs-types { grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); }

.mfs-type {
  grid-template-columns: auto auto 1fr;
  /* Randul „desc" a disparat odata cu descrierea de sub titlu (2026-08-21):
     lasat gol, ar fi tinut in continuare un `row-gap` in plus si cardul ar fi
     ramas mai inalt fara motiv. */
  grid-template-areas:
    "check icon  title"
    "price price price";
  align-content: start;
  row-gap: .3rem;
  padding: .8rem .9rem .7rem;
}
.mfs-type > input[type="radio"] { grid-area: check; margin-top: .2rem; }
.mfs-type > .mfs-icon           { grid-area: icon; }
/* `display: contents` scoate invelisul din calcul, ca titlul si descrierea sa
   fie ele insele celule ale grilei cardului. Fara asta, cele doua ar fi stat
   intr-un bloc care nu se poate alinia pe randuri separate. */
.mfs-type-body                  { display: contents; }
.mfs-type-title                 { grid-area: title; line-height: 1.3; overflow-wrap: anywhere; }
.mfs-type-price {
  grid-area: price; align-self: end; justify-self: end;
  margin-top: .35rem; white-space: nowrap;
}

/* Pe ecran ingust cardurile ocupa toata latimea: acolo incape si varianta pe un
   singur rand, mai compacta, cu pretul in dreapta titlului. */
@media (max-width: 480px) {
  .mfs-options { grid-template-columns: 1fr; }
  .mfs-option {
    grid-template-columns: auto auto 1fr auto;
    grid-template-areas: "check icon title price";
    align-items: center;
    row-gap: 0;
  }
  .mfs-option-price { align-self: center; }
}

/* ============================================================================
   FISIERE TRIMISE — gaura alba din coloana de fisier
   2026-08-21 (raportat de Xprime: "am o gaura mare alba in tabelul fisiere
   trimise")
   ---------------------------------------------------------------------------
   Doua reguli vechi se bateau cap in cap, si amandoua erau puse cu motiv:

     .data-table .col-file { max-width: 26rem }      (ca numele lungi sa nu
                                                      lateasca tabelul)
     table.data-table      { width: 100% }           (ca tabelul sa umple cardul)

   `max-width` pe o celula NU ingusteaza COLOANA — coloana si-o alege algoritmul
   tabelului, iar cu latime 100% si celelalte coloane inguste, tot spatiul ramas
   se duce in coloana cu continutul cel mai lat, adica exact asta. Rezultatul:
   coloana lata de 800px si cutia celulei oprita la 416px, cu restul alb. Pe un
   monitor de 2560px, o gaura cat jumatate de ecran.

   Reparatia nu e "mai mult max-width": e sa nu mai lasam spatiul liber sa se
   adune intr-o singura coloana. Impartim latimea pe procente, iar taierea cu
   "…" se muta de pe celula pe textul din ea — care are voie sa umple coloana,
   oricat de lata iese.
   ========================================================================== */
.jobs-table { table-layout: fixed; }
.jobs-table th:nth-child(1) { width: 44%; }   /* fisier + identificare */
.jobs-table th:nth-child(2) { width: 15%; }   /* status */
.jobs-table th:nth-child(3) { width: 15%; }   /* data */
.jobs-table th:nth-child(4) { width: 10%; }   /* total */
.jobs-table th:nth-child(5) { width: 16%; }   /* actiune */

/* Celula nu mai are plafon propriu: umple coloana pe care i-o da tabelul. */
.jobs-table .col-file { max-width: none; }

/* Taierea se face pe TEXT, la latimea reala a coloanei. `min-width: 0` e
   obligatoriu pe un copil de flex: fara el, un nume lung refuza sa se
   micsoreze sub latimea lui naturala si iese din celula in loc sa fie taiat. */
.jobs-table .job-file,
.jobs-table .mono.job-file { max-width: 100%; min-width: 0; }
.jobs-table .job-identity  { max-width: 100%; }

/* Sub 900px procentele devin prea inguste pentru "Așteaptă plata" si pentru
   butoane; acolo tabelul se intoarce la latimi dupa continut si cardul il
   deruleaza orizontal, ca pana acum. */
@media (max-width: 900px) {
  .jobs-table { table-layout: auto; }
  .jobs-table th:nth-child(n) { width: auto; }
}

/* ============================================================================
   PRETURI, IN PANOUL CLIENTULUI — 2026-08-21 (cerinta Xprime)
   ========================================================================== */
.price-table .price-op { display: block; font-weight: 500; }
.price-table .price-code { display: block; font-size: .76rem; margin-top: .1rem; }
.price-table .price-amount { font-variant-numeric: tabular-nums; font-weight: 600; margin-right: .35rem; }
.price-table th:last-child, .price-table td:last-child { white-space: nowrap; }

/* Punctul colorat din titlul sectiunii: spune din ce portofel se plateste
   inainte de a citi coloana. Aceeasi pastila ca in restul portalului. */
.coin-dot--green { background: var(--coin-green); }
.coin-dot--red   { background: var(--coin-red); }
h2 > .coin-dot { display: inline-block; width: .6rem; height: .6rem; border-radius: 50%;
  margin-right: .45rem; vertical-align: baseline; }

/* ============================================================================
   RESTAURARE RELANSATA — 2026-08-21 (cerinta Xprime)
   ========================================================================== */
/* "Aplica modificari", sub butoanele de plata. Buton secundar cu explicatia
   alaturi: nu concureaza cu "Plateste", dar nici nu se ascunde. */
.rechain-form {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem;
  margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--line);
}
.rechain-form .hint { flex: 1 1 16rem; margin: 0; }

/* Costul adus de la restaurare, pe randul lui deasupra totalului. Discret, dar
   prezent: e o suma pe care clientul nu a bifat-o si trebuie sa stie de unde vine. */
.options-carried { color: var(--muted); font-size: .9rem; }
.options-carried .options-total-value { font-variant-numeric: tabular-nums; }

/* BALONUL DE AJUTOR — 2026-08-21 (cerinta Xprime)
   ---------------------------------------------------------------------------
   Descrierea tipului de lucrare statea sub eticheta, taiata la doua randuri. Pe
   textele lungi un rand ajungea de trei ori mai inalt decat vecinul lui, si
   tabelul — care e o lista de preturi, citita pe verticala cu ochiul pe coloana
   din dreapta — isi pierdea ritmul. Textul s-a mutat aici.

   Semnul e un `<button>`: intra singur in ordinea de tabulare, deci balonul se
   deschide si de la tastatura, nu doar cu mouse-ul. Pe telefon, unde nu exista
   hover, atingerea da focus — si tot se deschide.

   BALONUL E ANCORAT LA STANGA, nu centrat pe semn. Centrat arata mai frumos in
   mijlocul paginii si iese din card la primul rand aliniat la stanga — adica
   exact unde stau etichetele intr-un tabel de preturi. */
.price-op-row { display: flex; align-items: center; gap: .3rem; }

.tip { position: relative; display: inline-flex; line-height: 1; }

.tip-mark {
  width: 1.05rem; height: 1.05rem; padding: 0; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel); color: var(--ink-soft);
  font: inherit; font-size: .68rem; font-weight: 700; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: help; transition: border-color .15s ease, color .15s ease;
}
.tip-mark:hover, .tip-mark:focus-visible { border-color: var(--accent); color: var(--accent); }

.tip-bubble {
  position: absolute; bottom: calc(100% + .5rem); left: -.4rem;
  z-index: 40; width: max-content; max-width: min(24rem, 60vw);
  padding: .55rem .7rem; border-radius: var(--radius-s);
  background: var(--ink-surface); color: var(--onink);
  border: 1px solid var(--line);
  font-size: .82rem; font-weight: 400; line-height: 1.45; text-align: left;
  white-space: normal;             /* invinge `nowrap` mostenit din tabel */
  box-shadow: var(--shadow-soft);
  opacity: 0; visibility: hidden; transition: opacity .12s ease;
  pointer-events: none;            /* balonul nu fura mouse-ul de pe rand */
}
/* Varful, in culoarea balonului. Pe fundal opac unul singur e de ajuns. */
.tip-bubble::after {
  content: ""; position: absolute; top: 100%; left: .85rem;
  border: .32rem solid transparent; border-top-color: var(--ink-surface);
}
.tip-mark:hover + .tip-bubble,
.tip-mark:focus-visible + .tip-bubble { opacity: 1; visibility: visible; }

@media (max-width: 640px) { .tip-bubble { max-width: 78vw; } }

/* ============================================================================
   CONFIRMAREA DE DINAINTE DE PROCESARE — 2026-08-21 (cerinta Xprime)
   ---------------------------------------------------------------------------
   Doua propozitii si o bifa, intre total si butonul de trimitere. Incadrate, ca
   sa se citeasca drept "opreste-te o clipa", nu ca inca un rand de ajutor pe
   care ochiul il sare.

   Randul despre "nu se ia niciun coin" e cel care schimba comportamentul: fara
   el omul ezita la buton crezand ca plateste acum. De-aia are contrast propriu,
   nu culoarea notelor.
   ========================================================================== */
.start-gate {
  margin-top: 1rem; padding: .95rem 1.1rem; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel-2);
}
.start-gate-notice { margin: 0; color: var(--muted); line-height: 1.5; font-size: .9rem; }
.start-gate-free   { margin: .5rem 0 0; line-height: 1.5; font-size: .9rem; color: var(--ink); }
.start-gate-confirm {
  display: flex; align-items: flex-start; gap: .55rem;
  margin: .8rem 0 0; padding-top: .8rem; border-top: 1px solid var(--line);
  line-height: 1.5; font-size: .88rem;
}
.start-gate-confirm input { margin-top: .2rem; flex: none; }

/* ============================================================================
   AUTORIZAREA DEBITARII — 2026-08-21 (cerinta Xprime)
   ---------------------------------------------------------------------------
   Rezumatul de dinainte de a apasa: cat costa, din ce portofel se ia, si cu ce
   ramai. Trei intrebari pe care omul si le pune oricum; daca nu-i raspunzi
   aici, si le pune DUPA, cand raspunsul e o reclamatie.
   ========================================================================== */
.debit-summary {
  margin: 1rem 0 0; padding: .9rem 1.1rem; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel-2);
  display: grid; gap: .35rem;
}
.debit-summary > div { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.debit-summary dt { margin: 0; color: var(--muted); font-size: .9rem; }
.debit-summary dd { margin: 0; font-variant-numeric: tabular-nums; font-size: .9rem; }
.debit-summary .debit-total dt,
.debit-summary .debit-total dd { color: var(--ink); font-weight: 600; font-size: 1rem; }
.debit-summary .debit-after {
  margin-top: .35rem; padding-top: .5rem; border-top: 1px solid var(--line);
}
.debit-summary .coin-dot { display: inline-block; width: .5rem; height: .5rem; border-radius: 50%; margin-right: .35rem; }

/* Doua bife, una sub alta, cu aer intre ele: lipite, a doua se citeste ca o
   continuare a primei si trece neobservata — si tocmai ea e cea contestata. */
.terms-gate .opt + .opt { margin-top: .7rem; padding-top: .7rem; border-top: 1px solid var(--line); }
.terms-gate .opt { display: flex; align-items: flex-start; gap: .55rem; line-height: 1.5; font-size: .88rem; }
.terms-gate .opt input { margin-top: .2rem; flex: none; }

/* ===========================================================================
   DISPOZITIVE SI PASSKEY 2026-08-21 (cerinta Xprime)
   ===========================================================================
   Ecranul are de spus un singur lucru inainte de orice altceva: verdele merge
   sau nu merge pe dispozitivul asta. De aia starea e o caseta colorata in
   capul paginii, cu aceleasi trei tonuri folosite peste tot in aplicatie
   (--ok, --error, neutru), si nu un rand de text printre celelalte.
   ------------------------------------------------------------------------- */

.device-state { border-left: 4px solid var(--line); }
.device-state h2 { margin-top: 0; font-size: 1.1rem; }
.device-state p:last-child { margin-bottom: 0; }
.device-state--ok   { border-left-color: var(--ok);    background: var(--ok-bg); }
.device-state--bad  { border-left-color: var(--warn);      background: var(--warn-bg); }
.device-state--idle { border-left-color: var(--line);  background: var(--neutral-bg); }

.device-counts { margin: 1rem 0 1.4rem; }
/* Unitatea ("coins") sta langa cifra, dar mai mica si mai stinsa: cifra e
   informatia, unitatea doar o dezambiguizeaza. */
.device-counts .stat-unit { font-size: .6em; font-weight: 500; color: var(--ink-soft); }

/* Butonul si mesajul lui stau pe acelasi rand si se rup impreuna pe telefon:
   un mesaj de eroare aterizat departe de butonul care l-a produs nu se citeste
   ca raspuns la apasare. */
.device-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem; margin: .9rem 0 0; }

.passkey-msg { font-size: .9rem; color: var(--ink-soft); }
.passkey-msg--bad { color: var(--error); }

/* LATIMI FIXE, ca la tabelul de fisiere trimise (2026-08-20): fara
   `table-layout: fixed`, coloana cu numele — singura de lungime necunoscuta —
   imprastie datele si butonul in afara cardului. */
.device-table { width: 100%; border-collapse: collapse; table-layout: fixed; margin-bottom: 1rem; }
.device-table th,
.device-table td { padding: .55rem .5rem; text-align: left; border-bottom: 1px solid var(--line);
                   vertical-align: middle; overflow-wrap: anywhere; }
.device-table th { font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }
.device-table th:nth-child(1), .device-table td:nth-child(1) { width: 40%; }
.device-table th:nth-child(2), .device-table td:nth-child(2) { width: 18%; }
.device-table th:nth-child(3), .device-table td:nth-child(3) { width: 24%; }
.device-table th:nth-child(4), .device-table td:nth-child(4) { width: 18%; }
.device-table tr:last-child td { border-bottom: 0; }
.device-row-action { text-align: right; }

.badge-ok { display: inline-block; margin-left: .4rem; padding: .06rem .45rem; border-radius: 999px;
            font-size: .72rem; background: var(--ok-bg); color: var(--ok); border: 1px solid var(--ok-line); }

.device-add { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
              padding-top: .9rem; border-top: 1px solid var(--line); }
.device-add label { font-size: .85rem; color: var(--ink-soft); }
.device-add input { flex: 1 1 12rem; min-width: 0; padding: .5rem .65rem;
                    border: 1px solid var(--line); border-radius: var(--radius-s); font: inherit; }
/* Sfatul de sub rand ocupa toata latimea, ca sa nu inghesuie campul. */
.device-add .hint { flex-basis: 100%; margin: .2rem 0 0; }

.device-reset-price { font-weight: 600; margin-bottom: .3rem; }
.device-reset-price--free { color: var(--ok); }
.device-reset-short { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.device-reset-form { margin-top: 1rem; display: flex; flex-direction: column; gap: .7rem; align-items: flex-start; }
/* Bifa si textul ei: caseta sus, aliniata la primul rand, nu centrata pe un
   text de trei randuri. */
.device-reset-form .check { display: flex; gap: .55rem; align-items: flex-start; cursor: pointer; line-height: 1.5; }
.device-reset-form .check input { margin-top: .25rem; accent-color: var(--accent-btn); }

/* BANDA „DISPOZITIV NEVERIFICAT" — trebuie sa sara in ochi (Xprime, 10.09.2026).
   Ramane chihlimbar, nu rosu: nimic nu s-a stricat, doar nu se plateste din
   verde acum. Dar chihlimbarul la 13% pe fundal aproape negru nu se vedea —
   banda arata ca orice alt card, iar omul trecea pe langa ea si platea rosii
   fara sa inteleaga de ce.
   Ce o face vizibila, in ordinea in care o vede ochiul: o dunga groasa in stanga
   (singurul element de pe ecran cu 4px de chihlimbar plin), umplerea ridicata la
   o valoare care se distinge de card, si un semn de exclamare desenat langa
   titlu. Fara animatie si fara rosu — se citeste ca o conditie, nu ca o alarma. */
.device-gate {
  border: 1px solid var(--warn-line);
  border-left: 4px solid var(--warn);
  background: var(--warn-bg-strong);
  padding-left: 1.15rem;
}
.device-gate h2 {
  display: flex; align-items: center; gap: .5rem;
  margin-top: 0; font-size: 1.05rem; color: var(--warn-bright);
}
/* Semnul de exclamare e desenat din chenare, nu dintr-un font de pictograme si
   nici dintr-un emoji: se randeaza la fel in toate cele 20 de limbi si pe orice
   sistem, si preia culoarea titlului. */
.device-gate h2::before {
  content: "!"; flex: 0 0 auto;
  display: inline-grid; place-items: center;
  width: 1.35rem; height: 1.35rem;
  border: 1.5px solid currentColor; border-radius: 50%;
  font-size: .82rem; font-weight: 700; line-height: 1;
}
.device-gate p { margin-bottom: 0; }
/* Randul de actiuni: butoanele au acum aceeasi cutie (vezi blocul de butoane),
   deci se aliniaza singure. `align-items: center` ramane pentru mesajul de
   passkey, care e text si e mai scund decat butoanele. */
.device-gate .device-actions { margin-top: 1rem; }
/* In banda, butonul de verificare e ACTIUNEA — pe fundal chihlimbar, un contur
   cyan s-ar citi ca un link oarecare. Se umple din start. */
.device-gate .btn-primary {
  background: var(--warn); border-color: var(--warn); color: #10202b;
}
.device-gate .btn-primary:hover, .device-gate .btn-primary:focus-visible {
  background: var(--warn-bright); border-color: var(--warn-bright); color: #10202b;
}

@media (max-width: 640px) {
  .device-table th:nth-child(3), .device-table td:nth-child(3) { display: none; }
  .device-table th:nth-child(1), .device-table td:nth-child(1) { width: 52%; }
  .device-table th:nth-child(2), .device-table td:nth-child(2) { width: 24%; }
  .device-table th:nth-child(4), .device-table td:nth-child(4) { width: 24%; }
}

/* ===========================================================================
   ABONAMENT: STARE SI UPGRADE — 2026-08-21 (cerinta Xprime)
   ===========================================================================
   Pagina raspunde in ordinea in care clientul isi pune intrebarile: ce am, pana
   cand, si ce pot face mai departe. Starea e prima si e o caseta, nu un rand de
   text printre altele — fara abonament ea e tot ce conteaza pe pagina.
   ------------------------------------------------------------------------- */

.sub-state { border-left: 4px solid var(--line); }
.sub-state h2 { margin-top: 0; font-size: 1.1rem; }
.sub-state--active { border-left-color: var(--ok); background: var(--ok-bg); }
.sub-state--none   { border-left-color: var(--accent); background: var(--neutral-bg); }
.sub-state .btn-primary { margin-top: .9rem; }

.sub-tier-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem; margin: .2rem 0 .9rem; }
.sub-tier-badge { font-size: 1.15rem; font-weight: 600; }

/* Cifrele abonamentului, pe coloane. `auto-fit` in loc de un numar fix: cardul
   are trei sau patru date dupa cum stim sau nu pretul pe zi, si nu vrem o
   coloana goala cand nu-l stim. */
.sub-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
             gap: .8rem; margin: 0; }
.sub-facts dt { font-size: .78rem; text-transform: uppercase; letter-spacing: .04em;
                color: var(--ink-soft); margin-bottom: .15rem; }
/* Valoarea se rupe daca nu incape, in loc sa iasa din celula. Lista asta a fost
   facuta pentru cifre scurte (pret, data), dar o folosim si pentru adrese de
   email: 31 de caractere intr-o coloana de 9rem ies pe langa card la 390px.
   `min-width: 0` fiindca un element de grila refuza implicit sa se ingusteze
   sub latimea continutului sau. */
.sub-facts > * { min-width: 0; }
.sub-facts dd { margin: 0; font-size: 1.05rem; font-weight: 600; font-variant-numeric: tabular-nums;
                overflow-wrap: anywhere; }

/* SOCOTEALA DE UPGRADE. Se arata intreaga — pret, credit, de plata — fiindca
   "platesti 240 in loc de 300" fara sa se vada de unde vine diferenta e o cifra
   pe care clientul trebuie s-o creada pe cuvant. */
.sub-plan-buy--upgrade { text-align: right; }
.sub-upgrade-sums { display: grid; gap: .18rem; }
.sub-upgrade-line { display: flex; justify-content: space-between; gap: 1.2rem;
                    font-size: .88rem; color: var(--ink-soft); }
.sub-upgrade-line--credit { color: var(--ok); }
.sub-upgrade-line--total { border-top: 1px solid var(--line); margin-top: .25rem;
                           padding-top: .3rem; font-size: 1rem; font-weight: 600; color: var(--ink); }
.sub-plan-actions { display: flex; gap: .4rem; justify-content: flex-end; flex-wrap: wrap; }
/* Atentionarea cand clientul da mai multe zile decat primeste. Galben, nu rosu:
   nu e o eroare si nu e interzis — e o socoteala pe care trebuie s-o vada. */
.sub-upgrade-warn { margin: 0 0 .55rem; padding: .45rem .6rem; border-radius: var(--radius-s);
                    background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--warn-ink);
                    font-size: .82rem; line-height: 1.4; text-align: left; }
/* DE UNDE VINE CIFRA 2026-08-22. O notita sub linia de credit, nu o casuta de
   avertisment: nu e nici eroare, nici pericol — e explicatia unei cifre. Se
   aliniaza la stanga si curge pe cate randuri are nevoie, fiindca e o propozitie
   intreaga intr-o coloana de cifre aliniate la dreapta. */
.sub-upgrade-note { display: block; text-align: left; font-size: .78rem;
                    line-height: 1.4; color: var(--ink-soft); margin: .2rem 0 .1rem;
                    overflow-wrap: anywhere; }

.sub-plan-buy--upgrade .sub-plan-label { min-width: 0; display: block; margin-bottom: .3rem; }

/* Downgrade: se ARATA, stins, cu data de la care devine posibil. Un buton care
   lipseste fara explicatie e un tichet de suport. */
.sub-plan-buy--blocked { opacity: .62; text-align: right; }
.sub-plan-why { font-size: .82rem; text-align: right; }
.sub-upgrade-warn { text-align: left; }

@media (max-width: 560px) {
  /* Pe telefon totul se aliniaza la stanga: cifrele la dreapta pe o coloana de
     un card lat cat ecranul se citesc mai greu decat lipite de text. */
  .sub-plan-buy, .sub-plan-buy--upgrade, .sub-plan-buy--blocked,
  .sub-plan-label, .sub-plan-why { text-align: left; }
  .sub-plan-actions { justify-content: flex-start; }
}

/* Traducerile numelui de grup, in panoul de administrare (2026-08-21).
   Douazeci de randuri intr-un `<details>`: sunt de completat rar si nu au de ce
   sa impinga in jos setarile care se schimba des. Se deschide singur cand exista
   deja traduceri, ca sa nu para ca s-au pierdut. */
.group-i18n { margin: .8rem 0; border: 1px solid var(--line); border-radius: var(--radius-s); padding: .6rem .8rem; }
.group-i18n summary { cursor: pointer; font-weight: 600; }
.group-i18n table { margin-top: .7rem; }
.group-i18n input { width: 100%; }

/* ===========================================================================
   FISIERE RAPORTATE — doar panoul de administrare
   ===========================================================================
   Cardul din pagina clientului („Ne lasi fisierul?") a fost scos cu totul pe
   11.09.2026, impreuna cu `.report-card`, `.report-nothing-back` si
   `.report-form`, care nu mai au ce imbraca. Ce urmeaza tine lista din panou,
   unde raman rapoartele stranse pana atunci.
   ------------------------------------------------------------------------- */
.report-table td { vertical-align: top; }
.report-actions { text-align: right; white-space: nowrap; }
/* Randul de detalii nu are chenar propriu: e continuarea randului de deasupra,
   nu o intrare separata in lista. */
.report-detail-row > td { border-top: 0; padding-top: 0; }
.report-detail-row summary { cursor: pointer; font-size: .85rem; color: var(--ink-soft); }
.report-detail { padding: .6rem 0 .2rem; display: grid; gap: .5rem; }
.report-detail h4 { margin: .3rem 0 .1rem; font-size: .78rem; text-transform: uppercase;
                    letter-spacing: .04em; color: var(--ink-soft); }
.report-detail pre { margin: 0; padding: .5rem .6rem; background: var(--neutral-bg);
                     border-radius: var(--radius-s); font-size: .8rem; line-height: 1.45;
                     white-space: pre-wrap; word-break: break-word; max-height: 16rem; overflow: auto; }
.report-status-form { display: grid; gap: .35rem; max-width: 34rem; }
.report-status-form textarea { width: 100%; padding: .45rem .55rem; border: 1px solid var(--line);
                               border-radius: var(--radius-s); font: inherit; resize: vertical; }
.report-status-actions { display: flex; gap: .4rem; align-items: center; }
.report-delete-form { margin-top: .4rem; }
.report-row--done { opacity: .6; }
.report-kind--identify { background: var(--warn-bg); color: var(--warn-ink); }
.report-kind--process  { background: var(--error-bg); color: var(--error); }

/* Bara de salvare in bloc, sub o lista de preturi din administrare (2026-08-21).
   Sta lipita de tabel, nu la capatul cardului: butonul care salveaza randurile
   trebuie sa fie langa randuri, nu dupa doua paragrafe de explicatii. */
.bulk-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem;
            margin: .9rem 0 .2rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.bulk-bar .btn-primary { margin-top: 0; }
.bulk-bar .hint { flex: 1 1 16rem; margin: 0; }


/* ============================================================================
   COMPOZITIILE NOI — 2026-08-21
   ============================================================================
   Vin din propunerea „terminal" si sunt ce a placut la machete: inelul de
   incarcare care lumineaza, fasiile despartite cu o linie de un pixel,
   pipeline-ul de procesare.

   Scrise aici, in app.css, NU intr-o a doua foaie de stil, si NU pe
   `body:not(.admin)`: o singura paleta, un singur limbaj vizual, si pentru
   client si pentru admin. Toate culorile ies din tokenurile de la `:root`.
   ========================================================================== */

/* --- antetul public: lipit sus, cu fundal cetos ---------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(7,16,25,0.92);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 12px 34px rgba(0,0,0,.24);
  backdrop-filter: blur(16px);
}
.brand { font-style: italic; letter-spacing: -.025em; }
.brand-dash { color: var(--accent-2); }

/* --- banda principala ----------------------------------------------------- */
.terminal-hero {
  position: relative; overflow: hidden; isolation: isolate;
  /* Inaltimea e ceruta, altfel banda ar fi cat textul si din masina s-ar vedea
     o dunga. Dar nu atat cat sa umple singura un laptop de 768px: la
     `clamp(42rem, 73vh, 54rem)` — cat avea propunerea — cei 3 pasi si cifrele
     de dedesubt cadeau integral sub linia de vizibilitate. */
  min-height: clamp(32rem, 60vh, 44rem);
  border: 1px solid var(--line); border-radius: 18px;
  background-color: var(--panel);
  background-image:
    linear-gradient(90deg, rgba(5,12,18,.98) 0%, rgba(5,12,18,.89) 33%,
                    rgba(5,12,18,.28) 67%, rgba(5,12,18,.12) 100%),
    url("/assets/img/bg-home.jpg");
  background-size: cover; background-position: center;
  box-shadow: var(--shadow);
}
.terminal-hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(circle at 45% 50%,
              rgba(32,214,239,0.13), transparent 27%);
}
.terminal-hero-grid {
  position: relative; z-index: 1; display: grid;
  /* Trei coloane, iar a treia ramane goala INTENTIONAT: acolo se vede masina.
     Cu doua coloane, inelul se lipeste de marginea din dreapta si acopera
     exact partea din fotografie pentru care am ales fotografia. */
  grid-template-columns: minmax(19rem, .9fr) minmax(23rem, 1fr) minmax(9rem, .55fr);
  align-items: center; min-height: inherit;
  gap: clamp(1.25rem, 3vw, 4rem); padding: clamp(2rem, 4.5vw, 4.5rem);
}
.terminal-copy { max-width: 38rem; }
.terminal-kicker {
  margin: 0 0 .8rem; color: var(--accent-2);
  font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .22em;
}
/* Latimea titlului: propunerea avea `11ch`, adica o presupunere despre engleza.
   Situl are 20 de limbi, iar in germana sau finlandeza un singur cuvant trece
   de 11 caractere si iese din coloana. Plafon mai larg + rupere controlata. */
.terminal-copy h1 {
  margin: 0; color: var(--ink); font-weight: 700;
  font-size: clamp(2.1rem, 3.6vw, 4.2rem); line-height: 1.05; letter-spacing: -.035em;
  max-width: 14ch; overflow-wrap: break-word; hyphens: auto;
}
.terminal-lead {
  max-width: 34rem; margin: 1.35rem 0 0; color: var(--ink-soft);
  font-size: clamp(1rem, 1.2vw, 1.15rem); line-height: 1.7;
}
.terminal-promise {
  display: flex; gap: .72rem; align-items: flex-start; max-width: 33rem;
  margin-top: 1.8rem; padding-top: 1.25rem;
  border-top: 1px solid var(--line); color: var(--muted); font-size: .88rem;
}
.terminal-promise-mark {
  flex: none; display: inline-grid; place-items: center;
  width: 1.45rem; height: 1.45rem; border-radius: 50%;
  color: var(--accent-ink); background: var(--accent-2);
  box-shadow: 0 0 18px rgba(87,231,155,0.45);
}
.terminal-upload-slot { grid-column: 2; min-width: 0; }

/* --- inelul de incarcare -------------------------------------------------- */
.terminal-upload { width: min(100%, 32rem); margin-inline: auto;
                   display: flex; flex-direction: column; align-items: center; }
/* Input-ul ramane in pagina (accesibil cu tastatura), doar ca nu se vede. */
.terminal-file-input {
  position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.terminal-ring {
  position: relative; display: grid; place-items: center; isolation: isolate;
  width: clamp(19rem, 29vw, 26rem); aspect-ratio: 1;
  padding: 5px; border: 5px solid transparent; border-radius: 50%; cursor: pointer;
  background: linear-gradient(var(--panel), var(--panel)) padding-box,
              conic-gradient(from 218deg, var(--accent) 0deg, #1fb8ff 92deg,
                             var(--accent-2) 225deg, var(--accent) 360deg) border-box;
  box-shadow: 0 0 9px rgba(32,214,239,0.95),
              0 0 27px rgba(32,214,239,0.68),
              0 0 52px rgba(87,231,155,0.36),
              inset 0 0 40px rgba(16,151,187,.08);
  transition: transform .22s ease, box-shadow .22s ease, filter .22s ease;
}
/* ::before e halo-ul (aceeasi banda, neclara). ::after REASAZA interiorul
   inchis peste el — fara asta lumina umple mijlocul si textul dinauntru devine
   ilizibil. `isolation: isolate` face ca `z-index: -1` sa se aseze peste
   fundalul propriu al elementului, nu sub el. */
.terminal-ring::before {
  content: ""; position: absolute; inset: -10px; z-index: -1; border-radius: inherit;
  background: conic-gradient(from 218deg, var(--accent), #22baff, var(--accent-2), var(--accent));
  filter: blur(19px); opacity: .82;
}
.terminal-ring::after {
  content: ""; position: absolute; inset: 7px; z-index: -1; border-radius: inherit;
  background: radial-gradient(circle at 50% 42%, rgba(20,66,82,.26), transparent 43%),
              linear-gradient(145deg, rgba(11,24,34,.98), rgba(4,11,17,.99));
  border: 1px solid rgba(167,214,231,.09);
}
.terminal-ring:hover, .terminal-ring.is-drag, .terminal-ring.has-file {
  transform: translateY(-3px) scale(1.012); filter: saturate(1.12);
  box-shadow: 0 0 11px var(--accent),
              0 0 38px rgba(32,214,239,0.82),
              0 0 72px rgba(87,231,155,0.5),
              inset 0 0 45px rgba(16,151,187,.13);
}
.terminal-file-input:focus-visible + .terminal-ring { outline: 2px solid var(--ink); outline-offset: 8px; }
.terminal-ring-content {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 73%; color: var(--ink); text-align: center; line-height: 1.42;
}
.terminal-file-icon { color: var(--accent); margin-bottom: 1rem;
  filter: drop-shadow(0 0 10px rgba(32,214,239,0.46)); }
.terminal-ring-content strong { font-size: clamp(1rem, 1.5vw, 1.25rem); }
.terminal-upload-action { margin-top: .3rem; color: var(--ink-soft); font-size: .85rem; }
.terminal-upload-limit { margin-top: .65rem; color: var(--muted); font-size: .74rem; }
.terminal-file-name {
  display: block; max-width: 100%; min-height: 1.45rem; margin-top: .65rem;
  overflow: hidden; color: var(--accent-2); font-size: .78rem;
  text-overflow: ellipsis; white-space: nowrap;
}
/* Declaratia de proprietate are greutate legala: nu o lasam la 0.72rem. */
.terminal-own {
  display: flex; align-items: flex-start; gap: .55rem; width: min(100%, 29rem);
  margin: 1.55rem auto 0; color: var(--ink-soft);
  font-size: .8rem; font-weight: 400; line-height: 1.55;
}
.terminal-own input { flex: none; margin-top: .2rem; }
.terminal-own a { color: var(--accent-dark); }
.terminal-submit { min-width: 13rem; margin-top: 1rem; }
.terminal-remaining { margin: .8rem 0 0; color: var(--muted); font-size: .78rem; text-align: center; }

/* varianta „poarta": acelasi cerc, dar inchis */
.terminal-upload--gate .terminal-ring { cursor: default; }
.terminal-upload--gate .terminal-ring-content { width: 75%; }
.terminal-upload--gate h2 { margin: .75rem 0 0; color: var(--ink); }
.terminal-upload--gate p { margin: 0; color: var(--ink-soft); font-size: .85rem; }
.terminal-lock {
  width: 2rem; height: 1.6rem; border: 2px solid var(--accent-2); border-radius: 5px;
  box-shadow: 0 0 18px rgba(87,231,155,0.35);
}
.terminal-lock::before {
  content: ""; display: block; width: 1rem; height: .8rem; margin: -.9rem auto 0;
  border: 2px solid var(--accent-2); border-bottom: 0; border-radius: .8rem .8rem 0 0;
}
/* EXPLICATIA PORTII, SUB CERC — 2026-08-25.
   Cercul are dimensiune fixa (`aspect-ratio: 1`) si nu creste dupa continut,
   deci orice fraza mai lunga de doua randuri iesea peste inel. Se vedea la
   toate cele trei porti, in romana si in germana, si `overflow_all.js` nu o
   prindea: textul depasea un element decorativ, nu pagina.
   Acum in cerc raman lacatul si titlul; explicatia sta aici, cu latimea de
   care are nevoie, si merge la fel in toate cele 20 de limbi. */
.terminal-gate-text {
  max-width: 34rem; margin: 1.25rem auto 0; padding: 0 .5rem;
  color: var(--ink-soft); font-size: .9rem; line-height: 1.6; text-align: center;
}
.terminal-gate-actions { display: flex; gap: .65rem; justify-content: center; flex-wrap: wrap; }
.terminal-gate-actions .btn-primary, .terminal-gate-actions .btn-secondary { margin-top: 1.35rem; }

/* --- fasia celor 3 pasi ---------------------------------------------------
   `gap: 1px` peste un fundal de culoarea liniei: liniile despartitoare ies
   exact de un pixel, fara borduri duble intre casute. */
.terminal-flow {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
  margin: 1.5rem 0; overflow: hidden;
  border: 1px solid var(--line); border-radius: 14px; background: var(--line);
}
.terminal-flow-step {
  display: grid; grid-template-columns: auto 1fr; gap: 1rem; min-width: 0;
  padding: 1.5rem; background: var(--panel);
}
.terminal-flow-no { color: var(--accent); font-size: .72rem; font-weight: 700; letter-spacing: .12em; }
.terminal-flow-step h2 { margin: 0 0 .3rem; color: var(--ink); font-size: .98rem; }
.terminal-flow-step p { margin: 0; color: var(--ink-soft); font-size: .82rem; line-height: 1.6; }

/* aceleasi linii de un pixel si la cele 3 cifre */
.stat-tiles { gap: 1px; border: 1px solid var(--line); border-radius: 14px;
              overflow: hidden; background: var(--line); }
.stat-tile { border: 0; border-radius: 0; background: var(--panel); box-shadow: none; }
.stat-tile-icon { color: var(--accent-2); }

/* --- pagina /detect -------------------------------------------------------- */
.detect-terminal-page {
  position: relative; overflow: hidden; min-height: 36rem;
  padding: clamp(2rem, 5vw, 4.5rem);
  border: 1px solid var(--line); border-radius: 18px;
  background: linear-gradient(90deg, rgba(5,12,18,.97), rgba(5,12,18,.55) 60%, rgba(5,12,18,.3)),
              url("/assets/img/bg-home.jpg") center / cover;
}
.detect-terminal-copy { max-width: 36rem; }
.detect-terminal-copy h1 { margin: 0; color: var(--ink); font-size: clamp(2rem, 3.6vw, 3.6rem); }
.detect-terminal-stage { margin: -3rem auto 0; width: fit-content; max-width: 100%; }
.detect-manual-entry { max-width: 35rem; margin: 2rem auto 0; }
.terminal-flow--detect { margin-top: 1.5rem; }

/* --- panoul clientului ----------------------------------------------------- */
.panel-dashboard-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 1rem; margin-bottom: 1.3rem;
}
.panel-dashboard-head h1 { margin: 0; color: var(--ink); font-size: clamp(1.8rem, 3vw, 2.6rem); }
.terminal-dashboard-stats { grid-template-columns: repeat(4, minmax(10rem, 1fr)); gap: .75rem; }
.terminal-dashboard-stats .stat {
  min-height: 8rem; padding: 1.15rem 1.25rem;
  border: 1px solid var(--line); border-radius: 11px;
  background: var(--panel); box-shadow: var(--shadow-soft);
}
.terminal-dashboard-stats .stat-value { color: var(--accent); font-size: 1.75rem; }
.terminal-dashboard-stats .status-ok { color: var(--ok); }
/* Casuta cu portofelele: doua sume si doua pastile pe acelasi rand. Fara
   `flex-wrap` controlat, pastila rosie cade singura pe randul urmator si arata
   ca o greseala de aliniere. */
.terminal-wallet-stat .stat-value {
  display: flex; align-items: center; flex-wrap: wrap; gap: .25rem .45rem;
  font-size: 1.25rem; line-height: 1.2;
}
.terminal-wallet-stat .stat-second { color: var(--coin-red-ink); }
.terminal-wallet-stat .coin-badge { font-size: .68rem; padding: .1rem .45rem; }

.terminal-dashboard-workspace {
  display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(22rem, .75fr);
  gap: 1.25rem; align-items: start;
}
.terminal-section-label {
  display: block; color: var(--accent);
  font-size: .68rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
}
.terminal-dashboard-workspace .section-head h2, .terminal-upload-heading h2 {
  margin: .15rem 0 0; color: var(--ink);
}
.terminal-table-card { padding: .55rem 1rem; }
/* Mesajul „nu ai fisiere inca" e o propozitie, nu o valoare de tabel: are voie
   sa se rupa pe randuri. `.data-table td` tine `nowrap` pentru cifre. */
.terminal-table-card .data-table td[colspan] { white-space: normal; }
.terminal-dashboard-upload {
  padding: 1.2rem 1.25rem 1.35rem; border: 1px solid var(--line); border-radius: 14px;
  background: radial-gradient(circle at 50% 25%,
              rgba(32,214,239,0.1), transparent 32%),
              var(--panel);
  box-shadow: var(--shadow-soft);
}
.terminal-dashboard-upload .terminal-upload { width: 100%; }
.terminal-dashboard-upload .terminal-ring { width: min(100%, 19rem); }
.terminal-dashboard-upload .terminal-file-icon { width: 50px; height: 50px; margin-bottom: .55rem; }
.terminal-dashboard-upload .terminal-ring-content strong { font-size: 1rem; }
.terminal-dashboard-upload .terminal-submit { min-width: 11rem; }
.terminal-support-link {
  display: flex; justify-content: space-between; gap: 1rem;
  margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--line);
  color: var(--muted); font-size: .78rem;
}
.terminal-support-link a { flex: none; color: var(--accent-2); text-decoration: none; }

/* --- starea de procesare, in direct ---------------------------------------
   Fara procent inventat: arcul si pipeline-ul spun etapa reala, citita din
   `$stage`. Atat stie serverul, atat aratam. */
.processing-live-card {
  position: relative; overflow: hidden; min-height: 34rem; padding: 0;
  background: linear-gradient(90deg, rgba(7,16,24,.98) 0%, rgba(7,16,24,.92) 45%,
                              rgba(7,16,24,.4) 100%),
              url("/assets/img/bg-home.jpg") center right / cover;
}
.processing-live-head {
  position: relative; z-index: 1; display: flex; align-items: center;
  justify-content: space-between; gap: 1rem; padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--line); background: rgba(4,10,15,.5);
}
.processing-file-name { display: block; margin-top: .15rem; color: var(--ink); font-size: 1.15rem; }
.processing-ref { color: var(--muted); font-size: .78rem; }
.processing-live-main {
  position: relative; z-index: 1; display: grid;
  grid-template-columns: minmax(20rem, .9fr) minmax(26rem, 1.25fr);
  gap: clamp(2rem, 5vw, 5rem); align-items: center;
  min-height: 28rem; padding: clamp(2rem, 4vw, 4rem);
}
.processing-glow-ring {
  position: relative; display: grid; place-items: center; isolation: isolate;
  width: min(100%, 23rem); aspect-ratio: 1; margin-inline: auto;
  border: 8px solid transparent; border-radius: 50%;
  background: linear-gradient(var(--panel), var(--panel)) padding-box,
              conic-gradient(from 205deg, #1bbcff 0 45%, #2fe3ef 63%,
                             var(--accent-2) 84%,
                             rgba(87,231,155,0.16) 84% 100%) border-box;
  box-shadow: 0 0 10px rgba(32,214,239,0.96),
              0 0 35px rgba(32,214,239,0.78),
              0 0 75px rgba(87,231,155,0.46),
              inset 0 0 45px rgba(23,177,211,.13);
}
.processing-live-card--identifying .processing-glow-ring {
  background: linear-gradient(var(--panel), var(--panel)) padding-box,
              conic-gradient(from 205deg, #1bbcff 0 28%, #2fe3ef 44%,
                             rgba(87,231,155,0.15) 44% 100%) border-box;
}
.processing-glow-ring::before {
  content: ""; position: absolute; inset: -12px; z-index: -1; border-radius: inherit;
  background: conic-gradient(from 205deg, #18c7ff, #29d8ef, var(--accent-2),
                             rgba(32,214,239,0.2));
  filter: blur(22px); opacity: .86;
}
/* Perechea lui ::before. Lipsea in propunere, si de-aia lumina umplea cercul. */
.processing-glow-ring::after {
  content: ""; position: absolute; inset: 8px; z-index: -1; border-radius: inherit;
  background: radial-gradient(circle at 50% 42%, rgba(20,66,82,.26), transparent 43%),
              linear-gradient(145deg, rgba(11,24,34,.98), rgba(4,11,17,.99));
  border: 1px solid rgba(167,214,231,.09);
}
.processing-glow-content { width: 72%; text-align: center; }
.processing-live-state { color: var(--accent-2); font-size: .72rem; font-weight: 700;
                         letter-spacing: .12em; text-transform: uppercase; }
.processing-glow-content h2 { margin: .65rem 0 .55rem; color: var(--ink); font-size: 1.45rem; }
.processing-glow-content p { margin: 0; color: var(--ink-soft); font-size: .84rem; }
.processing-queue { margin-top: .7rem; color: var(--accent-dark); }
.processing-glow-ring .spinner {
  position: absolute; inset: -8px; width: auto; height: auto; margin: 0;
  border: 0; border-radius: 50%; box-shadow: none;
  animation: terminal-pulse 2.2s ease-in-out infinite;
}
@keyframes terminal-pulse {
  0%, 100% { box-shadow: 0 0 5px rgba(32,214,239,0.45); opacity: .72; }
  50% { box-shadow: 0 0 34px rgba(32,214,239,0.95),
                    0 0 68px rgba(87,231,155,0.42); opacity: 1; }
}
.processing-pipeline {
  position: relative; display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1rem; margin: 0; padding: 0; list-style: none;
}
.processing-pipeline::before {
  content: ""; position: absolute; top: 1.6rem; left: 9%; right: 9%; height: 1px;
  background: linear-gradient(90deg, var(--accent-2), var(--accent) 55%, var(--line) 55%);
}
.processing-pipeline li { position: relative; z-index: 1; min-width: 0;
                          text-align: center; color: var(--muted); }
.processing-step-icon {
  display: grid; place-items: center; width: 3.2rem; height: 3.2rem;
  margin: 0 auto .75rem; border: 1px solid var(--line-strong); border-radius: 50%;
  background: var(--panel); color: var(--muted); font-size: .7rem;
  box-shadow: 0 0 0 7px rgba(7,16,24,.88);
}
.processing-pipeline strong { display: block; font-size: .78rem; line-height: 1.35; }
.processing-pipeline .is-done { color: var(--ok); }
.processing-pipeline .is-done .processing-step-icon {
  border-color: var(--ok); color: var(--accent-ink); background: var(--ok);
  box-shadow: 0 0 0 7px rgba(7,16,24,.88), 0 0 22px rgba(84,233,154,0.38);
}
.processing-pipeline .is-current { color: var(--ink); }
.processing-pipeline .is-current .processing-step-icon {
  border: 2px solid var(--accent); color: var(--accent);
  box-shadow: 0 0 0 7px rgba(7,16,24,.88), 0 0 18px var(--accent),
              0 0 34px rgba(87,231,155,0.35);
}
.processing-live-card #wait-timeout {
  position: relative; z-index: 2; margin: 0 2rem 2rem; padding: 1rem;
  border: 1px solid var(--line); border-radius: 10px; background: rgba(7,16,24,.92);
}

/* Iesirea din fundatura de pe pagina jobului: butonul si explicatia lui pe
   acelasi rand, cu explicatia dedesubt pe ecran ingust. */
/* Cardul de refuz la descarcare: o propozitie si trei butoane. Fara limita de
   latime, propozitia se intinde pe tot ecranul si se citeste ca un banner, nu
   ca un raspuns. */
.download-blocked { max-width: 44rem; }

/* Randul „ultima curatenie" din Admin -> Storage (2026-08-22). Cand e o
   avertizare, notita ocupa un rand intreg si nu se lipeste de butoane. */
.storage-lastrun { margin: .8rem 0 .4rem; }
.storage-lastrun .notice { display: block; margin: 0; }

.dead-end-actions { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
                    margin-top: .9rem; }
.dead-end-actions .btn-primary { margin-top: 0; }
.dead-end-actions .hint { flex: 1 1 16rem; min-width: 0; }

/* TABELUL COMPACT DE PE DASHBOARD: COLOANELE DIN DREAPTA ISI PRIMESC LATIMEA
   2026-09-11 (raportat de Xprime cu o captura: „Choose options se lipeste de
   chenarul din dreapta").

   CAUZA, masurata in cardul din captura, lat de 616px: coloana de actiuni era
   pironita la `width: 7.5rem`, adica 120px, din care raman 100,8px dupa
   marginile celulei. Butonul „Choose options" masoara 132,4px si
   „Pay & download" 136,3px. Cu `table-layout: fixed`, coloana NU creste dupa
   continut — deci butonul iesea 25-29px in afara celulei SI a cardului, cardul
   capata bara de derulare orizontala, iar textul ajungea peste chenar. Restul
   spatiului se ducea in coloana fisierului, care e `auto` si ia tot ce ramane.

   REPARAT prin latimile celor doua coloane din dreapta, alese dupa cea mai lunga
   eticheta din cele douazeci de limbi — nu dupa engleza: maghiara are
   „Lehetőségek választása" si „Bezahlen & herunterladen" e germana. Coloana
   fisierului ramane `auto` si primeste restul, cu numele taiat cu trei puncte ca
   pana acum. Insigna de stare are voie sa se rupa pe doua randuri in tabelul
   compact — o pastila pe doua randuri e mai buna decat una care iese din
   coloana, si e exact ce face deja regula de pe ecrane mici.

   Masurat dupa, pe latimile de card posibile (de la ~560px in sus, sub care
   regula de ecran mic ascunde oricum coloana a treia), in engleza, maghiara,
   greaca si ucraineana: nimic nu iese din celula, nimic nu iese din card,
   nicio derulare orizontala. */
.jobs-table--compact { table-layout: fixed; }
.jobs-table--compact .col-file { width: auto; }
.jobs-table--compact .col-file .job-file { max-width: 100%; }
.jobs-table--compact th:nth-child(2),
.jobs-table--compact td:nth-child(2) { width: 11rem; }
/* Latimea se declara pe CAPUL de tabel, nu doar pe celula: cu
   `table-layout: fixed`, coloanele se masoara din primul rand, iar `<th></th>`-ul
   coloanei de actiuni n-are clasa `.actions`. Fara randul asta, latimea ceruta
   mai jos nu ajungea niciodata la coloana — exact scaparea din care a pornit
   totul. */
.jobs-table--compact th:nth-child(3),
.jobs-table--compact .actions { width: 8rem; }
.jobs-table--compact .actions { text-align: right; }
/* Plasa: orice eticheta viitoare mai lunga decat coloana se taie cu trei
   puncte in loc sa iasa peste chenar. Nu ar trebui sa se intample — verbul
   scurt incape in toate cele 20 de limbi — dar o traducere adaugata maine nu
   are cum sa strice randul. */
.jobs-table--compact .actions .btn-small {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.jobs-table--compact .ui-badge { white-space: normal; }
.jobs-table--compact td, .jobs-table--compact th { padding-inline: .6rem; }

/* Anuntul „nicio metoda de plata pornita": sta la fel in toate cele trei
   pagini de plata, cu link-ul de contact pe acelasi rand. */
.no-payment-notice { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
                     margin: .8rem 0 1.2rem; }
.no-payment-notice a { color: inherit; text-decoration: underline; }

/* Tabelul de diagnostic al metodelor de plata: strans, ca sa nu para o lista
   de date, ci un raspuns la o singura intrebare. */
.gateway-state { margin-top: 1rem; max-width: 46rem; }
.gateway-state td, .gateway-state th { padding-block: .45rem; }

/* --- meniul din stanga -----------------------------------------------------
   Elementul activ era o pastila plina de cian: pe un meniu intreg, o suprafata
   atat de tare trage ochiul mai mult decat continutul paginii. Aceeasi
   informatie, spusa mai in soapta: un val de culoare si o dunga in stanga. */
.admin-side {
  background: linear-gradient(180deg, #071018, #050b11);
  border-right: 1px solid var(--line);
  box-shadow: 12px 0 34px rgba(0,0,0,.18);
}
.admin-nav-link { color: var(--ink-soft); }
.admin-nav-link:hover { color: var(--ink); background: rgba(32,214,239,0.08); }
.admin-nav-link.is-active {
  color: var(--ink);
  background: linear-gradient(90deg, rgba(32,214,239,0.19), rgba(87,231,155,0.07));
  border-left: 2px solid var(--accent);
  box-shadow: inset 12px 0 24px rgba(26,188,216,0.05), 0 0 20px rgba(37,201,227,0.06);
}
.admin-nav-title { color: var(--muted); }

/* --- bara laterala pe ecrane joase ----------------------------------------
   Pe un laptop de 768px inaltime, meniul din stanga capata o bara de derulare
   permanenta. Strangem doar ritmul vertical; scrisul ramane la fel. */
/* Pe laptopurile scunde (1366x768 e inca foarte raspandit) inelul mananca tot
   ecranul si fasia cu cei 3 pasi nu se mai ghiceste sub el. Micsoram inelul,
   nu textul: cercul ramane obiectul principal, dar lasa ceva sa se vada. */
@media (min-width: 901px) and (max-height: 820px) {
  .terminal-hero { min-height: clamp(26rem, 76vh, 34rem); }
  .terminal-ring { width: clamp(15rem, 23vw, 20rem); }
  .terminal-hero-grid { padding-block: clamp(1.4rem, 3vw, 2.4rem); }
}

@media (min-width: 901px) and (max-height: 850px) {
  .admin-side { padding-top: .9rem; padding-bottom: .75rem; }
  .admin-brand { margin-bottom: .85rem; }
  .admin-nav-group { margin-bottom: .62rem; }
  .admin-nav-title { margin-bottom: .15rem; }
  .admin-nav-link { padding: .38rem .65rem; }
  .admin-side-foot { margin-top: .35rem; padding-top: .5rem; }
}

@media (max-width: 1180px) {
  .terminal-hero-grid { grid-template-columns: minmax(18rem, .8fr) minmax(21rem, 1fr); }
  .terminal-upload-slot { grid-column: 2; }
  .terminal-dashboard-stats { grid-template-columns: repeat(2, minmax(10rem, 1fr)); }
  .terminal-dashboard-workspace { grid-template-columns: 1fr; }
  .terminal-dashboard-upload { max-width: 38rem; }
  .processing-live-main { grid-template-columns: 1fr; }
  .processing-glow-ring { width: min(100%, 20rem); }
}
@media (max-width: 820px) {
  .site-header { position: relative; }
  .terminal-hero { background-position: 65% center; }
  .terminal-hero-grid { grid-template-columns: 1fr; padding: 2rem 1.35rem 3rem; }
  .terminal-upload-slot { grid-column: 1; }
  .terminal-copy { max-width: 100%; text-align: center; }
  .terminal-copy h1 { max-width: 18ch; margin-inline: auto; }
  .terminal-lead { margin-inline: auto; }
  .terminal-promise { margin-inline: auto; text-align: left; }
  .terminal-ring { width: min(82vw, 22rem); }
  .terminal-flow { grid-template-columns: 1fr; }
  .detect-terminal-stage { margin-top: 2rem; }
  .processing-live-main { padding: 2rem 1rem 3rem; }
  .processing-pipeline { grid-template-columns: repeat(2, 1fr); row-gap: 1.5rem; }
  .processing-pipeline::before { display: none; }
}
@media (max-width: 620px) {
  .terminal-hero { min-height: auto; border-radius: 12px; }
  .terminal-hero-grid { padding-inline: .85rem; }
  .terminal-copy h1 { font-size: 2.15rem; }
  .terminal-ring { width: min(86vw, 20rem); }
  .terminal-flow-step { padding: 1.15rem; }
  .stat-tiles { grid-template-columns: 1fr; }
  .terminal-dashboard-stats { grid-template-columns: 1fr; }
  .panel-dashboard-head { align-items: flex-start; flex-direction: column; }
  .processing-live-head { align-items: flex-start; flex-direction: column; }
  .processing-glow-ring { width: min(82vw, 18rem); }
  .processing-glow-content h2 { font-size: 1.12rem; }
}
@media (prefers-reduced-motion: reduce) {
  .processing-glow-ring .spinner { animation: none; }
  .terminal-ring { transition: none; }
}


/* ============================================================================
   RAPORTUL UNIFICAT — 2026-08-22 (cerinta Xprime)
   Un client, un grup, un plan sau tot site-ul citesc pe aceeasi pagina, deci si
   stilurile sunt unele singure. Regula de aur aici: NIMIC nu iese din chenar si
   nimic nu se taie in tacere — un raport care ascunde o cifra e mai rau decat
   unul urat. Tabelele largi isi capata propria bara de scroll (`.table-card`).
   ========================================================================== */

.rep-head {
  display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between;
  gap: 1rem; margin-bottom: 1rem;
}
.rep-title { margin: 0; overflow-wrap: anywhere; }
.rep-head-links { display: flex; flex-wrap: wrap; gap: .5rem; }
.rep-jump { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem; }
.rep-crosslink { margin-bottom: 1rem; }

.rep-period { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.rep-period-presets { display: flex; flex-wrap: wrap; gap: .35rem; }
.rep-period-presets .is-active { border-color: var(--accent); color: var(--accent); }
.rep-period-label { margin-left: auto; white-space: nowrap; }

.rep-h2 { margin: 1.8rem 0 .6rem; font-size: 1.15rem; }
.rep-h3 { margin: 0 0 .6rem; font-size: 1rem; }

/* Datele de identitate ale subiectului: perechi eticheta/valoare care se aseaza
   pe cate coloane incap, fara sa se stramteze pana la ilizibil. */
.rep-facts { display: grid; gap: .9rem 1.6rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.rep-fact { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.rep-fact-label { color: var(--ink-soft); font-size: .78rem; letter-spacing: .04em; }
.rep-fact-value { font-size: 1.05rem; overflow-wrap: anywhere; }

/* KPI-urile. Fiecare caseta spune un numar SI din ce e facut — un total fara
   compozitie e o cifra pe care nu o poti verifica. */
.rep-kpis { display: grid; gap: 1rem; margin-bottom: .4rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.rep-kpi { display: flex; flex-direction: column; gap: .25rem; min-width: 0;
  border-left: 3px solid var(--line); }
.rep-kpi--green { border-left-color: var(--coin-green-ink); }
.rep-kpi--red   { border-left-color: var(--coin-red-ink); }
.rep-kpi--eur   { border-left-color: var(--accent); }
.rep-kpi-label { color: var(--ink-soft); font-size: .82rem; }
.rep-kpi-value { font-size: 1.7rem; font-weight: 700; line-height: 1.1; color: var(--ink); }
.rep-kpi-sub { color: var(--ink-soft); font-size: .8rem; overflow-wrap: anywhere; }

.rep-money { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }
.rep-table { min-width: 34rem; }
.rep-row-total td { border-top: 2px solid var(--line); font-weight: 600; }

.rep-chart { overflow-x: auto; }

/* `.card:has(> .data-table)` acopera deja cazul, dar `:has()` nu exista in
   browserele mai vechi de 2023 — iar un tabel de raport taiat pe dreapta, fara
   bara, e exact reclamatia de la care a pornit toata treaba asta. Clasa scrisa
   pe mana nu depinde de nimic. */
.table-card { overflow-x: auto; scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent; }
.table-card::-webkit-scrollbar { height: 9px; }
.table-card::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 999px; }
.table-card::-webkit-scrollbar-track { background: transparent; }

/* Sirul de operatiuni. Ora si suma sunt coloane inguste si fixe, ca ochiul sa
   coboare pe ele; descrierea primeste restul si se rupe in loc sa impinga. */
.rep-ops { min-width: 52rem; }
.rep-op-when { white-space: nowrap; }
.rep-op-ref { margin-left: .4rem; font-size: .82rem; }

/* CELE DOUA COLOANE DE TEXT LIBER AU VOIE SA CURGA PE MAI MULTE RANDURI.
   Regula generala a tabelelor (sectiunea „ALINIERI", 2026-08-21) tine celulele
   pe un singur rand si lasa cardul sa capete scroll — corect pentru date scurte
   si numere, gresit aici: un email de 60 de caractere si o descriere de fisier
   ar impinge tabelul la trei ecrane latime, si atunci ora si suma — coloanele
   pe care le citesti — ies din campul vizual. `max-width` singur nu ajunge:
   fara `white-space: normal` celula ramane clampata si textul iese peste
   vecina. Amandoua, sau niciuna. */
.data-table td.rep-op-who,
.data-table td.rep-op-detail,
.data-table td.rep-wrap {
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: normal;
  vertical-align: top;
}
.rep-op-who { max-width: 16rem; }
.rep-op-detail { max-width: 24rem; }
.rep-wrap { max-width: 26rem; }
.rep-op-kind { font-weight: 600; }
.rep-op-kind--coins   { color: var(--coin-green-ink); }
.rep-op-kind--payment { color: var(--accent); }
.rep-op-kind--plan    { color: var(--accent-2); }

.rep-out { display: inline-block; padding: .1rem .5rem; border-radius: 999px;
  font-size: .76rem; border: 1px solid var(--line); white-space: nowrap; }
.rep-out--ok      { border-color: var(--ok-line);    background: var(--coin-green-soft); color: var(--coin-green-ink); }
.rep-out--fail    { border-color: var(--error-line); background: var(--coin-red-soft);   color: var(--coin-red-ink); }
.rep-out--pending { color: var(--ink-soft); }

.rep-coins { white-space: nowrap; font-weight: 600; }
.rep-coins--green { color: var(--coin-green-ink); }
.rep-coins--red   { color: var(--coin-red-ink); }

@media (max-width: 640px) {
  .rep-period-label { margin-left: 0; }
  .rep-kpi-value { font-size: 1.4rem; }
}


/* ============================================================================
   FACTURA — 2026-08-22 (cerinta Xprime)
   Documentul se vede pe ecran in tema inchisa, ca restul site-ului, si se
   TIPARESTE pe alb (regulile de @media print de mai jos). Butonul „Tipareste"
   deschide dialogul browserului, de unde „Salveaza ca PDF" da fisierul — nu
   exista si nu merita o biblioteca de PDF pentru o pagina A4 cu un tabel.
   ========================================================================== */

.inv-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: 1.2rem; }

.inv-sheet {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 2rem 2.2rem;
  max-width: 52rem;          /* proportia unei coli, si pe ecran */
  margin: 0 auto;
}

.inv-head { display: flex; flex-wrap: wrap; gap: 1.5rem; justify-content: space-between;
  border-bottom: 1px solid var(--line); padding-bottom: 1.2rem; margin-bottom: 1.2rem; }
.inv-seller { min-width: 0; flex: 1 1 18rem; }
.inv-seller-name { margin: 0 0 .4rem; font-size: 1.25rem; overflow-wrap: anywhere; }
.inv-meta { text-align: right; flex: 0 1 auto; }
.inv-doc-type { margin: 0; color: var(--ink-soft); letter-spacing: .12em;
  text-transform: uppercase; font-size: .78rem; }
.inv-number { margin: .1rem 0 .7rem; font-size: 1.5rem; font-weight: 700; }
.inv-dates { margin: 0; display: grid; gap: .25rem; }
.inv-dates div { display: flex; gap: .6rem; justify-content: flex-end; }
.inv-dates dt { color: var(--ink-soft); font-size: .82rem; }
.inv-dates dd { margin: 0; font-size: .82rem; }

.inv-h2 { font-size: .78rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0 0 .35rem; }
.inv-buyer { margin-bottom: 1.4rem; }
.inv-buyer-name { margin: 0 0 .2rem; font-weight: 600; font-size: 1.05rem; overflow-wrap: anywhere; }
.inv-line { margin: 0; font-size: .88rem; overflow-wrap: anywhere; }

.inv-table { width: 100%; border-collapse: collapse; margin-bottom: 1.2rem; }
.inv-table th { text-align: left; font-size: .76rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-soft); padding: .5rem .6rem;
  border-bottom: 1px solid var(--line); }
.inv-table td { padding: .7rem .6rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.inv-table th.num, .inv-table td.num { text-align: right; white-space: nowrap; }
.inv-item { display: block; overflow-wrap: anywhere; }
.inv-item-detail { display: block; color: var(--ink-soft); font-size: .84rem; overflow-wrap: anywhere; }

.inv-totals { display: grid; gap: .3rem; justify-content: end; margin-bottom: 1.4rem; }
.inv-total-row { display: flex; gap: 2.5rem; justify-content: space-between; min-width: 16rem; }
.inv-total-row--grand { border-top: 2px solid var(--line); padding-top: .5rem;
  font-size: 1.15rem; font-weight: 700; }

.inv-foot { border-top: 1px solid var(--line); padding-top: 1rem; display: grid; gap: .35rem; }
.inv-note { margin: 0; font-size: .86rem; overflow-wrap: anywhere; }

@media (max-width: 560px) {
  .inv-sheet { padding: 1.2rem; }
  .inv-head { flex-direction: column; }
  .inv-meta { text-align: left; }
  .inv-dates div { justify-content: flex-start; }
}

/* ============================================================================
   TIPAR — 2026-08-21
   Tema e inchisa; pe hartie asta inseamna cerneala irosita si, la multe
   imprimante, casete negre in loc de text. La tipar intoarcem foaia: fundal
   alb, scris negru, fara fotografii de fundal si fara meniuri.
   ========================================================================== */
@page {
  /* MARGINILE FOII 2026-08-22. Fara ele, coloana din dreapta a facturii —
     numarul, sumele — sta lipita de marginea hartiei si se poate pierde la
     taiere sau in zona pe care imprimanta n-o poate tipari. */
  margin: 16mm 14mm;
}

@media print {
  html, body { background: #fff !important; color: #000 !important; }
  body::before, body::after { display: none !important; }
  .site-header, .site-footer, .cookie-banner, .panel-side, .admin-nav,
  .lang-switch, .panel-lang, .btn-primary, .btn-secondary, .btn-small { display: none !important; }
  .card, .hero, .notice, .data-table, .panel-card {
    background: #fff !important; color: #000 !important;
    border: 1px solid #999 !important; box-shadow: none !important;
  }
  .hero, .hero-photo, .terminal-hero, .detect-terminal-page, .processing-live-card {
    background-image: none !important; min-height: 0 !important; }
  .terminal-ring, .processing-glow-ring { box-shadow: none !important; border-color: #999 !important; }
  a { color: #000 !important; text-decoration: underline; }

  /* FACTURA PE HARTIE 2026-08-22. Pe ecran e un card intr-o pagina; pe hartie
     TREBUIE sa fie foaia insasi — fara chenar, fara umbra, pe toata latimea, si
     fara butoanele de deasupra. `.no-print` acopera si orice alt bloc de actiuni
     pe care il vom mai adauga. */
  .no-print, .inv-actions { display: none !important; }
  .inv-sheet {
    max-width: none !important; margin: 0 !important; padding: 0 !important;
    border: none !important; border-radius: 0 !important; box-shadow: none !important;
    background: #fff !important; color: #000 !important;
  }
  .inv-table th, .inv-table td, .inv-head, .inv-foot, .inv-total-row--grand {
    border-color: #999 !important;
  }
  .inv-doc-type, .inv-dates dt, .inv-h2, .inv-item-detail, .inv-line.hint,
  .inv-table th {
    color: #444 !important;
  }
  /* Titlurile isi pierd culoarea de tema si devin cerneala. */
  .inv-seller-name, .inv-number, .inv-buyer-name, .inv-total-row--grand {
    color: #000 !important;
  }
  /* Un tabel de factura nu se rupe frumos peste doua pagini. */
  .inv-table { page-break-inside: avoid; }
  .inv-totals, .inv-foot { page-break-inside: avoid; }
}

/* ============================================================================
   POARTA DE DESTINATIE — 2026-08-25 (cerinta Xprime, decizia "Model B")
   ---------------------------------------------------------------------------
   Blocul in care clientul declara tara si destinatia vehiculului, cand selectia
   contine o optiune care atinge un sistem antipoluare.

   ARATA ALTFEL DECAT RESTUL FORMULARULUI, si e intentionat. Nu e inca un camp
   de completat: e momentul in care omul isi asuma ceva. Un bloc care se pierde
   printre celelalte casute se completeaza reflex — exact ce nu vrem de la o
   declaratie care se pastreaza cu data si cu textul ei.

   Chenar chihlimbar, nu rosu: nu e o eroare, nu s-a stricat nimic. E o
   intrebare la care raspunsul conteaza.
   ========================================================================== */
.dest-gate {
  margin: 1.1rem 0 0; padding: 1.05rem 1.15rem; border-radius: 12px;
  background: var(--panel-2); border: 1px solid var(--line);
  border-left: 3px solid var(--warn);
}
.dest-gate-title {
  margin: 0 0 .35rem; font-size: 1rem; font-weight: 700; color: var(--ink);
}
.dest-gate-why {
  margin: 0 0 .9rem; font-size: .88rem; line-height: 1.55; color: var(--ink-soft);
}
.dest-gate-field { display: block; margin: 0 0 1rem; }
.dest-gate-field > span {
  display: block; margin-bottom: .3rem; font-size: .88rem; font-weight: 600; color: var(--ink);
}
.dest-gate-field select { width: 100%; max-width: 26rem; }
.dest-gate-field .hint { display: block; margin-top: .3rem; }

.dest-gate-dest { border: 0; padding: 0; margin: 0 0 .9rem; }
.dest-gate-dest legend {
  padding: 0; margin-bottom: .45rem; font-size: .88rem; font-weight: 600; color: var(--ink);
}
.dest-opt {
  display: flex; align-items: flex-start; gap: .55rem;
  margin: 0 0 .45rem; line-height: 1.45;
}
.dest-opt input { margin-top: .25rem; flex: none; }
.dest-opt .hint { display: block; margin-top: .1rem; font-size: .82rem; }

.dest-gate-declare {
  margin: 0; padding-top: .85rem; border-top: 1px solid var(--line);
  font-size: .84rem; line-height: 1.55; color: var(--ink-soft);
}

/* ---------------------------------------------------------------------------
   MARCAJELE DE PE OPTIUNI
   ---------------------------------------------------------------------------
   Semnul de langa o optiune restrictionata trebuie sa fie acolo INAINTE de
   bifa, nu sa apara dupa. Un semn care apare tarziu se citeste ca obstacol;
   unul care e acolo de la inceput, ca o conditie.
   --------------------------------------------------------------------------- */
.opt-flag {
  display: inline-block; margin-left: .4rem; padding: .05rem .42rem;
  border-radius: 999px; font-size: .7rem; font-weight: 600;
  letter-spacing: .2px; white-space: nowrap; vertical-align: middle;
}
.opt-flag-restricted   { background: var(--error-bg); color: var(--error); }
.opt-flag-homologation { background: var(--warn-bg);  color: var(--warn-ink); }

/* ---------------------------------------------------------------------------
   INREGISTRARE: TIPUL DE CONT SI BLOCUL DE FIRMA — 2026-08-25
   --------------------------------------------------------------------------- */
.reg-account-type {
  border: 1px solid var(--line); border-radius: 10px;
  padding: .85rem 1rem; margin: 0 0 1.2rem; background: var(--panel-2);
}
.reg-account-type legend {
  padding: 0 .4rem; font-size: .85rem; font-weight: 600; color: var(--ink-soft);
}
.reg-account-type .opt {
  display: flex; align-items: flex-start; gap: .55rem; margin: .35rem 0; line-height: 1.45;
}
.reg-account-type .opt input { margin-top: .25rem; flex: none; }
.reg-account-type .hint { display: block; margin-top: .1rem; font-size: .82rem; }

.reg-business {
  padding: .9rem 1rem; margin: 0 0 1rem;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2);
}
.reg-business[hidden], .reg-business-consent[hidden] { display: none; }

/* Titlurile de lista din politica de rambursare a procesarii manuale. */
.mfs-policy-h { margin: 1rem 0 .3rem; font-size: .9rem; }
.mfs-policy ul { margin: 0 0 .8rem; padding-left: 1.2rem; line-height: 1.55; }
.mfs-policy li { margin: .2rem 0; font-size: .88rem; color: var(--ink-soft); }

/* Avertismentul din poarta de destinatie — 2026-08-25.
   Rosu, si nu din exces: e singura fraza de pe ecran care spune ce poate
   afecta fisierul si cine raspunde. Culoarea notelor obisnuite ar fi trecut-o
   in randul explicatiilor, adica exact acolo unde nu se citeste.
   NU e mesajul de refuz — ala apare doar cand chiar se refuza ceva. */
.dest-gate-warning {
  margin: 0 0 .9rem; padding: .7rem .85rem; border-radius: 8px;
  background: var(--error-bg); color: var(--error);
  font-size: .86rem; line-height: 1.55;
}


/* ============================================================================
   TRASAREA UNUI FISIER EXPORTAT (2026-08-27)
   Ecran de admin: cauti dupa cod, vezi exemplarul si sursele din care a fost
   compus, cu descarcare si marcare defect pe fiecare.
   ========================================================================== */
.trace-code {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 1.35rem;
  letter-spacing: 0.14em;
  font-weight: 700;
}
.trace-facts { display: grid; grid-template-columns: max-content 1fr; gap: 0.35rem 1.2rem; }
.trace-facts dt { color: var(--ink-soft); }
.trace-facts dd { margin: 0; word-break: break-all; }
.trace-src-row--defective { background: var(--error-bg); }
.trace-src-ref {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  word-break: break-all;
}
.trace-flag {
  display: inline-block; padding: 0.1rem 0.45rem; border-radius: 0.35rem;
  font-size: 0.78rem; font-weight: 600;
  background: var(--error-bg); color: var(--error);
}
.trace-flag--pending { background: var(--warn-bg); color: var(--warn-ink); }
.trace-note { max-width: 22rem; }
.trace-empty { color: var(--ink-soft); }


/* ============================================================================
   RAFINARE VIZUALA 2026-09-05 (cerinta Xprime: „cosmetizare, aliniere,
   optimizare" — pe baza existenta, fara redesign).

   Un singur strat, la sfarsitul fisierului, ca sa bata regulile de mai sus
   fara `!important` si sa se poata scoate dintr-o bucata daca ceva nu place.
   Principii aplicate (din ghidurile publice de design pentru agenti —
   impeccable / taste / Emil Kowalski): ritm vertical consecvent, aliniere
   in grile, stari clare (hover / focus / disabled), tipografie cu titluri
   echilibrate si text lizibil, miscare scurta si numai pe proprietati ieftine.
   ========================================================================== */

/* --- 1. ALINIEREA CARDURILOR IN GRILE (defect general) ----------------------
   `.card + .card { margin-top: 1.2rem }` e scrisa pentru carduri STIVUITE, dar
   intr-o grila al doilea card e tot un frate adiacent: primea marginea si
   statea cu 19px mai jos decat primul. Se vedea pe /plans (Basic mai sus
   decat Pro/Shop), pe /contact (formularul mai sus decat „Already a
   customer?") si oriunde doua carduri stau una langa alta. Regula de mai jos
   anuleaza marginea in ORICE container de tip grila/rand, nu per pagina.

   `.paid-split` (ecranul de descarcare, 22.09.2026) a intrat in aceeasi lista:
   numele lui nu contine „grid", asa ca al doilea card primea marginea si statea
   cu 19px mai jos decat primul. Se adauga AICI, nu cu o regula proprie — un al
   doilea loc care rezolva acelasi lucru inseamna, mai devreme sau mai tarziu,
   doua comportamente diferite. */
:is([class*="grid"], .coin-wallets, .stat-tiles, .steps, .entry-grid, .plans-grid,
    .paid-split) > .card + .card,
:is([class*="grid"], .coin-wallets, .stat-tiles, .steps, .entry-grid, .plans-grid,
    .paid-split) > .card + .profile-grid {
  margin-top: 0;
}

/* --- 2. TIPOGRAFIE --------------------------------------------------------- */
h1, h2, h3, .hero h1, .terminal-copy h1, .detect-terminal-copy h1 { text-wrap: balance; }
p, li, .lead, .hint { text-wrap: pretty; }
/* Cifrele stau in coloana in tabele si in bara de sus (preturi, coins). */
.data-table td, .panel-coins-value, .plan-price, .opt-price, .stat-tile-value { font-variant-numeric: tabular-nums; }
/* Titlul paginii si primul paragraf de sub el respira la fel peste tot. */
.admin-main h1 + p, .admin-main h1 + .lead, .admin-main h1 + .hint { margin-top: 0; }
::selection { background: rgba(32,214,239,.28); color: var(--ink); }

/* --- 3. STARI: focus, hover, dezactivat ------------------------------------ */
/* Campurile aveau doar o schimbare de chenar la focus; de la tastatura nu se
   vedea unde esti. Inel discret, aceeasi culoare ca butoanele. */
input:focus-visible, select:focus-visible, textarea:focus-visible {
  border-color: var(--accent-btn);
  box-shadow: 0 0 0 3px rgba(19,159,208,.28);
}
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible {
  outline: 2px solid var(--accent-btn); outline-offset: 2px; box-shadow: none;
}
/* Butoanele raspund la apasare, nu doar la trecerea mausului. */
.btn-primary, .btn-secondary, .btn-small { transition: background .15s ease, color .15s ease, box-shadow .15s ease, transform .12s ease; }
.btn-primary:active, .btn-secondary:active, .btn-small:active { transform: translateY(1px); }
.btn-primary:disabled, .btn-primary[disabled] { cursor: not-allowed; transform: none; }
/* Linkurile din meniul de sus si din panou: o tranzitie de culoare scurta. */
.main-nav a, .admin-nav-link, .link-button, a { transition: color .15s ease, background-color .15s ease, border-color .15s ease; }

/* --- 4. PAGINA /detect ----------------------------------------------------- */
/* Paragraful statea lipit de titlu, iar inelul urca peste el (`margin-top:
   -3rem`). Acum: titlu, o pauza, textul, apoi inelul sub ele, cu spatiu. */
.detect-terminal-copy .lead { margin: .9rem 0 0; max-width: 34rem; }
.detect-terminal-stage { margin-top: 1.6rem; }
@media (min-width: 901px) {
  .detect-terminal-copy { margin-inline: auto; text-align: center; }
  .detect-terminal-copy .lead { margin-inline: auto; }
  .detect-terminal-page { padding-top: clamp(2rem, 4vw, 3.4rem); }
}

/* --- 5. FORMULARUL DE INREGISTRARE ----------------------------------------- */
/* Textele de consimtamant mosteneau `label { font-weight: 600 }`: sase
   paragrafe bold, greu de citit. Bifa ramane, textul devine text. */
.reg-consent { align-items: flex-start; font-weight: 400; padding: .45rem 0; }
.reg-consent > input { margin-top: .25rem; flex: none; }
.reg-consent > span { font-size: .85rem; line-height: 1.55; color: var(--ink-soft); }
.reg-consent > span strong { color: var(--ink); }

/* Aceeasi problema la bifele de plata / pornire de pe pagina fisierului:
   trei paragrafe juridice, toate bold. Ramane bold doar ce e marcat <strong>. */
.terms-gate .opt, .start-gate-confirm { font-weight: 400; }
.terms-gate .opt > span, .start-gate-confirm > span { line-height: 1.55; }

/* --- 6. DOCUMENTELE JURIDICE ----------------------------------------------- */
/* Coloana de citit statea lipita in stanga, sub o banda pe toata latimea, cu
   40% din ecran gol in dreapta. Se centreaza, la aceeasi latime de citit. */
.legal { max-width: 52rem; margin-inline: auto; }
.legal-incomplete { max-width: 52rem; margin-inline: auto; }

/* --- 7. CHENARELE CU CIFRE ------------------------------------------------- */
/* Au ramas doua (cel cu „proiecte" a fost scos). Doua chenare late cat
   ecranul, cu cifra in coltul stang, arata goale; le tinem la latimea fasiei
   cu cei trei pasi si centram continutul in fiecare. */
.stat-tiles { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }
.stat-tile { justify-items: center; text-align: center; padding: 1.25rem 1.2rem 1.3rem; }
.stat-tile-icon { margin-bottom: .45rem; }

/* --- 8. ANTETUL PUBLIC PE TELEFON ------------------------------------------ */
/* Sub 640px meniul se rupea in doua randuri aliniate la dreapta, cu pastila
   „Creeaza cont" si limba pe al doilea. Acum: sigla sus, meniul pe un rand
   intreg dedesubt, intins uniform, pastila mai compacta. */
@media (max-width: 640px) {
  .header-row { row-gap: .55rem; padding: .7rem 0 .75rem; }
  .main-nav { flex: 1 0 100%; justify-content: space-between; gap: .5rem .9rem; }
  .main-nav a { font-size: .86rem; }
  .main-nav a.nav-cta { padding: .42rem .95rem; font-size: .72rem; letter-spacing: .06em; }
  .lang-switch summary { padding: .28rem .65rem; }
}

/* --- 9. PANOUL CLIENTULUI PE TELEFON --------------------------------------- */
/* Sub 620px meniul lateral se desena INTREG, pe verticala, deasupra
   continutului: un ecran de derulat inainte sa vezi pagina. O prima varianta
   (2026-09-05) l-a facut banda derulabila orizontal — GRESIT (Xprime): pe
   ecran ramaneau vizibile doar primele 3 intrari, restul pareau disparute,
   iar meniurile stinse acum din admin vor reveni si trebuie sa se vada toate.
   Acum: TOATE intrarile raman pe ecran, ca pastile care se rup pe randuri,
   fiecare grup cu titlul lui; ocupa cam o treime din cat ocupa lista
   verticala. Pe tableta si desktop nu se schimba nimic. */
@media (max-width: 620px) {
  .admin-side { padding: .75rem 1rem .55rem; }
  .admin-brand { margin-bottom: .55rem; }
  .admin-nav { display: block; overflow: visible; }
  .admin-nav-group {
    display: flex; flex-wrap: wrap; align-items: center; gap: .35rem;
    width: 100%; margin-bottom: .55rem;
  }
  .admin-nav-title { flex: 1 1 100%; padding: 0; margin: 0 0 .05rem; }
  .admin-nav-link {
    flex: 0 0 auto; white-space: nowrap;
    padding: .38rem .8rem; border: 1px solid var(--line); border-radius: 999px;
    font-size: .84rem; background: var(--panel-2);
  }
  .admin-nav-link.is-active { border-color: transparent; }
  .admin-side-foot {
    display: flex; flex-wrap: wrap; align-items: center; gap: .15rem 1rem;
    margin-top: .2rem; padding-top: .55rem;
  }
  .admin-side-foot > .admin-nav-link { padding: .2rem 0; border: 0; background: none; font-size: .82rem; }
  .admin-side-foot .panel-lang { flex: 1 1 100%; margin: 0; }
  .admin-side-foot .panel-lang > summary { padding-inline: 0; }
  .admin-side-foot .admin-who { flex: 1 1 100%; margin: 0; order: 9; }
  .admin-main { padding-top: 1.1rem; }
  .panel-topbar { justify-content: flex-start; }
}

/* --- 9b. DASHBOARD PE TELEFON: cercul de incarcare decalat ----------------- */
/* Defect pre-existent (verificat si pe CSS-ul dinainte), raportat de Xprime
   2026-09-05: sub 1180px zona de lucru devine o singura coloana `1fr`, dar
   `1fr` inseamna `minmax(auto, 1fr)` — coloana se largeste pana la latimea
   minima a tabelului „Recent files" (celule `nowrap`), adica peste 600px pe
   un telefon. Cardul „New file" statea in aceeasi coloana, deci cercul se
   centra intr-un container mai lat decat ecranul si iesea in dreapta, iar
   tabelul se taia. `minmax(0, 1fr)` opreste largirea; tabelul primeste
   derulare proprie in card. */
@media (max-width: 1180px) {
  .terminal-dashboard-workspace { grid-template-columns: minmax(0, 1fr); }
  .terminal-dashboard-workspace > * { min-width: 0; max-width: 100%; }
  .terminal-table-card { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .terminal-dashboard-upload .terminal-upload,
  .terminal-dashboard-upload .terminal-ring { max-width: 100%; }
}
/* Pe telefon tabelul „Recent files" incape in ecran: trei coloane pe
   procente (fisier / stare / actiune), numele fisierului si randul cu
   vehiculul se rup pe randuri, starea si butonul raman vizibile fara
   derulare laterala. `th.col-file { min-width: 10rem }` din regula generala
   e lasat jos, altfel cele trei coloane nu incap in 350px. */
@media (max-width: 620px) {
  /* `display: table` explicit: regula generala de sub 640px face din tabele
     `display: block` (derulabile), iar pe un bloc `table-layout: fixed` si
     latimile pe coloane nu au niciun efect. */
  .terminal-table-card .data-table { display: table; width: 100%; table-layout: fixed; }
  /* Doua coloane, nu trei: randul intreg e deja clicabil (`tr.row-link`,
     dashboard.php), deci butonul din a treia coloana e redundant pe un ecran
     de 350px, unde nici nu incapea („Pay & download" pe doua randuri, peste
     starea de langa el). Starea ramane, cu voie sa se rupa. */
  .terminal-table-card .jobs-table--compact th:nth-child(1) { width: 62%; min-width: 0; }
  .terminal-table-card .jobs-table--compact th:nth-child(2) { width: 38%; }
  .terminal-table-card .jobs-table--compact th:nth-child(3),
  .terminal-table-card .jobs-table--compact td.actions { display: none; }
  .terminal-table-card .data-table th,
  .terminal-table-card .data-table td { white-space: normal; }
  .terminal-table-card .data-table .col-file,
  .terminal-table-card .data-table .job-file { overflow-wrap: anywhere; word-break: break-word; }
  .terminal-table-card .jobs-table--compact .ui-badge { white-space: normal; line-height: 1.3; }
  /* Numele fisierului se rupe pe randuri in loc sa fie taiat cu „…": pe
     telefon nu exista hover care sa-l arate intreg. */
  .terminal-table-card .jobs-table--compact .job-file { white-space: normal; overflow: visible; text-overflow: clip; }
}

/* --- 10. MARUNTISURI DE ALINIERE ------------------------------------------- */
/* Subsolul public: randul cu linkuri se rupe curat pe telefon. */
.site-footer .wrap { line-height: 1.9; }
/* Imaginile din continut nu depasesc niciodata cardul. */
/* PLASA DE SIGURANTA, NU REGULA 2026-09-10.
   Scrisa ca `.card svg:not(.stat-tile-icon)` avea specificitate 0-2-1 si batea
   orice componenta care isi declara singura latimea (0-1-0). Graficul de gain
   isi cerea `max-width: 680px` si primea `100%`: un SVG de 640x300 intins la
   1554px, adica marit de 2,4 ori cu tot cu cifrele de pe axe — de aceea arata
   disproportionat pe ecran lat. `:where()` are specificitate ZERO, deci regula
   ramane ce trebuia sa fie de la inceput: o limita pentru ce nu-si declara
   dimensiunea, nu o suprascriere peste ce si-o declara. */
:where(.card) :where(img, svg:not(.stat-tile-icon)) { max-width: 100%; height: auto; }
/* Mesajele flash au aceeasi distanta fata de titlu ca orice card. */
.flash + h1, .flash + .card { margin-top: 1rem; }

/* --- 11. BARA DE DERULARE ORIZONTALA DESENATA DE NOI (2026-09-06 / 09-12) ---
   Vezi `templates/partials/hscroll.php`, unde sta si povestea intreaga.

   JOS, LIPITA DE MARGINEA DE JOS A FERESTREI (12.09.2026, raportat de Xprime:
   „dai scroll down, merge in sus cu lista si dispare odata cu lista"). Era
   `top: 0`, adica deasupra tabelului — iar zona in care un element lipit poate
   ramane se termina acolo unde incepe fratele urmator, deci bara pleca exact in
   clipa in care intrai in lista. Acum e ultimul copil al invelisului, cu
   `bottom`: cat timp tabelul e pe ecran, bara pluteste la baza ferestrei; cand
   ai trecut de tabel, se aseaza la locul ei si iese din cadru odata cu el.

   Invelisul (`.hscroll-box`) e pus de script in jurul fiecarui element care
   chiar se poate derula orizontal. El e blocul continator al barei — fara el,
   bara ar pluti peste tot restul paginii, inclusiv peste alt tabel. */
.hscroll-box { position: relative; }
.hscroll {
  position: sticky; bottom: .55rem; z-index: 4;
  height: 12px; margin: .5rem 0 0; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line);
  box-shadow: 0 2px 10px rgba(0,0,0,.35);
  cursor: pointer; user-select: none; touch-action: none;
}
.hscroll-thumb {
  position: absolute; top: 1px; bottom: 1px; left: 1px; width: 40px;
  border-radius: 999px; background: var(--accent-btn); opacity: .85; cursor: grab;
}
.hscroll-thumb:active { cursor: grabbing; opacity: 1; }
.hscroll[hidden] { display: none; }

/* Invelisul e adaugat de script DUPA ce s-a randat pagina, deci regulile de
   distanta dintre carduri („.card + .card") nu-l mai vad si stivuirea s-ar
   strange. Randurile astea ii dau invelisului exact rolul pe care il avea
   elementul invelit — altfel reparatia barei ar muta toate cardurile. */
.hscroll-box + .card,
.card + .hscroll-box,
.hscroll-box + .hscroll-box,
.hscroll-box + .profile-grid,
.profile-grid + .hscroll-box { margin-top: 1.2rem; }
.flash + .hscroll-box > .card { margin-top: 1rem; }
:is([class*="grid"], .coin-wallets, .stat-tiles, .steps, .entry-grid, .plans-grid) > .hscroll-box + .hscroll-box {
  margin-top: 0;
}

/* --- 12. FORMULARUL DE FURNIZOR (admin → Email guard, 2026-09-06) ----------
   Campuri in randuri de 2–4 coloane pe desktop, o coloana pe telefon;
   randurile de furnizori opriti sunt estompate, nu ascunse. */
.form-grid { display: grid; gap: .75rem; margin-top: .6rem; }
.form-grid label { display: flex; flex-direction: column; gap: .3rem; font-size: .85rem; font-weight: 500; }
.form-grid label.opt { flex-direction: row; align-items: center; }
.form-grid input[type="text"], .form-grid input[type="number"] { width: 100%; }
.form-grid .form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: .75rem; }
.form-grid .hint { font-weight: 400; }
.data-table tr.row-muted td { opacity: .55; }
.data-table tr.row-muted td.actions { opacity: 1; }
.actions .inline-form { display: inline-block; margin: 0 .15rem .25rem 0; }

/* GOLIREA UNUI DIRECTOR DIN STORAGE 2026-09-09 (cerinta Xprime): butonul care
   sterge tot cache-ul de identificare, sub titlul cardului. Sta pe acelasi rand
   cu explicatia lui cat incape si trece dedesubt cand nu incape — un buton care
   sterge ceva nu trebuie sa iasa niciodata din ecran. Tonul e de avertizare, nu
   de pericol: fisierele se refac singure. */
.storage-purge { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; margin: 0 0 1rem; }
.storage-purge .hint { margin: 0; }
.storage-purge-btn { border-color: var(--warn); color: var(--warn); }
.storage-purge-btn:hover { border-color: var(--warn-bright); color: var(--warn-bright); background: var(--warn-bg); }

/* ── CELE DOUA MODELE DE DOCUMENTE JURIDICE (2026-09-09, admin → Settings) ──
   Doua carduri de ales, nu doua butoane radio pierdute intr-o coloana. Motivul
   e ca alegerea nu e „da/nu", ci „care dintre doua texte se publica" — iar
   diferenta dintre ele se citeste, nu se ghiceste, deci fiecare optiune isi
   poarta explicatia inauntru. Cel activ e marcat cu marginea de accent: un
   comutator care schimba un contract trebuie sa spuna, dintr-o privire, in ce
   stare e acum. */
.legal-mode-opt {
  display: flex; align-items: flex-start; gap: 0.7rem;
  padding: 0.85rem 1rem; margin: 0 0 0.7rem;
  border: 1px solid var(--line); border-radius: var(--radius-s);
  cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease;
}
.legal-mode-opt:hover { border-color: var(--accent-btn); }
.legal-mode-opt input { accent-color: var(--accent-btn); margin-top: 0.25rem; }
.legal-mode-opt > span { display: block; }
.legal-mode-opt .hint { display: block; margin: 0.3rem 0 0; }
.legal-mode-opt.is-on { border-color: var(--accent-btn); background: var(--accent-soft); }
.legal-mode form { margin-top: 0.4rem; }

/* ── IESIREA CATRE PROCESAREA MANUALA, IN FIRUL TICHETULUI (2026-09-09) ─────
   Butonul sta sub raspunsul care il explica, despartit de text printr-o linie
   subtire: e o actiune, nu o continuare a paragrafului, si trebuie sa se vada
   ca atare fara sa strige. Explicatia de sub el spune daca fisierul mai e pe
   server — singura informatie de care omul are nevoie inainte sa apese. */
.msg-manual { margin-top: 0.9rem; padding-top: 0.9rem; border-top: 1px solid var(--line); }
.msg-manual .hint { margin: 0.5rem 0 0; }

/* ── CELE TREI FERESTRE DE COTA LA IDENTIFICARE (2026-09-09, admin → Settings)
   Pe un rand, fiindca sunt aceeasi decizie privita din trei unghiuri: cate pe
   zi, cate pe luna, cate in total. Una sub alta s-ar citi ca trei reglaje fara
   legatura, iar operatorul n-ar mai vedea ca lucreaza impreuna. Sub 640px trec
   una sub alta — un camp numeric strivit nu se completeaza. */
.quota-row { display: flex; gap: 1rem; flex-wrap: wrap; margin: 0.2rem 0 0.6rem; }
.quota-row > div { flex: 1 1 9rem; min-width: 8rem; }
.quota-row label { display: block; }
.quota-row input { width: 100%; }
@media (max-width: 640px) { .quota-row { flex-direction: column; gap: 0.2rem; } }

/* ══════════════════════════════════════════════════════════════════════════
   PANOUL DE ADMINISTRARE — BARA DE SUS, FIRIMITURI, ANTETUL PAGINII
   2026-09-09, cerinta Xprime: „modifica si panoul de admin, inclusiv meniurile,
   segregare corecta si distincta", cu portalul clientului ca directie.

   Nu e o identitate noua: sunt aceleasi jetoane de culoare, aceeasi raza, aceeasi
   familie de litere. Se schimba trei lucruri care lipseau, si care in portalul
   clientului existau deja:

     1. O BARA DE SUS. Panoul incepea direct cu titlul, deci „unde sunt" si „cu
        ce cont sunt logat" nu se vedeau nicaieri — al doilea statea in coltul de
        jos al barei laterale, cu litera de nota de subsol.
     2. FIRIMITURI. Cu opt sectiuni si patruzeci de ecrane, titlul singur nu
        spune din ce parte a panoului face parte pagina.
     3. UN SUBTITLU sub titlu. Vine din aceeasi definitie ca meniul, deci nu
        poate ajunge sa spuna altceva decat el.
   ══════════════════════════════════════════════════════════════════════════ */

.admin-topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0 0 0.9rem; margin-bottom: 1.4rem; border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.admin-crumbs {
  display: flex; align-items: center; gap: 0.45rem;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-soft); min-width: 0;
}
.admin-crumbs a { color: var(--ink-soft); text-decoration: none; }
.admin-crumbs a:hover { color: var(--accent-btn); }
.admin-crumbs strong { color: var(--ink); font-weight: 700; }
.admin-crumb-sep { opacity: 0.45; }

.admin-topbar-right { display: flex; align-items: center; gap: 0.9rem; min-width: 0; }
.admin-who { display: inline-block; font-size: 0.8rem; color: var(--ink-soft); margin: 0; overflow-wrap: anywhere; }

/* STAREA MOTORULUI. Pastila e mica si tacuta cand totul e in regula, si devine
   rosie cand nu e — un indicator care striga mereu se invata sa fie ignorat, iar
   atunci nu mai indica nimic. Duce la Diagnostics, fiindca aia e prima pagina pe
   care o deschizi cand vezi „offline". */
.admin-engine {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.25rem 0.65rem; border-radius: 999px; text-decoration: none;
  font-size: 0.78rem; font-weight: 600; border: 1px solid var(--line); color: var(--ink-soft);
}
.admin-engine-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.admin-engine--on { color: var(--ok); border-color: var(--ok-line); }
.admin-engine--off { color: var(--error); border-color: var(--error-line); background: var(--error-bg); }

/* ANTETUL PAGINII. Titlul isi pierde marginea de jos si o preia subtitlul, ca
   cele doua sa se citeasca drept un bloc — nu drept doua randuri care s-au
   nimerit unul sub altul. */
.admin-page { min-width: 0; }
.admin-page > * { min-width: 0; }
.admin-page > h1 { margin-bottom: 0.25rem; }
.admin-page-sub {
  margin: 0 0 1.4rem; max-width: 78ch;
  font-size: 0.92rem; line-height: 1.5; color: var(--ink-soft);
}

@media (max-width: 900px) {
  .admin-topbar { align-items: flex-start; }
  .admin-topbar-right { width: 100%; justify-content: space-between; }
}

/* Adresa dintr-un sir de operatiuni nu se rupe in doua randuri: coloana e
   ingusta, dar tabelul are deja bara lui de derulare orizontala (2026-09-06),
   iar un email taiat la mijloc nu se poate citi nici cu ea. */
.rep-op-who { white-space: nowrap; }

/* MENIUL A CRESCUT DE LA SASE GRUPURI LA OPT (2026-09-09), iar segregarea a
   meritat-o. Pretul e inaltimea: pe un laptop de 768px, ultimul grup („System")
   ajungea sub marginea ecranului si trebuia cautat prin derulare — adica exact
   sectiunea in care intri cand ceva nu merge. Se strange ritmul vertical, nu se
   taie nimic: aceleasi intrari, cu doi-trei pixeli mai putin fiecare, incap toate
   pe un ecran obisnuit. Sub 1.05rem intre grupuri titlurile incep sa se lipeasca
   de intrarea de deasupra, deci aici se opreste. */
.admin-side { padding-top: 1.1rem; padding-bottom: 0.9rem; }
.admin-brand { margin-bottom: 1.05rem; }
.admin-nav-group { margin-bottom: 0.85rem; }
.admin-nav-title { margin-bottom: 0.22rem; }
.admin-nav-link { padding: 0.34rem 0.55rem; }

/* COMUTATORUL DE SUBIECT din Reports: o bara, nu un card cu aer in jur. Cauta un
   client sau sari pe un grup — doua randuri, atat. */
.rep-subject { padding: 0.9rem 1rem; margin-bottom: 0.9rem; }
.rep-subject-row { display: flex; align-items: flex-end; gap: 0.7rem; flex-wrap: wrap; }
.rep-subject-field { display: flex; flex-direction: column; gap: 0.25rem; flex: 1 1 18rem; min-width: 12rem; }
.rep-subject-field input { margin: 0; }
.rep-subject-links { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-left: auto; }
.rep-subject-matches { list-style: none; margin: 0.8rem 0 0; padding: 0.7rem 0 0; border-top: 1px solid var(--line); }
.rep-subject-matches li { padding: 0.28rem 0; display: flex; gap: 0.6rem; align-items: baseline; flex-wrap: wrap; }

/* JURNALUL DE ACTIVITATE (Logs → Activity, 2026-09-09).
   Bara de filtre incapea pe trei randuri fiindca `input[type=email]` isi lua
   toata latimea disponibila; trei randuri de filtre deasupra unui tabel arata ca
   un formular, nu ca o bara. Si coloana de detaliu: JSON-ul scris de cod se
   rupea la mijlocul unui nume de fisier („bmw_320d_edc17.bi / n"), care nu se
   mai poate citi — se taie cu trei puncte, iar textul intreg ramane in `title`. */
.filter-input--email { flex: 0 1 20rem; min-width: 12rem; }
.activity-table .activity-meta {
  max-width: 34rem; white-space: normal;
  word-break: normal; overflow-wrap: break-word;
}

/* ══════════════════════════════════════════════════════════════════════════
   PROPUNERE 2026-09-09 — TON DE INSTRUMENT TEHNIC B2B
   Cerința: „fără glow, gradient și carduri umflate; colțuri aproape drepte și
   delimitări fine; formular compact pe o grilă coerentă; panou lateral pentru
   contextul fișierului; progres liniar, nu pastile; bară fixă pentru acțiunile
   principale; aspect sobru, de produs industrial european."

   Blocul se adaugă la sfârșitul lui app.css și REDEFINEȘTE. Nu se șterge nimic:
   dacă direcția nu convine, se scoate blocul și totul revine exact cum era.
   Culorile mărcii, familia de litere și structura paginilor rămân neatinse —
   se schimbă raza, adâncimea, densitatea și forma progresului.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Colțuri aproape drepte. 3px, nu 0: la 0 marginile par tăiate cu foarfeca
     pe ecranele fără antialiasing bun, iar câmpurile de formular par lipite. */
  --radius: 4px;
  --radius-s: 3px;
  /* Fără adâncime falsă. Un card nu plutește deasupra paginii — e o zonă
     delimitată, iar delimitarea o face o linie de un pixel. */
  --shadow: none;
  --shadow-soft: none;
  /* Suprafața cardului coboară spre fundal: separarea vine din linie, nu din
     contrastul de umplere. */
  --panel: #0a131b;
  --field: #060d13;          /* câmpurile sunt adâncite, nu ridicate */
  --line: rgba(159,190,207,.20);
  --line-soft: rgba(159,190,207,.10);
}

.card > h2:first-child, .card > h3:first-child { margin-top: 0; }
.card h2 { font-size: 1.02rem; letter-spacing: 0; }
.card h3 { font-size: .9rem; }


/* ── CÂMPURI: compacte, adâncite, aliniate pe grilă ─────────────────────── */
input[type="text"], input[type="email"], input[type="password"], input[type="tel"],
input[type="search"], input[type="number"], input[type="url"], input[type="date"],
select, textarea {
  padding: 0.45rem 0.6rem; border-radius: var(--radius-s);
  background: var(--field); border-color: var(--line);
  font-size: .9rem;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent-btn); box-shadow: none; outline: none; }
.fg-req { display: inline; color: var(--error); font-style: normal; }
/* ETICHETA MICA DOAR PENTRU ETICHETE, NU PENTRU PROPOZITII 2026-09-09.
   Regula de dinainte prindea `.card label` fara exceptie, deci prindea si
   randurile de bifa si de radio — acolo eticheta INVELESTE controlul si tine
   toata explicatia, iar `uppercase` transforma trei fraze intr-un bloc de
   majuscule pe care nu-l mai citeste nimeni (se vedea la Settings ->
   Identification limits).
   Distinctia corecta nu e o lista de clase, ci forma: eticheta care sta INAINTEA
   campului e un nume de camp si primeste stilul mic; eticheta care CONTINE un
   camp e un rand de optiune si ramane text normal. `:has()` face fix asta.
   Ordinea conteaza: baza e textul normal, majusculele se adauga peste. Intr-un
   browser fara `:has()` iese o eticheta nestilizata, nu o propozitie strigata. */
.card label, .form-grid label {
  font-size: .82rem; font-weight: 600; color: var(--ink-soft); margin-bottom: .28rem;
}
.card label:not(:has(input, select, textarea)),
.form-grid label:not(:has(input, select, textarea)) {
  font-size: .72rem; letter-spacing: .05em; text-transform: uppercase;
}
.card label:has(input[type="checkbox"], input[type="radio"]),
.form-grid label:has(input[type="checkbox"], input[type="radio"]) {
  font-weight: 500; color: var(--ink);
}
/* Grila formularului: două coloane, aceleași jgheaburi peste tot, iar câmpurile
   lungi ocupă tot rândul. Fără asta, fiecare formular își inventează lățimile
   și nimic nu se aliniază de la un ecran la altul. */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .85rem 1.1rem; }
.form-grid .fg-wide { grid-column: 1 / -1; }
.form-grid > div { display: flex; flex-direction: column; }
@media (max-width: 720px) { .form-grid { grid-template-columns: 1fr; } }

/* ── SECȚIUNE ÎN FORMULAR: titlu mic cu linie, nu încă un card ──────────── */
.form-section { margin-top: 1.5rem; }
.form-section:first-child { margin-top: 0; }
.form-section > h3 {
  font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0 0 .8rem; padding-bottom: .45rem;
  border-bottom: 1px solid var(--line-soft);
}

/* ── PROGRES LINIAR ─────────────────────────────────────────────────────── */
.stepline { margin: 0 0 1.4rem; }
.stepline-rail { position: relative; height: 2px; background: var(--line-soft); }
.stepline-fill { position: absolute; inset: 0 auto 0 0; background: var(--accent-btn); }
/* Sabolonul scrie `<ol><li>`, nu `<span>` — regula tintea alt element decat
   cel randat, deci pasii nu se asezau niciodata pe coloane egale. `> *` tine
   si daca marcajul se schimba din nou. */
.stepline-steps { display: flex; margin: .5rem 0 0; padding: 0; list-style: none; }
.stepline-steps > * { flex: 1 1 0; min-width: 0; font-size: .74rem; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-soft); }
.stepline-steps > * > a { color: inherit; text-decoration: none; }
.stepline-steps > * > a:hover b { text-decoration: underline; }
.stepline-steps b { display: block; font-weight: 600; font-size: .82rem;
  text-transform: none; letter-spacing: 0; color: inherit;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: .6rem; }
.stepline-steps .is-done { color: var(--ok); }
.stepline-steps .is-now { color: var(--accent-bright); }

/* ── BARĂ FIXĂ DE ACȚIUNI ──────────────────────────────────────────────── */
.action-bar {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-top: 1.6rem; padding: .8rem 0 .9rem;
  background: var(--bg); border-top: 1px solid var(--line);
}
.action-bar .hint { margin: 0; flex: 1 1 auto; text-align: center; }
.action-bar > a, .action-bar > button { white-space: nowrap; flex: 0 0 auto; }

/* ── PANOU LATERAL DE CONTEXT ──────────────────────────────────────────── */
.work-split { display: grid; grid-template-columns: minmax(0,1fr) 280px; gap: 0 1.6rem; align-items: start; }
@media (max-width: 1100px) { .work-split { grid-template-columns: 1fr; } }
.ctx-rail { border-left: 1px solid var(--line); padding: 0 0 0 1.4rem; position: sticky; top: 1rem; }
.ctx-rail h2 { font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0 0 .2rem; }
.ctx-item { padding: .6rem 0; border-bottom: 1px solid var(--line-soft); }
.ctx-label { display: block; font-size: .72rem; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-soft); }
.ctx-value { display: block; font-weight: 600; font-size: .92rem; margin-top: .1rem; }

/* ── NAVIGAȚIE: iconițe, rând activ cu bară, fără pastilă plină ─────────── */
.admin-nav-link { display: flex; align-items: center; gap: .6rem; border-radius: var(--radius-s); }
.nav-ico { width: 17px; height: 17px; flex: 0 0 17px; opacity: .65; }
.admin-nav-link:hover .nav-ico, .admin-nav-link.is-active .nav-ico { opacity: 1; }
.admin-nav-link.is-active {
  background: var(--neutral-bg); color: var(--accent-bright); font-weight: 600;
  box-shadow: inset 2px 0 0 var(--accent-btn);
}
.admin-nav-link.is-active .nav-badge { background: var(--accent-soft); color: var(--accent-bright); }
.nav-badge, .tag, .status-badge, .pill, .chip { border-radius: var(--radius-s); }
.side-foot-link { display: flex; align-items: center; gap: .6rem; padding: .32rem .55rem;
  font-size: .84rem; color: var(--ink-soft); text-decoration: none; border-radius: var(--radius-s); }
.side-foot-link:hover { background: var(--neutral-bg); color: var(--accent-btn); }
.side-foot-link .nav-ico { width: 15px; height: 15px; flex-basis: 15px; }

/* ── BARA DE SUS ───────────────────────────────────────────────────────── */
.coin-pill {
  display: inline-flex; align-items: baseline; gap: .4rem;
  padding: .24rem .55rem; border-radius: var(--radius-s); border: 1px solid;
  text-decoration: none; font-variant-numeric: tabular-nums; font-size: .84rem;
}
.coin-pill .coin-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor;
  align-self: center; flex: 0 0 6px; }
.coin-pill b { font-weight: 600; }
.coin-pill span { font-size: .74rem; opacity: .7; letter-spacing: .04em; text-transform: uppercase; }
.coin-pill--green { color: var(--ok); border-color: var(--ok-line); background: transparent; }
.coin-pill--red { color: var(--error); border-color: var(--error-line); background: transparent; }
.admin-engine { border-radius: var(--radius-s); }

/* ── BANDĂ DE INDICATORI ───────────────────────────────────────────────── */
.stat-strip { display: flex; padding: 0; }
.stat-strip > * { flex: 1 1 0; min-width: 0; padding: .85rem 1.1rem; display: flex; gap: .75rem; align-items: center; }
.stat-strip > * + * { border-left: 1px solid var(--line-soft); }
.stat-strip .nav-ico { width: 20px; height: 20px; flex-basis: 20px; opacity: .4; }
.stat-strip-value { display: block; font-size: 1.35rem; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat-strip-label { display: block; font-size: .7rem; letter-spacing: .03em; text-transform: uppercase;
  color: var(--ink-soft); margin-top: .15rem; line-height: 1.3; }
.stat-strip > * { min-width: 8.5rem; }
@media (max-width: 900px) {
  .stat-strip { flex-wrap: wrap; }
  .stat-strip > * { flex: 1 1 44%; }
  .stat-strip > * + * { border-left: 0; border-top: 1px solid var(--line-soft); }
}

/* ── TABELE: rânduri cu linie fină, antet mic ──────────────────────────── */
.data-table th { font-size: .7rem; letter-spacing: .08em; }
.data-table td, .data-table th { padding: .5rem .7rem; }

/* ── STARE GOALĂ ───────────────────────────────────────────────────────── */
.empty-state { text-align: center; padding: 2.6rem 1.5rem; }
.empty-state .nav-ico { width: 30px; height: 30px; flex-basis: 30px; opacity: .3; margin-bottom: .8rem; }
.empty-state h3 { margin: 0 0 .35rem; font-size: .95rem; font-weight: 600; }
.empty-state p { margin: 0 auto; max-width: 44ch; color: var(--ink-soft); font-size: .88rem; line-height: 1.55; }


/* ── EXCEPȚIA ASUMATĂ: INELUL DE ÎNCĂRCARE ─────────────────────────────────
   `.terminal-ring` de pe pagina de încărcare rămâne exact cum e — cu lumina,
   cu banda conică, cu tot (decizia lui Xprime, 09.09.2026: e semnătura vizuală
   a produsului și stă pe pagina cea mai văzută).

   Nu are nevoie de nicio regulă aici: nu folosește `--shadow`, `--grad` sau
   `--radius`, ci valori scrise la el în bloc. Nota există ca să nu fie „reparat"
   într-o zi de cineva care vede o umbră rămasă și crede că e o scăpare.
   Singurul lucru care îl atinge e `--panel` (fundalul din interiorul inelului),
   care coboară cu trei nuanțe odată cu restul suprafețelor — și trebuie să
   coboare, altfel inelul ar plana peste o pagină care nu mai are relief. */

/* Bara de sus a panoului de client capătă stânga (firimituri) și dreapta
   (solduri, cumpărare, cont) — până acum tot ce avea stătea aliniat la dreapta.
   2026-09-09. */
.panel-topbar { justify-content: space-between; padding: 0 0 .9rem; margin-bottom: 1.4rem;
  border-bottom: 1px solid var(--line); }
.panel-topbar-right { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; min-width: 0; }
@media (max-width: 900px) {
  .panel-topbar { align-items: flex-start; }
  .panel-topbar-right { width: 100%; }
}

/* ── TEXTUL DIN INELUL DE ÎNCĂRCARE, ÎN INTERIORUL CERCULUI ────────────────
   2026-09-09, raportat de Xprime cu o captură: numele fișierului și rândul
   „Max 32 MB…" ieșeau peste marginea inelului.

   CAUZA, și e geometrie, nu neatenție: conținutul era lat de 73% din DIAMETRU.
   Dar un cerc nu are 73% lățime utilă decât exact pe axa lui — pătratul înscris
   are latura de 70,7% din diametru (D/√2), iar orice rând aflat mai sus sau mai
   jos de centru dispune de și mai puțin. Cu 73%, primul rând lung de sub centru
   trecea peste bandă. Nu se vedea până când n-a apărut un nume de fișier lung.

   64% lasă o margine reală de fiecare parte, la orice înălțime din bloc. Iconița
   scade de la 70 la 56px ca blocul să rămână scurt pe verticală — cu cât e mai
   înalt, cu atât rândurile de la capete au mai puțin loc pe orizontală. */
.terminal-ring-content { width: 64%; max-width: 64%; }
.terminal-upload--gate .terminal-ring-content { width: 64%; }
.terminal-file-icon { width: 56px; height: 56px; margin-bottom: .7rem; }
.terminal-upload-limit { line-height: 1.35; }
.terminal-file-name { max-width: 100%; }

/* ── ȘI CENTRAT PE CERC, NU DOAR ÎNCADRAT ÎN EL ────────────────────────────
   2026-09-11, raportat de Xprime cu o captură: după ce alegi un fișier, tot
   blocul de text din inel stă mutat spre dreapta față de centrul cercului.

   CAUZA, măsurată: inelul e `display: grid`, iar coloana lui era implicită,
   deci dimensionată după conținut. Numele fișierului se scrie pe un singur
   rând (`white-space: nowrap`); la intrinsic sizing, `max-width: 100%` de pe
   el NU se ia în calcul — procentele se ignoră acolo — așa că un nume lung
   cerea coloanei toată lățimea textului. Coloana creștea peste caseta de
   conținut a inelului (314px într-un cerc care oferă 288px), ieșea în afară
   pe dreapta, iar blocul se centra în COLOANĂ, nu în cerc: 15px la dreapta.
   Fără fișier ales, numele e gol, coloana intra la loc și nimic nu se vedea —
   de asta se arată abia după ce omul alege fișierul.

   `minmax(0, 1fr)` fixează pista exact cât caseta inelului, pe amândouă axele:
   blocul nu mai poate împinge coloana, iar centrul lui rămâne centrul cercului
   la orice lățime. `min-width: 0` scoate dimensiunea minimă automată a
   elementului de grilă — fără ea, blocul s-ar umfla din nou după numele lung,
   iar tăierea cu trei puncte n-ar mai avea unde să se producă. */
.terminal-ring { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
.terminal-ring-content { min-width: 0; }

/* Același nume de fișier, în capul paginii de job și în cardul de procesare.
   Un nume de ECU e un singur cuvânt de șaizeci de caractere („yasee_friend_
   2BOSCH_EDC17CP47_INT_FLASH_0281020071.bin"): fără voie să se rupă, împinge
   pagina la 451px într-o coloană de 307px pe telefon — măsurat, la 390px, în
   toate limbile. Se rupe unde apucă; e un nume de fișier, nu o propoziție. */
.job-head .mono, .processing-file-name { overflow-wrap: anywhere; min-width: 0; }

/* ── WIZARDUL DE PROCESARE MANUALĂ, ÎN TON DE INSTRUMENT ───────────────────
   2026-09-09. Progresul devine liniar, panoul de context stă la dreapta, iar
   bara de acțiuni se lipește de baza ferestrei. Formularul rămâne același
   markup — se schimbă densitatea și alinierea. */

/* Progresul. `<ol>` cu numere, deci se citește și fără CSS și rămâne o listă
   ordonată pentru cititoarele de ecran. */
.stepline-steps { display: flex; margin: .55rem 0 0; padding: 0; list-style: none; }
.stepline-steps > li { flex: 1 1 0; min-width: 0; font-size: .74rem; letter-spacing: .06em;
  color: var(--muted); }
.stepline-steps > li a { color: inherit; text-decoration: none; }
.stepline-steps > li a:hover { color: var(--accent-btn); }
.stepline-steps > li b { display: block; font-weight: 600; font-size: .84rem; letter-spacing: 0;
  color: inherit; margin-top: .1rem; }
.stepline-steps .is-done { color: var(--ok); }
.stepline-steps .is-now { color: var(--accent-bright); }

/* Panoul de context. Flotant, ca formularul să curgă în stânga lui fără să fie
   nevoie de un `<div>` deschis într-un fișier și închis în altul — includerile
   parțiale nu suportă asta fără să devină imposibil de citit. */
.mfs-context {
  float: right; width: 270px; margin: 0 0 1.1rem 1.6rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); padding: .9rem 1.1rem;
}
.mfs-context h2 { font-size: .74rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0 0 .3rem; }
.mfs-context .ctx-item { padding: .55rem 0; border-bottom: 1px solid var(--line-soft); }
.mfs-context .ctx-item:last-child { border-bottom: 0; padding-bottom: 0; }
.mfs-context .ctx-label { display: block; font-size: .7rem; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-soft); }
.mfs-context .ctx-value { display: block; font-weight: 600; font-size: .88rem; margin-top: .12rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 1100px) {
  .mfs-context { float: none; width: auto; margin: 0 0 1.1rem; }
  .mfs-context .ctx-value { white-space: normal; }
}

/* Formularul: două coloane egale, jgheaburi identice, etichete mici cu
   majuscule. `minmax(230px, 1fr)` producea trei coloane pe ecran lat și una pe
   unul mediu — adică o grilă care se schimbă sub ochi. Două, mereu. */
.mfs-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .85rem 1.1rem; }
@media (max-width: 720px) { .mfs-grid-2 { grid-template-columns: 1fr; } }
.fld { display: flex; flex-direction: column; }
.fld-label { font-size: .72rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: .28rem; }
.mfs-form h2 { font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); margin: 1.5rem 0 .8rem; padding-bottom: .45rem;
  border-bottom: 1px solid var(--line-soft); }
.mfs-form > h2:first-of-type { margin-top: 0; }

/* Bara de acțiuni: rămâne la vedere cât timp se completează. Un formular lung
   pe care butonul „mai departe" stă sub trei ecrane de derulare îl face pe om
   să deruleze ca să afle dacă a terminat. */
.mfs-actions {
  position: sticky; bottom: 0; z-index: 5;
  margin-top: 1.4rem; padding: .8rem 0 .9rem;
  background: var(--bg); border-top: 1px solid var(--line);
  justify-content: space-between;
}
.mfs-actions > *:only-child { margin-left: auto; }
.mfs-actions .btn-primary, .mfs-actions .btn-small, .mfs-actions .btn-secondary { white-space: nowrap; }

/* ── FILE, NU PASTILE ──────────────────────────────────────────────────────
   Filele erau pastile late, cu colturi rotunde si fila activa umpluta cu
   accent — adica exact „colectia de pastile" pe care brieful B2B o scoate.
   Un instrument tehnic marcheaza fila curenta cu o linie sub ea si atat: se
   citeste ca un rand de file, nu ca un rand de butoane, si nu mai concureaza
   vizual cu butonul de salvare din aceeasi pagina.                           */
.report-tabs {
  gap: 0; margin: 0 0 1.4rem;
  border-bottom: 1px solid var(--line);
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.report-tab {
  padding: .58rem .95rem; border: 0; border-radius: 0; background: none;
  font-size: .84rem; font-weight: 600; color: var(--ink-soft);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  white-space: nowrap; flex: 0 0 auto;
}
.report-tab:hover { color: var(--ink); border-bottom-color: var(--line); }
.report-tab.is-active {
  background: none; color: var(--accent-bright);
  border-bottom-color: var(--accent-btn);
}

/* ── RAND DE BIFA / DE RADIO ───────────────────────────────────────────────
   `.check-row` era folosit in doisprezece locuri si nu avea NICIO regula: se
   baza pe stilul generic de `label`, deci controlul, numele optiunii si
   explicatia curgeau toate pe acelasi rand, iar explicatia se lipea de nume
   („Limit identification ... Off by default. While it is off ...").
   Aici: controlul intr-o coloana fixa, textul in a doua, explicatia dedesubtul
   textului, aliniata cu el. `position` + `padding-left` in loc de grid pentru
   ca numele optiunii e un nod de text liber, pe care grid-ul nu-l poate tinti. */
.check-row {
  display: block; position: relative; padding-left: 1.75rem;
  margin: 0 0 .7rem; cursor: pointer;
}
.check-row > input[type="checkbox"],
.check-row > input[type="radio"] {
  position: absolute; left: 0; top: .15rem; margin: 0;
}
.check-row .hint { display: block; margin-top: .2rem; }
.card .check-row + .check-row { margin-top: -.15rem; }
/* Randul de bifa nu e un nume de camp: nu primeste marginea de eticheta care
   il lipea de campul urmator. */
.card label.check-row, .form-grid label.check-row { margin-bottom: .7rem; }
/* Bifa compacta din interiorul unui rand de tabel: pe orizontala, fara marginea
   de eticheta. Era singura clasa de bifa fara nicio regula in foaie. */
.check-inline { display: inline-flex; align-items: center; gap: .4rem; margin: 0; white-space: nowrap; }
.card .check-inline, .form-grid .check-inline { margin-bottom: 0; }

/* ── CE CURGE LANGA PANOUL FLOTANT ─────────────────────────────────────────
   Panoul de context e `float: right`. Un bloc obisnuit de dupa el isi pune
   CUTIA sub panou si doar textul ocoleste — adica fundalul anuntului de intrare
   si al cardurilor trecea pe sub panou, si se vedea taiat la marginea lui.
   `display: flow-root` face din fiecare o cutie care se ingusteaza langa
   panou in loc sa treaca pe sub el. Nu `clear`, fiindca atunci s-ar duce toate
   sub panou si coloana din dreapta ar ramane cu un gol de un ecran langa ea. */
.mfs-entry-notice, .stepline, .mfs-form, .mfs-carried, .card.mfs-form { display: flow-root; }
@media (max-width: 1100px) {
  .mfs-entry-notice, .stepline, .mfs-form, .mfs-carried, .card.mfs-form { display: block; }
}
/* Panoul ramane la vedere cat se completeaza formularul — asta era rostul lui.
   Altfel dispare la prima derulare si omul tot trebuie sa se intoarca sus ca sa
   vada ce fisier completeaza. Sub 1100px panoul nu mai e flotant, deci nici
   lipit: acolo e un bloc obisnuit, deasupra formularului. */
@media (min-width: 1101px) { .mfs-context { position: sticky; top: 1rem; } }
/* Randul de limba iesea 1.1rem in afara subsolului din meniu: avea
   `margin: 0 -.55rem`, tras in afara ca fundalul de hover sa fie mai lat.
   Celelalte randuri din subsol (`.side-foot-link`) nu fac asta — deci randul de
   limba era si singurul care depasea, si singurul aliniat altfel. Aceeasi
   caseta ca vecinii lui. */
.panel-lang > summary { margin: 0; padding: .32rem .55rem; }
/* Precizarea „nu e acoperit de pachet" de pe ecranele fara iesire. Nu e o
   eroare si nu e o reclama: e conditia comerciala a butonului de sub ea. Deci
   nici rosie, nici colorata — un chenar fin la stanga, ca sa se citeasca
   inaintea butonului si sa nu se piarda printre celelalte randuri de hint. */
.manual-fallback-paid {
  margin-top: .7rem; padding: .6rem .8rem;
  border-left: 2px solid var(--line);
  background: var(--neutral-bg); color: var(--ink-soft);
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
}

/* Randul „un inginer o poate reconstrui manual — se plateste in coins rosii",
   pus sub mesajul de restaurare esuata (2026-09-12, cerinta Xprime). Nu e un
   hint sters: e informatia care lipsea din mesaj, deci se citeste la fel de
   tare ca el. `.coin-word--red` ii coloreaza singurul cuvant colorat. */
.manual-paid-line { margin: .5rem 0 0; }

/* ── EFECTUL CONFIGURATIEI, SCRIS 2026-09-14 (cerinta Xprime) ────────────────
   Sub „Identification limits": o fraza care spune ce face setul de comutatoare
   de dedesubt, si — cand e cazul — alarma ca face pe dos decat pare. Alarma nu
   e un hint: are greutatea unui mesaj de eroare, fiindca despre asta e vorba. */
.cfg-effect {
  margin: 0 0 1rem; padding: .6rem .8rem;
  border-left: 2px solid var(--accent-btn);
  background: var(--neutral-bg); color: var(--ink);
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
  font-size: .92rem; line-height: 1.5;
}
.cfg-alarm {
  margin: 0 0 .6rem; padding: .65rem .85rem;
  border-radius: var(--radius-s); font-size: .92rem; line-height: 1.5;
  font-weight: 500;
}
.cfg-alarm--bad  { background: var(--error-bg); color: var(--error); }
.cfg-alarm--warn { background: var(--warn-bg);  color: var(--warn-ink); }

/* ── MESAJE DE CONTACT SI SCRIS CATRE CLIENT 2026-09-10 ─────────────────── */
/* Randul necitit se marcheaza cu litera, nu cu fundal: peste el trece deja
   dunga de hover a tabelului, iar doua umpluri suprapuse fac randul ilizibil. */
.row-unread td { font-weight: 600; }
.row-unread td:first-child { box-shadow: inset 2px 0 0 var(--accent-btn); }
.msg-excerpt { color: var(--ink-soft); }

/* Scrisul catre client: doua butoane VIZIBILE, formularul se deschide sub ele.
   Varianta dinainte era un `<details>` al carui buton de deschidere se randa ca
   link cyan discret — functia exista, dar nu se citea ca buton, deci pentru
   cine o cauta pur si simplu nu era acolo. */
.msg-user-lead { margin: .7rem 0 0; max-width: 68ch; }
.msg-user-form { margin-top: 1.1rem; padding-top: 1.1rem; border-top: 1px solid var(--line-soft);
                 display: flex; flex-direction: column; gap: .2rem; }
.msg-user-form textarea { resize: vertical; }
.msg-user-form .device-actions { margin-top: 1rem; }

/* Corpul unui mesaj primit: latime de citit, nu cat cardul. */
.contact-body { max-width: 62ch; line-height: 1.6; margin: 0; }

/* Cifra care nu trebuie sa fie zero (email neplecat). */
.stat-strip-item.is-bad .stat-strip-value { color: var(--warn-bright); }

/* Invelis de tabel care deruleaza doar cand chiar e nevoie — fara latime minima
   impusa. `.report-table-wrap` ramane pentru rapoartele late, cu zeci de coloane. */
.table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Lista de mesaje: numele deasupra, adresa dedesubt, extrasul pe un rand cu
   trei puncte. Fara asta, numele si adresa curg pe acelasi rand, coloana „From"
   se lateste, iar „Lang" si butonul ies dincolo de marginea cardului. */
.cm-mail { display: block; font-size: .8rem; color: var(--ink-soft); }
.cm-table .msg-excerpt { display: block; max-width: 42ch; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.cm-table td { vertical-align: top; }
/* Lista de fapte pe PERECHI: eticheta si valoarea ei stau in aceeasi cutie,
   deci o valoare lunga nu mai desparte etichetele de valorile lor. */
.fact-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
             gap: 1rem 1.4rem; margin: 0; }
.fact-grid > div { min-width: 0; }
.fact-grid dt { font-size: .72rem; font-weight: 600; letter-spacing: .05em;
                text-transform: uppercase; color: var(--ink-soft); margin: 0 0 .2rem; }
.fact-grid dd { margin: 0; font-size: .95rem; font-weight: 600; overflow-wrap: anywhere; }
.fact-muted { color: var(--ink-soft); font-weight: 400 !important; }
.back-link { margin: 0 0 1.1rem; font-size: .86rem; }
/* Un buton invelit intr-un `<form>` (ca sa poarte jetonul CSRF) statea cu 9px
   mai jos decat vecinul lui care e simplu link: formularul e elementul de
   flex, nu butonul, iar inaltimea lui nu e a butonului. Formularul devine el
   insusi flex si nu mai adauga nimic — butonul se aliniaza cu restul randului. */
:is(.device-actions, .manual-fallback-actions, .diag-buttons, .mfs-actions) > form {
  display: flex; margin: 0;
}

/* Actiunea distrugatoare a randului, impinsa la capatul opus al actiunii
   principale: se citeste ca secundara si nu se nimereste din greseala langa
   „Save". Cand randul se rupe pe ecran ingust, marginea automata ar lasa-o
   singura la dreapta, asa ca acolo se anuleaza si intra in rand normal. */
.act-end { margin-left: auto; }
@media (max-width: 560px) {
  .act-end { margin-left: 0; }
}

/* ── BANDA DE EXPIRARE A PACHETULUI (migrarea 146) ─────────────────────────
   Chihlimbar, ca banda de dispozitiv: nimic nu s-a stricat, dar daca nu faci
   nimic se strica. Aceeasi forma, ca sa se citeasca la fel fara sa fie invatata
   inca o data — dunga la stanga, umplere ridicata, semn de exclamare desenat. */
.expiry-notice {
  border: 1px solid var(--warn-line);
  border-left: 4px solid var(--warn);
  background: var(--warn-bg-strong);
  padding-left: 1.15rem;
}
.expiry-notice h2 {
  display: flex; align-items: center; gap: .5rem;
  margin-top: 0; font-size: 1.05rem; color: var(--warn-bright);
}
.expiry-notice h2::before {
  content: "!"; flex: 0 0 auto;
  display: inline-grid; place-items: center;
  width: 1.35rem; height: 1.35rem;
  border: 1.5px solid currentColor; border-radius: 50%;
  font-size: .82rem; font-weight: 700; line-height: 1;
}
.expiry-notice p { margin-bottom: 0; max-width: 70ch; }
.expiry-notice .device-actions { margin-top: 1rem; }
.expiry-notice .btn-primary {
  background: var(--warn); border-color: var(--warn); color: #10202b;
}
.expiry-notice .btn-primary:hover, .expiry-notice .btn-primary:focus-visible {
  background: var(--warn-bright); border-color: var(--warn-bright); color: #10202b;
}
/* Sectiune pliata intr-un formular (limbile unui reminder). Marcajul implicit
   al browserului e inlocuit cu unul propriu, ca sa arate a control, nu a
   triunghi de sistem. */
.msg-user-toggle {
  cursor: pointer; list-style: none; padding: .55rem 0;
  font-size: .86rem; font-weight: 600; color: var(--accent-btn);
}
.msg-user-toggle::-webkit-details-marker { display: none; }
.msg-user-toggle::before { content: "+ "; }
details[open] > .msg-user-toggle { color: var(--ink); }
details[open] > .msg-user-toggle::before { content: "\2212 "; }

/* ── TICHETE PE TREI COZI (2026-09-29) ─────────────────────────────────────
   Filele cozilor folosesc aspectul `.report-tab`, dar NU banda derulabila a
   acestuia: pe telefon se rup pe al doilea rand. Regula operatorului (05.09):
   nicio intrare de navigare ascunsa dupa marginea ecranului. Cifra de pe fila
   e „open" — mingea la noi —; aprinsa doar cand e peste zero, ca sa sara in
   ochi coada care asteapta, nu toate trei deodata.                         */
.report-tabs.tk-pools { flex-wrap: wrap; overflow: visible; row-gap: .15rem; margin-bottom: .6rem; }
.tk-pool-tab { display: inline-flex; align-items: center; gap: .45rem; }
.tk-pool-n {
  display: inline-block; min-width: 1.45rem; padding: 0 .4rem; border-radius: 999px;
  font-size: .72rem; line-height: 1.35rem; text-align: center;
  background: var(--neutral-bg); color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
.tk-pool-n--on { background: var(--accent-btn); color: var(--accent-ink); }
.tk-pool-hint { margin: 0 0 1rem; max-width: 60rem; }
/* Eticheta de coada din lista „All" si din capul tichetului. Culoarea spune
   felul treburii: galben = de facut (sistemul n-a putut), albastru = urmare
   a unui fisier livrat, neutru = suport general.                            */
.tk-pool--reported  { background: var(--warn-bg); color: var(--warn-ink); }
.tk-pool--processed { background: var(--accent-soft); color: var(--accent-dark); }
.tk-pool--support   { background: var(--neutral-bg); color: var(--ink-soft); }

/* ── „CLIENTUL A FOST DEJA ANUNTAT" (2026-09-29) ───────────────────────────
   Bannerul din dosarul comenzii si semnul din lista. Verde = emailul „am
   rezolvat" a plecat; rosu = incercarea a cazut (clientul NU stie); neutru =
   tichet deschis cu clientul. Sta sub titlu, peste tot restul dosarului.     */
.told-banner {
  margin: 0 0 1rem; padding: .75rem 1rem; border-radius: 10px;
  border: 1px solid var(--line); border-left-width: 3px; background: var(--neutral-bg);
}
.told-banner--ok     { border-color: var(--ok); background: var(--ok-bg); }
.told-banner--failed { border-color: var(--error); background: var(--error-bg); }
.told-banner-head { margin: 0; }
.told-banner--ok .told-banner-head strong { color: var(--ok); }
.told-banner--failed .told-banner-head strong { color: var(--error); }
.told-banner-msg {
  margin: .55rem 0 0; padding: .45rem .8rem; border-left: 2px solid var(--line);
  color: var(--ink-soft); white-space: normal; overflow-wrap: anywhere;
}
.told-banner .hint { margin: .4rem 0 0; }
.told-inline { margin: 0 0 .45rem; font-size: .84rem; font-weight: 600; color: var(--ok); }
.told-badge {
  display: inline-block; margin-top: .25rem; padding: .08rem .5rem; border-radius: 999px;
  font-size: .7rem; font-weight: 600; white-space: nowrap;
  background: var(--ok-bg); color: var(--ok);
}
.told-badge--failed { background: var(--error-bg); color: var(--error); }

/* ── EMAIL NECONFIRMAT: cardul din fisa contului (2026-09-29) ─────────────
   Galben, ca un lucru de rezolvat: contul nu se poate loga. Tabelul cu
   emailurile trimise ramane ingust — doua coloane, nu un raport.            */
.unverified-card { border-left: 3px solid var(--warn-ink); }
.unverified-card h2 { margin-top: 0; color: var(--warn-ink); }
.unverified-card .unverified-mails { width: auto; min-width: 0; margin: .4rem 0 .6rem; }
.unverified-card .inline-form { margin-top: .6rem; }
/* Retrimiterea activarii, sub textul de dupa inregistrare / sub eroarea de
   autentificare: intrebarea si butonul pe acelasi rand, rupte pe telefon.   */
.resend-inline {
  display: flex; flex-wrap: wrap; gap: .5rem .8rem; align-items: center;
  justify-content: center; margin: 1rem 0 0;
}
.card.narrow:not(.center) .resend-inline { justify-content: flex-start; margin: 0 0 1rem; }
.resend-inline-q { font-size: .9rem; color: var(--ink-soft); }

/* ── SETARI: CARDURI CU ACEEASI CONSTRUCTIE (07.11.2026 seara, cerinta Xprime) ─
   „Site & modules" ajunsese un sir lung de explicatii. Fiecare card: titlu +
   pastila ON/off, o propozitie, bifele cu un rand de explicatie, starea
   motorului intr-o lista scurta, iar textul lung sub „How it works" (details),
   strans pana il deschizi. Aceleasi culori, fonturi si spatii ca restul. */
.settings-card h2 { display: flex; align-items: center; gap: .5rem; }
.settings-card h3 { margin: 1.1rem 0 .3rem; font-size: .95rem; }
.settings-more { margin: .1rem 0 .9rem; }
.settings-more > summary { cursor: pointer; list-style: none; font-size: .84rem; font-weight: 600; color: var(--accent-bright); }
.settings-more > summary::-webkit-details-marker { display: none; }
.settings-more > summary::before { content: "\25B8\00A0"; }
.settings-more[open] > summary::before { content: "\25BE\00A0"; }
.settings-more > .hint { margin: .45rem 0 0; }
.settings-status { display: grid; grid-template-columns: max-content 1fr; gap: .25rem .8rem; margin: .4rem 0 .9rem; font-size: .84rem; }
.settings-status > div { display: contents; }
.settings-status dt { color: var(--ink-soft); font-weight: 600; }
.settings-status dd { margin: 0; font-family: var(--mono); overflow-wrap: anywhere; }
.settings-group-list { border: 1px solid var(--line); border-radius: var(--radius-s); padding: .6rem .8rem .5rem; margin: 0 0 .9rem; }
.settings-group-list legend { font-weight: 600; font-size: .9rem; padding: 0 .3rem; }
.settings-group-list .check-inline { margin: .15rem 1rem .15rem 0; }
.settings-group-list > .hint { display: block; margin-top: .35rem; }

/* ── MODIFICARI DETECTATE (08.11.2026, GO Xprime) ─────────────────────────────
   Sub bannerul „Fisierul nu este original": ce modificari poarta deja fisierul,
   ca etichete (aceleasi nume scurte ca in oferta), plus o fraza neutra cand raman
   modificari nerecunoscute. Pe rândul din oferta: marcajul „deja in fisier".   */
.file-mods { margin: -0.5rem 0 1.1rem; padding: 0 .2rem; }
.file-mods-title { font-size: .84rem; font-weight: 600; color: var(--ink-soft); margin: 0 0 .35rem; }
.file-mods-list { display: flex; flex-wrap: wrap; gap: .4rem; }
.file-mod { font-size: .84rem; font-weight: 600; padding: .22rem .65rem; border-radius: 999px;
  background: var(--warn-bg); color: var(--warn-ink); border: 1px solid var(--warn-line); }
.file-mods-other { margin: .5rem 0 0; }
.opt-already { font-size: .7rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
  padding: .12rem .5rem; border-radius: 999px; background: var(--warn-bg); color: var(--warn-ink); border: 1px solid var(--warn-line); }

/* ECU-LAB DESKTOP (09.11.2026) — „modul aplicatie": aceleasi pagini, in coaja de Windows.
   Se ascunde doar ce e de browser public: meniul de sus si subsolul (paginile de vizitator),
   bannerul de cookie. Panoul ramane identic — bara laterala e meniul aplicatiei. */
/* 10.11.2026: selectorul `.main-nav a` ascundea si linkurile limbilor din lista `.lang-switch` (lista se deschidea goala).
   Acum: copii DIRECTI ai meniului. In coaja (`app-shell`) se ascund doar Files / Plans / Contact (`.nav-public`) — Login,
   Register si Cont raman; pe paginile din emailuri (browser, fara `app-shell`) antetul ramane fara linkuri. */
body.app-mode:not(.app-shell) .site-header .main-nav > a,
body.app-shell .site-header .main-nav > a.nav-public,
body.app-mode .site-footer,
body.app-mode .cookie-banner { display: none !important; }
body.app-mode .app-login-note { margin: 0 0 .9rem; padding: .6rem .8rem; border-radius: 3px;
  background: var(--accent-soft); border: 1px solid rgba(44,130,238,.35); color: var(--ink); font-size: .9rem; }

/* ── LISTA DE SOLUTII CU PICTOGRAME (13.11.2026, cerinta Xprime) ─────────────────────────────
   Fiecare solutie de pe pagina fisierului e un rand pe fundal albastru-gheata, alternat (ca in
   modelul trimis), cu pictogramele componentelor inaintea numelui: o combinatie arata
   pictogramele in linie, in ordinea din cod (Stage 1 · AdBlue · DPF · EGR). Doar randurile
   `.opt-sol`; celelalte `.opt` (destinatie, termeni, filtre) raman cum erau. */
.options-form fieldset:has(> .opt-sol) { padding-bottom: .55rem; }
.opt.opt-sol {
  background: #eef4fb;
  padding: .5rem .85rem;
  margin: 0 0 6px;
  min-height: 2.9rem;
  gap: .8rem;
  border-radius: 4px;
  transition: background-color .15s ease, box-shadow .15s ease;
}
.opt.opt-sol:nth-of-type(even) { background: #f6f9fd; }
.opt.opt-sol:last-child { margin-bottom: 0; }
.opt.opt-sol:hover { background: var(--accent-soft, #e6f0fd); }
.opt.opt-sol:has(input:checked) { background: var(--accent-soft, #e6f0fd); box-shadow: inset 3px 0 0 var(--accent-btn, #1f74e0); }
.opt.opt-sol.opt--locked:hover, .opt.opt-sol.is-disabled:hover { background: #eef4fb; }
.opt.opt-sol > .mono { font-weight: 600; color: var(--ink, #0e2342); letter-spacing: .01em; }
.opt.opt-sol.opt-sol--none > span { color: var(--ink-soft, #4a5d75); }
.opt-icons { display: inline-flex; align-items: center; gap: .2rem; flex: none; min-width: 40px; }
/* Pictograma are aer propriu in desen (umbra de sol), deci 40 px desenati ~ 30 px vizibili. */
.opt-ico { width: 40px; height: 40px; display: block; flex: none; margin: -6px 0; }
/* Custom DTC: acelasi rand, iar butonul isi spune numele intreg pe un singur rand. */
.dtc-custom .opt.opt-sol.opt-dtc { border-top: 0; margin-top: .75rem; padding-top: .5rem; }
.dtc-search .btn-primary { white-space: nowrap; }
@media (max-width: 560px) {
  .opt.opt-sol { flex-wrap: wrap; row-gap: .35rem; padding: .5rem .7rem; }
  .opt-ico { width: 34px; height: 34px; margin: -5px 0; }
  .opt-icons { gap: .1rem; min-width: 34px; }
}
