/* GRAPHIT.EARTH — coaja platformei și componentele comune.
 *
 * Perechea lui tokens.css. Aici stă tot ce e crom: bara globală de stare, railul de capabilități,
 * sertarul de alarme, plus cele câteva componente pe care le repetau toate cele 17 pagini în
 * variante ușor diferite.
 *
 * PRINCIPIUL DE INTEGRARE — non-distructiv. Coaja NU restructurează corpul paginii. Bara și railul
 * sunt elemente `fixed`, iar conținutul existent e împins cu `padding` pe <body>. Alternativa
 * (împachetarea conținutului într-un container de grilă) e mai curată arhitectural, dar ar fi cerut
 * verificare vizuală pe fiecare pagină, iar cele patru pagini cu Cesium sunt cel mai delicat cod din
 * consolă. Toate elementele `position:fixed` care existau deja sunt toast-uri, o modală și un
 * meniu lateral glisant — niciunul nu e antet de pagină, deci niciunul nu intră în coliziune.
 *
 * PATRU MODURI, pe atributul `data-ge-mode` de pe <html>:
 *   console  — implicit. Bară + rail opace, conținutul e împins. Pentru panourile de lucru.
 *   atlas    — ca `console`, dar zona de lucru e o scenă 3D full-bleed. Pentru paginile-glob.
 *   dossier  — ca `console`, plus tipografie de lectură și reguli de tipar. Pentru dosare.
 *   bare     — fără crom. Pentru ecranul de perete: se citește de la 3–5 m, nu se atinge.
 */

/* ─────────────────────── ROLURI TIPOGRAFICE ───────────────────────
   Practica standard a sistemelor de design (Material 3 „type roles", IBM Carbon „type sets",
   Apple HIG „text styles") nu expune dimensiuni brute, ci ROLURI: fiecare leagă familia,
   dimensiunea, înălțimea de rând, greutatea și spațierea într-o singură decizie. Motivul e
   practic — cine scrie o pagină nouă alege „ăsta e un titlu de secțiune", nu „ăsta e 20 px cu
   1,3 și 600". Alegerea corectă devine cea mai ușoară.

   Trei familii, șapte dimensiuni, trei greutăți. Măsurătoarea de dinainte găsise 27 de
   dimensiuni distincte și 8 stive de font scrise literal — adică nicio scală, ci o acumulare.

   Scala: 12 · 13 · 14 · 16 · 20 · 24 · 32 — raport ≈1,2, aliniată la ritmul de 4 px peste 16. */

.ge-display   { font-family: var(--serif); font-size: var(--fs-3xl); line-height: var(--lh-tight);
                font-weight: var(--fw-bold); letter-spacing: var(--tr-display); text-wrap: balance; }
.ge-title     { font-family: var(--serif); font-size: var(--fs-2xl); line-height: var(--lh-title);
                font-weight: var(--fw-bold); text-wrap: balance; }
.ge-heading   { font-family: var(--sans);  font-size: var(--fs-xl);  line-height: var(--lh-title);
                font-weight: var(--fw-semi); }
.ge-subheading{ font-family: var(--sans);  font-size: var(--fs-lg);  line-height: var(--lh-snug);
                font-weight: var(--fw-semi); }
.ge-body-lg   { font-family: var(--sans);  font-size: var(--fs-lg);  line-height: var(--lh-read);
                font-weight: var(--fw-normal); max-inline-size: var(--measure); }
.ge-body      { font-family: var(--sans);  font-size: var(--fs-md);  line-height: var(--lh-body);
                font-weight: var(--fw-normal); }
.ge-label     { font-family: var(--sans);  font-size: var(--fs-sm);  line-height: var(--lh-snug);
                font-weight: var(--fw-semi); letter-spacing: var(--tr-label); }
.ge-caption   { font-family: var(--sans);  font-size: var(--fs-xs);  line-height: var(--lh-snug);
                font-weight: var(--fw-normal); color: var(--text-2); }
/* Eticheta de secțiune: mono, majuscule, spațiată. Singurul loc unde majusculele sunt permise —
   un text lung cu majuscule se citește cu ~15 % mai încet, deci se folosesc doar la 1–3 cuvinte. */
.ge-overline  { font-family: var(--mono);  font-size: var(--fs-xs);  line-height: var(--lh-snug);
                font-weight: var(--fw-semi); letter-spacing: var(--tr-overline);
                text-transform: uppercase; color: var(--text-2); }
/* Date: identificatori, coduri, marcaje de timp, valori. Cifre tabulare, ca o coloană să se
   poată citi pe verticală fără ca numerele să țopăie la reîmprospătare. */
.ge-data      { font-family: var(--mono);  font-size: var(--fs-sm);  line-height: var(--lh-snug);
                font-weight: var(--fw-normal); font-variant-numeric: tabular-nums; }
/* Ecranul de perete: se citește de la 3–5 m (ISO 11064-5), deci are propria podea. */
.ge-wall      { font-family: var(--sans);  font-size: var(--fs-wall); line-height: 1.35;
                font-weight: var(--fw-semi); }

/* ─────────────────────────── bază ─────────────────────────── */

/* Focus vizibil, o singură dată, pentru toată platforma. Înainte existau două apariții de
   :focus-visible pe 17 pagini. Contrastul inelului e ≥3:1 prin construcția tokenului. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Link de salt — prima oprire a navigării de la tastatură pe orice suprafață (WCAG 2.4.1). */
.ge-skip {
  position: fixed; inset-block-start: 0; inset-inline-start: 0;
  z-index: 200; transform: translateY(-120%);
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--accent); border-start-start-radius: 0; border-end-end-radius: var(--radius);
  padding: 10px 16px; font-family: var(--sans); font-size: var(--fs-md);
}
.ge-skip:focus { transform: translateY(0); }

.ge-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Text pentru arborele de accesibilitate, invizibil pe ecran. Folosit pentru titlurile paginilor
   al căror <h1> trăiește azi într-un antet grafic propriu: cititorul de ecran are nevoie de un
   titlu de nivel 1, ochiul nu are nevoie de încă unul. NU se folosește ca să ascundă conținut
   care ar trebui să fie vizibil. */
.ge-sr-only {
  position: absolute !important; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; white-space: nowrap;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}

.ge-ic {
  width: 20px; height: 20px; flex: none; display: block;
  stroke: currentColor; stroke-width: 1.5; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
  /* O icoană nu e niciodată ținta unui clic — e întotdeauna în interiorul unui buton sau al unei
     legături. Fără asta, `e.target` devine `<svg>`-ul, iar orice handler care citește direct
     `e.target.dataset.…` sau `e.target.id` primește `undefined`: butonul arată la fel și nu mai
     face nimic. Handlerele consolei folosesc `.closest()`, deci ar fi supraviețuit — dar regula
     ține și pentru cel care se scrie mâine, iar costul e o linie. */
  pointer-events: none;
}
.ge-ic.sm { width: 16px; height: 16px; }
.ge-ic.lg { width: 24px; height: 24px; }

/* Varianta pentru text CURENT. Implicitul `display:block` e corect în crom, unde icoana stă
   într-un container flex; în mijlocul unei fraze, într-un `pill` sau într-o celulă de tabel, un
   element bloc rupe rândul. Alinierea negativă așază glifa pe linia de bază optică a textului, nu
   pe cea geometrică — altfel icoana pare că plutește deasupra cuvântului de lângă ea. */
.ge-ic--i { display: inline-block; vertical-align: -.14em; }

/* Culoarea unei icoane de stare. Numele sunt prefixate, nu `.ok` / `.crit` scurte: paginile au deja
   selectoare compuse pe acele cuvinte (`.kpi.ok` colorează un chenar), iar o clasă scurtă definită
   global le-ar schimba și pe ele. `currentColor` face ca `color` să comande și conturul, și punctele
   semantice umplute din interiorul simbolului. */
.ge-ic--ok { color: var(--ok); }
.ge-ic--crit { color: var(--crit); }
.ge-ic--warn { color: var(--warn); }
.ge-ic--muted { color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .ge-bar, .ge-rail, .ge-drawer, .ge-skip, .ge-chip, .ge-btn { transition: none !important; }
  .ge-pulse { animation: none !important; }
}

/* ───────────── continuitatea cromului peste navigare ─────────────
   Platforma rămâne multi-pagină: fiecare suprafață e un document propriu, cu URL real, cu
   scripturile ei izolate — o pagină ruptă nu poate dărâma consola, iar o tură de 12 ore nu
   acumulează timere și contexte WebGL scăpate, cum s-ar întâmpla cu un router pe client.
   Ce se repara aici e doar PERCEPȚIA de reîncărcare: bara și railul erau redesenate de la zero
   la fiecare navigare și se vedeau apărând peste conținut.

   Tranziția între documente le declară aceeași identitate în ambele documente, deci browserul
   le tratează ca pe același element și le lasă pe loc; se schimbă doar conținutul. Condiția e
   ca ele să existe în noul document la prima ocazie de randare — de asta coaja se montează
   sincron (shell.js). Motoarele fără suport ignoră blocul și navighează normal.

   Durata e scurtă intenționat: în consolă, animația nu e decor, e latență percepută. */
@view-transition { navigation: auto; }

.ge-bar  { view-transition-name: ge-bar; }
.ge-rail { view-transition-name: ge-rail; }

::view-transition-old(root), ::view-transition-new(root) { animation-duration: 90ms; }
/* Cromul nu se estompează deloc: e ancora vizuală care spune că ești în aceeași aplicație. */
::view-transition-old(ge-bar), ::view-transition-new(ge-bar),
::view-transition-old(ge-rail), ::view-transition-new(ge-rail) { animation: none; mix-blend-mode: normal; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
    animation: none !important;
  }
}

/* ─────────────────────── împingerea conținutului ─────────────────────── */

/* Paginile în flux normal: padding pe <body>. Conținutul e împins, nimic nu se restructurează. */
html[data-ge-mode="console"] body,
html[data-ge-mode="dossier"] body {
  box-sizing: border-box;
  padding-block-start: var(--ge-bar-h);
  padding-inline-start: var(--ge-rail-w);
}

/* Modul atlas — MARGIN, nu padding, și ăsta e tot miezul.
   Paginile-glob nu au conținut în flux: au `#cesium{position:absolute;inset:0}` și panouri
   `position:absolute;top:46px;left:12px`. Un element absolut se rezolvă față de *caseta de
   padding* a blocului conținător, iar marginea stângă a acelei casete e tot la x=0 — deci
   padding-ul pe <body> NU-i deplasează cu nimic. Panoul de filtre din /sensors rămânea sub rail
   și textul lui apărea tăiat.
   Marginea, în schimb, mută caseta de bordură a lui <body> — deci și caseta de padding față de
   care se rezolvă copiii absoluți. Cu `position:relative` pe <body>, `inset:0` și `left:12px`
   încep amândouă de la colțul zonei de lucru. Cesium își redimensionează pânza după container,
   deci nu e nevoie de nimic în JavaScript.
   E și arhitectura convenită: V2 e un MOD în interiorul cojii V1, nu o aplicație separată. */
html[data-ge-mode="atlas"] { block-size: 100%; background: var(--bg); }
html[data-ge-mode="atlas"] body {
  box-sizing: border-box;
  position: relative;
  margin-block: var(--ge-bar-h) 0;
  margin-inline: var(--ge-rail-w) 0;
  padding: 0;
  block-size: calc(100vh - var(--ge-bar-h));
  overflow: hidden;
}

@media (max-width: 720px) {
  html[data-ge-mode="console"] body,
  html[data-ge-mode="dossier"] body { padding-inline-start: 0; padding-block-end: var(--ge-rail-w); }
  html[data-ge-mode="atlas"] body {
    margin-inline: 0;
    block-size: calc(100vh - var(--ge-bar-h) - var(--ge-rail-w));
  }
}

/* ───────────────────── STANDARD DE LĂȚIME ─────────────────────
   Suprafețele operaționale folosesc toată lățimea disponibilă; cele de lectură păstrează măsura.
   Regula bate plafoanele scrise în pagini (selector cu atribut = specificitate mai mare), deci
   nu trebuie atinsă nicio pagină. Modurile `atlas` și `bare` NU sunt incluse: acolo scena își
   gestionează singură spațiul, iar o regulă de lățime ar strica globurile. */
html[data-ge-mode="console"] main,
html[data-ge-mode="dossier"] main:not(.ge-read) {
  max-inline-size: none;
  inline-size: auto;
  margin-inline: 0;
  padding-inline: var(--ge-gutter);
}
@media (max-width: 720px) {
  html[data-ge-mode="console"] main,
  html[data-ge-mode="dossier"] main:not(.ge-read) { padding-inline: var(--ge-gutter-sm); }
}

/* Documentele de lectură — termeni, accesibilitate, despre — rămân o coloană CENTRATĂ.
   Acolo lățimea nu e o resursă, e un obstacol.

   O SINGURĂ măsură, nu două. Fișierul avea `var(--measure)` (68ch) aici și `78ch` mai jos, pe un
   selector mai puțin specific — deci a doua era moartă, iar intenția scrisă acolo nu se aplica
   niciodată. Rămâne 78ch: la 16 px asta dă ~730 px, o coloană care încape confortabil și tabelul
   de identitate din `/about`, nu doar proza. `--measure` (68ch) e calibrat pentru text de 14 px;
   aplicat la 16 px strângea documentele cu ~90 px degeaba. */
html[data-ge-mode="dossier"] main.ge-read {
  max-inline-size: 78ch;
  margin-inline: auto;
  padding-inline: var(--ge-gutter);
}

/* Într-un dosar cu tabele late, proza își păstrează măsura chiar dacă recipientul e lat.
   Regula e tipografică și se aplică doar textului curgător, nu celulelor sau etichetelor.

   `:not(.ge-read)` e esențial. Pe o suprafață de LECTURĂ (`/about`, `/termeni`, `/accesibilitate`,
   `/cookie`) recipientul E deja măsura — 78ch. Un al doilea plafon, de 68ch, pe paragrafele din
   el nu apăra nimic: doar făcea textul cu 10ch mai îngust decât coloana lui, iar nepotrivirea
   dintre paragraf și recipient e chiar ce se citește ca „rânduri rupte" — rânduri scurte cu alb
   nejustificat la dreapta. Regula are sens doar acolo unde containerul e LAT din alt motiv
   (tabele, matrici), nu unde e deja o coloană de citit. */
html[data-ge-mode="dossier"] main:not(.ge-read) > p,
html[data-ge-mode="dossier"] main:not(.ge-read) > section > p { max-inline-size: var(--measure); }

/* ─────────────────────────── bara globală ───────────────────────────
   Ține STAREA platformei, nu navigația. Navigația e railul; căutarea e paleta.
   Ce se vede permanent aici e ce nu are voie să dispară din ochii turei
   (ISO 11064-5, EEMUA 191): prospețimea, verdictul porții, numărul de alarme, ceasul UTC. */
.ge-bar {
  position: fixed; inset-block-start: 0; inset-inline: 0; z-index: 90;
  display: flex; align-items: center; gap: var(--s3);
  height: var(--ge-bar-h); padding-inline: var(--s3);
  background: var(--surface); border-block-end: 1px solid var(--line-control);
  font-family: var(--sans); font-size: var(--fs-sm); color: var(--ink);
}
/* În atlas, bara rămâne ancorată sus, pe toată lățimea — ca în console. Diferența dintre
   moduri e ce ocupă zona de lucru (o scenă 3D vs. un document), nu unde stă cromul. */
/* Sigla din bară — fișiere din kitul de marcă, suprapuse și comutate prin opacitate.
   Trei stări, trei fișiere, zero desenare proprie: alb pe temă închisă, negru pe temă deschisă,
   portocaliu la survolare și la focus. Suprapunerea (grid pe aceeași celulă) evită saltul de
   layout la schimbarea imaginii și păstrează tranziția sub 200 ms. */
.ge-bar__brand { display: inline-grid; align-items: center; text-decoration: none; }
.ge-bar__brand > .ge-logo { grid-area: 1 / 1; block-size: 40px; inline-size: auto;
  display: block; opacity: 0; transition: opacity var(--dur) var(--ease); }
@media (max-width: 900px) { .ge-bar__brand > .ge-logo { block-size: 32px; } }

/* Starea de repaus, după temă. Numele spun pe CE FUNDAL se pune sigla, nu ce culoare are:
   `--on-dark` e cerneala albă, `--on-light` e cea neagră.

   Toate regulile de stare sunt scrise cu ACELAȘI selector-părinte ca regula de bază. Prima
   versiune le scria fără el — `.ge-logo--on-dark` (o clasă) pierdea în fața lui
   `.ge-bar__brand > .ge-logo` (două clase), deci toate cele trei sigle rămâneau la opacitate 0
   și în bară nu se vedea nimic. */
.ge-bar__brand > .ge-logo--on-dark { opacity: 1; }
:root[data-theme="light"] .ge-bar__brand > .ge-logo--on-dark { opacity: 0; }
:root[data-theme="light"] .ge-bar__brand > .ge-logo--on-light { opacity: 1; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) .ge-bar__brand > .ge-logo--on-dark { opacity: 0; }
  :root:not([data-theme]) .ge-bar__brand > .ge-logo--on-light { opacity: 1; }
}
/* La survolare și la focus, marca — pe orice temă. */
.ge-bar__brand:hover > .ge-logo, .ge-bar__brand:focus-visible > .ge-logo { opacity: 0; }
.ge-bar__brand:hover > .ge-logo--brand,
.ge-bar__brand:focus-visible > .ge-logo--brand { opacity: 1; }
/* FORMA siglei se alege după lățimea disponibilă, nu după gust. Foaia de reguli a pachetului de
   marcă (docs/GRAPHIT.EARTH_brand_pack/06_utilizare/reguli.md) dă lockup-ului complet un minim de
   180 px lățime pe ecran și cere trecerea la forma mai simplă sub prag — „nu se micșorează
   lockup-ul". Cu viewBox 653,22×120: la 40 px înălțime lockup-ul are 218 px (peste prag), la
   32 px ar avea 174 px (sub prag). Deci sub 900 px intră `signature`, aceeași siglă fără motto.
   `display` bate `opacity`, deci regulile de temă de mai sus rămân valabile pe forma activă. */
.ge-bar__brand > .ge-logo--sig { display: none; }
@media (max-width: 900px) {
  .ge-bar__brand > .ge-logo--lock { display: none; }
  .ge-bar__brand > .ge-logo--sig { display: block; }
}
@media (max-width: 1100px) { .ge-bar__motto { display: none; } }
@media (max-width: 640px)  { .ge-bar__rule, .ge-bar__stack { display: none; } }

/* ─────────────── contul: ultimul element din bară ───────────────
   Declanșatorul e un cerc cu inițiale, nu o icoană generică: pe o platformă cu conturi nominale
   și urmă de audit, prima informație utilă e CINE ești acum — un cont greșit deschis într-o filă
   uitată semnează acțiuni în numele altcuiva. Inițialele o spun fără să coste lățime.
   Meniul se ancorează la dreapta, sub bară, și se închide la Escape sau la clic în afară. */
.ge-acct { position: relative; display: flex; align-items: center; }
.ge-acct__btn {
  display: grid; place-items: center; inline-size: 30px; block-size: 30px;
  border-radius: 50%; border: 1px solid var(--line-control); background: none;
  color: var(--ink); font-family: var(--sans); font-size: var(--fs-xs);
  font-weight: var(--fw-semi); cursor: pointer; padding: 0;
}
.ge-acct__btn:hover { background: var(--surface-2); border-color: var(--accent); }
.ge-acct__btn[aria-expanded="true"] { background: var(--accent-soft); border-color: var(--accent); }
.ge-acct__menu {
  position: absolute; inset-block-start: calc(100% + 8px); inset-inline-end: 0; z-index: 100;
  inline-size: 260px; padding: var(--s2); border-radius: var(--radius);
  border: 1px solid var(--line-control); background: var(--surface);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .28);
}
.ge-acct__head { padding: var(--s2) var(--s3) var(--s3); border-block-end: 1px solid var(--line);
  margin-block-end: var(--s2); }
.ge-acct__name { font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--ink); }
.ge-acct__mail { font-family: var(--mono); font-size: var(--fs-xs); color: var(--text-2);
  overflow-wrap: anywhere; }
.ge-acct__chips { display: flex; flex-wrap: wrap; gap: var(--s1); margin-block-start: var(--s2); }
.ge-acct__item {
  display: block; inline-size: 100%; text-align: start; min-block-size: 32px;
  padding: 7px var(--s3); border: 0; border-radius: var(--radius); background: none;
  color: var(--text-2); font-family: var(--sans); font-size: var(--fs-md);
  text-decoration: none; cursor: pointer;
}
.ge-acct__item:hover, .ge-acct__item:focus-visible { background: var(--surface-2); color: var(--ink); }
.ge-acct__out { margin: var(--s2) 0 0; padding-block-start: var(--s2);
  border-block-start: 1px solid var(--line); }

/* Mottoul. Rămâne în engleză în toate limbile interfeței — un motto e un element de marcă,
   nu conținut: se traduce la fel de puțin ca numele platformei. */
.ge-motto { font-family: var(--sans); letter-spacing: .14em; text-transform: uppercase;
  color: var(--brand-earth); font-size: var(--fs-xs); font-weight: 600; }
.ge-motto--lg { font-size: var(--fs-lg); letter-spacing: .22em; }

/* ─────────── meniul secundar al documentelor publice ───────────
   Se montează DOAR pe cele patru suprafețe publice (/about, /accesibilitate, /termeni, /cookie)
   și nicăieri altundeva: sunt singurele pagini pe care le poate deschide cineva care nu are cont,
   deci singurele care au nevoie de o navigație proprie. Rail-ul global rămâne alături — el duce
   la capabilități, care cer autentificare; meniul ăsta duce la documente, care nu cer.

   E ÎN PAGINĂ, lângă text — nu o a doua bandă de crom lipită de fereastră. Prima versiune îl
   fixase de viewport, cu fundal și chenar pe toată înălțimea: arăta ca o prelungire a rail-ului,
   iar textul rămânea împins la 288 px de marginea ferestrei. Acum e o coloană în flux, care
   însoțește cititorul pe măsură ce coboară (`sticky`) și se oprește deasupra textului pe ecran
   îngust. Inserat ÎNAINTE de <main>, deci ordinea de citire e corectă și fără reguli de `order`.

   `body` devine container flex DOAR pe aceste patru pagini — de aici selectorul cu atribut. */
html[data-ge-docnav] body {
  display: flex; align-items: flex-start; gap: var(--s6);
}
.ge-docnav {
  flex: 0 0 var(--ge-docnav-w);
  position: sticky; inset-block-start: calc(var(--ge-bar-h) + var(--s5));
  padding-block: var(--s7) var(--s5); padding-inline: var(--ge-gutter) 0;
}
.ge-docnav__title { margin: 0 0 var(--s3); }
.ge-docnav a {
  display: block; min-block-size: 24px; padding: 7px 10px; margin-block-end: 2px;
  border-radius: var(--radius); border-inline-start: 2px solid transparent;
  color: var(--text-2); font-size: var(--fs-md); line-height: var(--lh-snug); text-decoration: none;
}
.ge-docnav a:hover { background: var(--surface-2); color: var(--ink); }
.ge-docnav a[aria-current="page"] {
  background: var(--surface-2); color: var(--ink); font-weight: var(--fw-semi);
  border-inline-start-color: var(--brand-earth);
}
/* REVENIT la centrare. Am fixat cândva coloana la stânga (`margin-inline: 0 auto`), ca să nu
   rămână un gol între meniu și text. Leacul a fost mai rău decât boala: cu ~590 px de text și
   ~550 px de nimic în dreapta, pagina arăta ca o randare eșuată, nu ca un document.
   `margin-inline: auto` pe un element flex centrează în spațiul RĂMAS după meniu, deci albul se
   împarte simetric — ceea ce se citește ca intenție, nu ca defect. Golul de lângă meniu e prețul,
   și e prețul corect: o coloană de lectură se centrează, nu se lipește de crom. */
html[data-ge-docnav][data-ge-mode="dossier"] main.ge-read { margin-inline: auto; }

@media (max-width: 900px) {
  html[data-ge-docnav] body { display: block; }
  .ge-docnav {
    position: static; display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center;
    padding: var(--s3) var(--ge-gutter); border-block-end: 1px solid var(--line);
  }
  .ge-docnav__title { inline-size: 100%; margin: 0 0 var(--s1); }
  .ge-docnav a { margin-block-end: 0; border-inline-start: 0; border-block-end: 2px solid transparent; }
  .ge-docnav a[aria-current="page"] { border-block-end-color: var(--brand-earth); }
}

/* ── starea preluată din sesiune, până la prima confirmare ──
   Bara pornește de la ultima valoare cunoscută ca să nu clipească pe fiecare navigare, dar nu
   are voie să o prezinte ca proaspătă. Marcajul e dublu, fiindcă un singur canal nu ajunge:
   VIZUAL o linie punctată sub indicatori (nu doar opacitate — o culoare mai palidă nu e o
   informație, e o ambiguitate), și TEXTUAL prin `aria-description`, care spune momentul.
   Se stinge singur la prima interogare reușită, de obicei sub o secundă. */
.ge-bar[data-stale] .ge-sev,
.ge-bar[data-stale] .ge-chip {
  border-block-end: 1px dotted currentColor;
  opacity: .72;
}

.ge-bar__sep { inline-size: 1px; block-size: 22px; background: var(--line); flex: none; }
.ge-bar__spacer { flex: 1 1 auto; min-inline-size: var(--s2); }
.ge-bar__clock { font-family: var(--mono); font-size: var(--fs-xs); color: var(--text-2);
  font-variant-numeric: tabular-nums; white-space: nowrap; }

/* „live" e o afirmație despre date, nu un ornament: pulsează doar cât timp ultima interogare a
   reușit. Când linia tace, se stinge și trece pe tonul de nedeterminat — un punct verde care
   pulsează peste date vechi induce în eroare mai rău decât absența lui. */
.ge-bar__live { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-family: var(--mono); font-size: var(--fs-xs); color: var(--sev-indet); }
.ge-bar__live[data-live="1"] { color: var(--sev-clear); }
.ge-bar__live[data-live="0"] .ge-pulse { animation: none; opacity: .45; }
@media (max-width: 900px) { .ge-bar__live span:last-child { display: none; } }
@media (max-width: 900px) { .ge-bar__clock { display: none; } }

/* Contextul paginii, în bara globală: „GRAPHIT.EARTH · Sănătate și poartă de calitate".
   Înlocuiește antetul de marcă pe care îl repeta fiecare pagină.

   LĂȚIME FIXĂ, nu maximă — și asta e toată diferența. Cu `max-inline-size`, caseta se strânge
   pe numele scurte („Portal", 6 caractere) și se întinde pe cele lungi („Termeni și condiții de
   utilizare", 32), deci indicatorii de stare săreau ~164 px de la o pagină la alta. Informația
   de stare trebuie să stea în ACELAȘI loc pe toate suprafețele: operatorul o caută din reflex,
   nu o citește căutând-o. `flex: none` ține caseta la dimensiunea rezervată chiar și când bara
   se înghesuie, iar ce nu încape se taie cu puncte de suspensie (numele întreg rămâne în `title`). */
.ge-bar__ctx {
  flex: none;
  inline-size: var(--ge-ctx-w);
  color: var(--text-2); font-size: var(--fs-sm);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Pe ecrane mai strâmte locul se micșorează, dar rămâne FIX: proprietatea care contează e
   poziția constantă, nu mărimea. Sub 1000 px dispare de tot — railul și titlul paginii spun
   oricum unde ești, iar bara are nevoie de spațiu pentru stare. */
@media (max-width: 1280px) { :root { --ge-ctx-w: 22ch; } }
@media (max-width: 1000px) { .ge-bar__ctx { display: none; } }

/* ───────────────── antetele duplicate ale paginilor ─────────────────
   Fiecare pagină avea propria bară cu marca, ceasul UTC și un set de legături de navigare —
   exact cele trei lucruri pe care le dă acum coaja. Duplicarea nu e doar urâtă: două ceasuri
   care nu se actualizează sincron sunt o sursă reală de confuzie într-o tură.

   Se ascunde prin CSS, nu se șterge din marcaj, deliberat: scripturile paginilor scriu în
   `#clock` și în alte noduri din bară. Ascunse, continuă să funcționeze; șterse, ar arunca.

   `all`  — bara nu conținea decât duplicat → dispare întreagă.
   `part` — bara are controale proprii (verdictul gărzii, starea scenei, capabilitățile) →
            dispar doar piesele duplicate, restul rămâne. */
[data-ge-dup="all"] { display: none !important; }
[data-ge-dup="part"] > .brand,
[data-ge-dup="part"] > .live,
[data-ge-dup="part"] > .clock,
[data-ge-dup="part"] > .navlinks { display: none !important; }

/* ─────────────────────────── railul ─────────────────────────── */
.ge-rail {
  position: fixed; inset-block: var(--ge-bar-h) 0; inset-inline-start: 0; z-index: 80;
  inline-size: var(--ge-rail-w);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding-block: var(--s2); overflow-y: auto; overflow-x: hidden;
  background: var(--surface); border-inline-end: 1px solid var(--line);
}
/* Icoanele de NAVIGARE poartă culoarea mărcii. Cele de STARE nu: severitatea își păstrează
   propria culoare și formă, altfel marca ar începe să semnaleze ceva. */
/* Icoanele de navigare urmează exact regula siglei: ton neutru în repaus, culoarea mărcii la
   survolare, la focus și pe pagina curentă. Cromul rămâne sobru, iar culoarea de marcă devine
   un semnal de interacțiune — nu un fundal permanent care ar concura cu paleta de stare. */
.ge-rail a {
  display: grid; place-items: center; inline-size: 38px; block-size: 38px;
  border-radius: 8px; color: var(--text-2); text-decoration: none; flex: none;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.ge-rail a:hover, .ge-rail a:focus-visible { background: var(--surface-2); color: var(--brand-earth); }
.ge-rail a[aria-current="page"] { background: var(--accent-soft); color: var(--brand-earth); }

/* Intrarea „Despre platformă" din rail poartă sigla, cu aceleași trei stări ca bara:
   neutră după temă, marca la survolare și la focus. Aceleași fișiere din kit, la 20 px. */
.ge-rail__brand { position: relative; display: grid; place-items: center; }
.ge-rail__brand > .ge-logo { grid-area: 1 / 1; inline-size: 20px; block-size: 20px;
  opacity: 0; transition: opacity var(--dur) var(--ease); }
.ge-rail__brand > .ge-logo--on-dark { opacity: .72; }
:root[data-theme="light"] .ge-rail__brand > .ge-logo--on-dark { opacity: 0; }
:root[data-theme="light"] .ge-rail__brand > .ge-logo--on-light { opacity: .72; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) .ge-rail__brand > .ge-logo--on-dark { opacity: 0; }
  :root:not([data-theme]) .ge-rail__brand > .ge-logo--on-light { opacity: .72; }
}
.ge-rail__brand:hover > .ge-logo, .ge-rail__brand:focus-visible > .ge-logo { opacity: 0; }
.ge-rail__brand:hover > .ge-logo--brand,
.ge-rail__brand:focus-visible > .ge-logo--brand { opacity: 1; }

/* Utilitar: orice icoană care trebuie să poarte marca, oriunde în conținut. */
.ge-ic--brand { color: var(--brand-earth); }
.ge-rail__spacer { flex: 1 1 auto; min-block-size: var(--s4); }
@media (max-width: 720px) {
  .ge-rail { inset-block: auto 0; inset-inline: 0; inline-size: auto; block-size: var(--ge-rail-w);
    flex-direction: row; justify-content: flex-start; padding-inline: var(--s2);
    border-inline-end: 0; border-block-start: 1px solid var(--line-control); }
}

/* ─────────────────────── sertarul de alarme ───────────────────────
   Se deschide din chipul de alarme al barei. Deliberat NU e permanent deschis: pe un laptop de 13"
   ar mânca o treime din lățime. Cerința operațională — starea de alarmare mereu vizibilă — e
   satisfăcută de chipul din bară, care poartă severitatea maximă și numărul; coada în sine se
   deschide la nevoie, fără să părăsești pagina. */
.ge-drawer {
  position: fixed; inset-block: var(--ge-bar-h) 0; inset-inline-end: 0; z-index: 95;
  inline-size: min(var(--ge-drawer-w), 92vw);
  display: flex; flex-direction: column;
  background: var(--surface); border-inline-start: 1px solid var(--line-control);
  transform: translateX(101%); transition: transform var(--dur) var(--ease);
  font-size: var(--fs-sm);
}
.ge-drawer[data-open="1"] { transform: none; }
.ge-drawer__head { display: flex; align-items: center; gap: var(--s2);
  padding: var(--s3) var(--s4) var(--s2); border-block-end: 1px solid var(--line); }
.ge-drawer__title { font-family: var(--mono); font-size:var(--fs-xs); letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-2); margin: 0; font-weight: 400; }
.ge-drawer__list { overflow-y: auto; flex: 1; }
.ge-alarm { display: flex; gap: 10px; padding: 11px var(--s4);
  border-block-end: 1px solid var(--line); text-decoration: none; color: inherit; }
.ge-alarm:hover { background: var(--surface-2); }
.ge-alarm__t { font-size: var(--fs-sm); line-height: 1.35; margin: 0 0 3px; }
.ge-alarm__m { font-family: var(--mono); font-size:var(--fs-xs); color: var(--text-2); margin: 0; }
.ge-drawer__foot { padding: var(--s3) var(--s4); border-block-start: 1px solid var(--line); }

/* ─────────────────────────── componente ─────────────────────────── */

/* Severitate: culoare + FORMĂ + text. Niciodată doar culoare (WCAG 1.4.1, IEC 60073).
   Formele vin din icons.svg (`sv-*`) și sunt distincte în alb-negru, la 12 px. */
/* Cifre de lățime egală: fără ele, „56/56" → „4/56" rebalansează tot ce urmează la fiecare
   interogare de 60 s. E aceeași problemă ca numele paginii, doar la scară mai mică — și apare
   sub ochii cuiva care tocmai se uită la indicator. */
.ge-bar .ge-sev, .ge-bar .ge-chip { font-variant-numeric: tabular-nums; }

.ge-sev { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs);
  white-space: nowrap; }
.ge-sev svg, .ge-sevmark { inline-size: 12px; block-size: 12px; flex: none; }
/* Un SVG fără dimensiune intrinsecă se întinde la lățimea containerului. Marca de severitate
   ajunge și în chipuri care nu au `.ge-sev` ca ancestor, deci clasa proprie e obligatorie. */
.ge-sev--crit  { color: var(--sev-crit); }
.ge-sev--major { color: var(--sev-major); }
.ge-sev--minor { color: var(--sev-minor); }
.ge-sev--warn  { color: var(--sev-warn); }
.ge-sev--indet { color: var(--sev-indet); }
.ge-sev--clear { color: var(--sev-clear); }

/* Ținta rămâne ≥24 px chiar în modul compact — prin înălțime minimă, nu prin dimensiunea
   vizuală a chenarului (soluția permisă explicit de WCAG 2.5.8). */
.ge-chip { display: inline-flex; align-items: center; gap: 6px; min-block-size: 24px;
  padding: 3px 9px; border-radius: var(--radius-pill); border: 1px solid var(--line-control);
  background: none; color: var(--text-2); font-family: var(--mono); font-size:var(--fs-xs);
  white-space: nowrap; cursor: pointer; }
.ge-chip:hover { background: var(--surface-2); color: var(--ink); }
.ge-chip[aria-pressed="true"], .ge-chip.is-on {
  border-color: var(--accent); color: var(--accent-ink); background: var(--accent-soft); }
/* Selectorul de limbă e un <select> nativ, îmbrăcat ca un chip: aspectul sistemului de design,
   comportamentul platformei. */
.ge-lang { appearance: none; -webkit-appearance: none; padding-inline-end: 22px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 13px) 50%, calc(100% - 9px) 50%;
  background-size: 4px 4px, 4px 4px; background-repeat: no-repeat; }
.ge-lang option { background: var(--surface); color: var(--ink); }

.ge-chip--static { cursor: default; }
.ge-chip--static:hover { background: none; color: var(--text-2); }

.ge-btn { display: inline-flex; align-items: center; gap: 7px; min-block-size: 32px;
  padding: 7px 13px; border-radius: var(--radius); border: 1px solid var(--line-control);
  background: none; color: var(--ink); font-family: var(--sans); font-size: var(--fs-sm);
  cursor: pointer; text-decoration: none; }
.ge-btn:hover { background: var(--surface-2); }
.ge-btn--primary { border-color: var(--accent); color: var(--accent-ink); background: var(--accent-soft); }

.ge-iconbtn { display: grid; place-items: center; inline-size: 30px; block-size: 30px;
  border-radius: var(--radius); color: var(--text-2); background: none; border: 0; cursor: pointer; }
.ge-iconbtn:hover { background: var(--surface-2); color: var(--ink); }

/* Starea goală spune DE CE e goală. `empty` = nu s-a produs nimic; `starved` = nu a venit nimic
   de la sursă. Distincția e calculată de products/emptiness.py, dar interfața o afișa la fel:
   nimic. Componenta o face vizibilă fără să inventeze o categorie nouă. */
.ge-empty { display: flex; align-items: flex-start; gap: 9px; padding: var(--s3) var(--s4);
  color: var(--sev-indet); font-size: var(--fs-xs); line-height: 1.5; }
.ge-empty strong { color: var(--ink); font-weight: 600; }

.ge-prov { display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-family: var(--mono); font-size:var(--fs-xs); color: var(--text-2); }
.ge-prov b { font-weight:600; color: var(--ink); }

.ge-kv { display: grid; grid-template-columns: auto 1fr; gap: 5px var(--s3);
  font-size: var(--fs-xs); margin: var(--s2) 0; }
.ge-kv dt { font-family: var(--mono); font-size:var(--fs-xs); color: var(--text-2);
  text-transform: uppercase; letter-spacing: .06em; }
.ge-kv dd { margin: 0; font-variant-numeric: tabular-nums; }

/* Numerele nu au voie să țopăie la actualizare: o coloană de distanțe de miss care se mișcă
   la fiecare refresh e o eroare de lizibilitate, nu un detaliu. */
.ge-num, td.num, .num { font-variant-numeric: tabular-nums; text-align: end; white-space: nowrap; }

.ge-pulse { inline-size: 8px; block-size: 8px; border-radius: 50%; background: currentColor;
  animation: ge-pulse 1.8s ease-in-out infinite; }
@keyframes ge-pulse { 0%, 100% { opacity: .3 } 50% { opacity: 1 } }

/* ─────────────────────────── modul dosar ───────────────────────────
   Tipografie de lectură + tipar. Dosarul e livrabil: se tipărește direct ca anexă,
   fără export separat, cu cromul scos și cu proveniența păstrată. */
/* Măsura de lectură se declară o dată, la §„standard de lățime" — nu se repetă aici. */
html[data-ge-mode="dossier"] .ge-read h1 { font-family: var(--serif); font-size: var(--fs-2xl);
  line-height: 1.15; }

@media print {
  .ge-bar, .ge-rail, .ge-drawer, .ge-skip, .gp-ov { display: none !important; }
  html[data-ge-mode="console"] body, html[data-ge-mode="dossier"] body {
    padding: 0 !important; background: #fff !important; color: #000 !important; }
  .ge-prov { color: #333 !important; }
  a[href^="/"]::after { content: " (" attr(href) ")"; font-size:var(--fs-xs); color: #555; }
}

/* ───────────────────── CONTROALE DE PANOU — o convenție, un proprietar ─────────────────────
   DE CE AICI. Șase pagini își defineau fiecare propriul `.seg`/`.tog`. Când panoul globului a trecut
   pe contururi, /satelliti a rămas pe casete native: același filtru de regim arăta altfel pe două
   ecrane legate prin click. Aceeași cauză ca la culorile de regim (vezi `--regime-*` în tokens.css)
   — o regulă locală duplicată divergează. Se mută aici, unde ambele pagini o citesc.

   PREFIXUL `ge-` E OBLIGATORIU: o regulă neprefixată aici ar fi suprascrisă de copia locală a
   fiecărei pagini, fiindcă `<style>`-ul din pagină se încarcă DUPĂ acest fișier și câștigă la
   specificitate egală. Neprefixată n-ar fi partajare, ar fi CSS mort.

   CONVENȚIA, într-o propoziție: o familie (mono), două mărimi, starea pe CONTUR și pe text, nu ca
   umplere. `aria-pressed` e singura sursă de adevăr — o citesc și cititorul de ecran și filtrarea,
   deci nu pot să diveargă (casetele native aveau `.checked` separat de orice etichetă ARIA). */
.ge-tog { display: inline-flex; flex-wrap: wrap;
          /* Canal LOCAL, nu token de paletă: JS îl pune per buton cu culoarea categoriei. Declarat
             cu implicit, ca un grup fără culoare să aibă totuși stare vizibilă. */
          --tog-c: var(--accent); }
.ge-seg { display: inline-flex; }
.ge-seg.ge-fill { width: 100%; }
.ge-tog button, .ge-seg button {
  position: relative; cursor: pointer; background: transparent; color: var(--text-2);
  font-family: var(--mono); font-size: var(--fs-sm); padding: 4px 10px;
  border: 1px solid var(--line); border-left-width: 0; border-radius: 0;
  /* Eticheta stă pe UN rând: „vârsta stării” se rupea în două și înălța tot grupul, iar un
     segment cu butoane de înălțimi diferite nu mai citește ca un singur control. Rândul de
     filtre are deja `flex-wrap`, deci la lățime mică se rupe grupul, nu textul din buton. */
  white-space: nowrap; }
.ge-seg button { flex: 1; padding: 4px 8px; text-align: center; }
.ge-tog button:first-child, .ge-seg button:first-child { border-left-width: 1px; border-radius: 6px 0 0 6px; }
.ge-tog button:last-child,  .ge-seg button:last-child  { border-radius: 0 6px 6px 0; }
.ge-tog button:only-child,  .ge-seg button:only-child  { border-radius: 6px; }
/* `z-index`: marginea colorată nu trebuie acoperită de conturul neutru al vecinului. */
.ge-tog button[aria-pressed="true"] { color: var(--tog-c); border-color: var(--tog-c);
                                      border-left-width: 1px; z-index: 1; }
.ge-seg button[aria-pressed="true"] { color: var(--accent); border-color: var(--accent);
                                      border-left-width: 1px; z-index: 1; }
.ge-tog button[aria-pressed="true"] + button,
.ge-seg button[aria-pressed="true"] + button { border-left-width: 0; }
/* Comutator singular (nu într-un grup lipit): același desen, contur închis pe toate laturile. */
.ge-tgb { cursor: pointer; text-align: left; background: transparent; color: var(--text-2);
          border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px;
          font-family: var(--mono); font-size: var(--fs-sm); }
.ge-tgb[aria-pressed="true"] { color: var(--accent); border-color: var(--accent); }
.ge-tog button:hover, .ge-seg button:hover, .ge-tgb:hover { color: var(--ink); }
.ge-tgb:hover { border-color: var(--line-control); }
/* `select` rămâne NATIV — accesibilitatea și tastatura vin gratuit — dar poartă chenarul sistemului
   în loc de desenul sistemului de operare, ca să nu fie al treilea limbaj de control pe ecran. */
.ge-sel { background: transparent; color: var(--ink); border: 1px solid var(--line);
          border-radius: 6px; padding: 3px 7px; font-family: var(--mono); font-size: var(--fs-sm);
          appearance: none; background-image: none; cursor: pointer; }
.ge-sel:hover { border-color: var(--line-control); }
.ge-sel optgroup, .ge-sel option { background: var(--surface); color: var(--ink); }

/* ───────────────────── compatibilitate cu paginile existente ─────────────────────
   Meniul lateral glisant din /governance pornea de la marginea ferestrei; acum pornește
   de la marginea railului, ca să nu treacă pe sub el. Singura ajustare de acest fel. */
html[data-ge-mode="console"] nav.side { inset-inline-start: var(--ge-rail-w) !important; }
@media (max-width: 720px) { html[data-ge-mode="console"] nav.side { inset-inline-start: 0 !important; } }

/* Panourile plutitoare ale paginilor-glob își calculau înălțimea din `100vh`, adică din fereastră.
   Zona de lucru e acum mai scundă cu înălțimea barei, deci un panou dimensionat în `vh` ar trece
   dincolo de marginea de jos. Se recalculează din `100%` — adică din zona de lucru, care e
   exact ce a vrut autorul lor să zică prin „tot ecranul". */
html[data-ge-mode="atlas"] #panel,
html[data-ge-mode="atlas"] .panelbox { max-block-size: calc(100% - 58px) !important; }
