/* DOCUL DE MESAJE — cele două canale prin care pacienții trimit documente
   (handover §11.5), plus tot teatrul de fereastră din jurul lor.

   FIȘIER PROPRIU, nu o secțiune în styles-parity.css, din exact motivul pentru
   care acela s-a rupt din styles-pages.css: portarea ferestrei (66px strâns,
   434px extins, desprindere, mânere, loc rezervat) l-a trecut de plafonul de 600
   de rânduri. Cusătura e subiectul, nu numărul: docul nu e o pagină de paritate,
   e un component care trăiește în afara paginilor.

   LEGĂTURA DIN index.html STĂ IMEDIAT DUPĂ styles-parity.css ȘI ÎNAINTEA LUI
   styles-overlays.css, adică fix locul pe care regulile astea îl aveau cât erau
   în styles-parity.css: ordinea legăturilor E ordinea cascadei (LAYOUT.md §0).
   Contează într-un loc anume — `.page.active` de mai jos adaugă peste cel din
   styles-components.css, deci fișierul ăsta trebuie să vină după el.

   Marcajul e în web/partials/overlays.html; purtarea e în web/js/inbox.js
   (cutia poștală) și web/js/inbox-window.js (fereastra). */

/* ---- Docul de mesaje ------------------------------------------------------
   Cele două canale prin care pacienții trimit documente (handover §11.5).

   Stiva stă în afara paginilor (overlays.html) și se MUTĂ: pe Panou principal
   aterizează în `#inboxDock`, sub „Acțiuni rapide"; pe orice altă pagină
   plutește. Regulile de aici acoperă amândouă așezările, fiindcă e același nod
   mutat — nu două componente.

   TEATRUL DE FEREASTRĂ E PORTAT ACUM, ÎN ÎNTREGIME: forma mică de 66px, panoul
   extins de 434px lipit cu dreapta de coloană, desprinderea din coloană cu
   mouse-ul, cele trei mânere de redimensionare, locul rezervat cât e desprins și
   FLIP-ul perechii. LAYOUT.md §6 spunea că nu e portat; nu mai e adevărat, și
   nota de acolo e corectată în aceeași schimbare. Ce RĂMÂNE nefortat e bula de
   apel mutabilă — un alt component, refuzat pe alt argument (multi-linie).

   Z-INDEX-UL 290 E DELIBERAT SUB 300. În prototip 300 e bula unui apel în
   desfășurare: un apel viu trebuie să stea mereu deasupra conversațiilor scrise.
   Consola asta n-a portat bula, deci azi nimic nu ocupă 300 — numărul se
   păstrează oricum, fiindcă e o ierarhie, nu o valoare aleasă pentru un vecin
   care există azi.

   `--inbox-dur` STĂ ÎN CSS ȘI SE CITEȘTE DIN JS (inbox-window.js): cronometrul
   care încheie strângerea trebuie să cadă odată cu animația, nu înaintea ei —
   altfel panoul sare la forma mică din mers. O a doua constantă scrisă în JS ar
   fi exact duplicarea pe care o singură valoare o evită. */

.inbox-stack {
  --inbox-dur: 0.34s;
  /* Curba „emphasized" din Material: pornește hotărât și frânează lung, deci
     creșterea și strângerea par grele, nu smucite. */
  --inbox-ease: cubic-bezier(0.2, 0, 0, 1);
  /* Forma mică. Aceeași valoare o citește JS-ul pentru locul rezervat și pentru
     ținta animației de strângere. */
  --inbox-collapsed-h: 66px;
  display: flex;
  flex-direction: column;
  gap: var(--se-space-8);
}
/* `hidden` nu bate un `display: flex` scris de noi. Stiva nu se mai ascunde
   singură (vezi renderInbox), dar regula rămâne: `hidden` pus de altcineva
   trebuie să însemne ascuns. */
.inbox-stack[hidden] {
  display: none;
}
/* CÂT E POARTA TRASĂ, DOCUL NU EXISTĂ. Stiva e frate cu `.app-shell`, nu copil
   al ei, deci `body.gated .app-shell { display: none }` n-o atinge — iar de când
   stiva nu se mai ascunde singură când e goală (vezi renderInbox), fără regula
   asta numele și numerele pacienților ar sta pe ecran peste ecranul de
   autentificare, exact ce refuză LAYOUT.md §1. */
body.gated .inbox-stack {
  display: none;
}
/* Plutitoare: jos-dreapta. Nu se calcă nici cu bannerul de reapelare (sus,
   centrat) nici cu toastul (jos, centrat), și stă sub amândouă pe z-index —
   un mesaj așteaptă, o reapelare care pleacă în 5 secunde nu. */
.inbox-stack.floating {
  position: fixed;
  right: var(--se-space-20);
  bottom: var(--se-space-20);
  z-index: 290;
  align-items: flex-end;
  width: min(280px, calc(100vw - 2 * var(--se-space-20)));
}
.inbox-stack.floating .inbox-card {
  width: 100%;
}
.inbox-stack.floating .inbox-card.expanded {
  width: min(434px, calc(100vw - 2 * var(--se-space-20)));
}
/* Bara de sus e mânerul de tragere: în coloană doar cât panoul e deschis (acolo
   e ancorat), iar plutitoare mereu — acolo cele două sunt un doc care se mută
   întreg, chiar și strâns. */
.inbox-card.expanded .inbox-head,
.inbox-stack.floating .inbox-head {
  cursor: grab;
  user-select: none;
}
.inbox-card.dragging .inbox-head,
.inbox-stack.dragging .inbox-head {
  cursor: grabbing;
}
/* Cât e purtată cu mouse-ul, poziția trebuie să urmeze cursorul instantaneu —
   o tranziție ar face-o să alunece în urma lui. */
.inbox-stack.dragging {
  transition: none;
}

/* Cât ascunde stiva plutitoare din josul ferestrei. Pus de `syncDockSpace`
   (inbox.js) și rezervat aici, ca ultimul rând al unei pagini să rămână
   citibil sub ea. */
.page.active {
  /* + locul pastilei de apel (call-pill.js, `--pill-space`), care plutește deasupra docului. */
  padding-bottom: calc(var(--se-space-24) + var(--dock-space, 0px) + var(--pill-space, 0px));
}

/* Înălțimea fixă a formei mici e ce face animația posibilă: fără ea cardul e cât
   îl face conținutul, iar `height` nu are de la ce număr să plece. Extins,
   înălțimea o pune JS în px (sizeInboxWidget), ca să se poată anima ȘI să se
   strângă pe conversațiile pe care le are. */
.inbox-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  flex: none;
  height: var(--inbox-collapsed-h);
  background: var(--se-color-bg-surface);
  border: 1px solid var(--se-color-border-default);
  border-radius: var(--se-radius-lg);
  box-shadow: var(--shadow-card);
  /* `transform` NU e pentru cardul care se deschide, ci pentru perechea lui:
     cât unul crește sau se strânge, celălalt e împins de reflow-ul din flex,
     care nu se animă singur. JS îi dă un FLIP pe transform (flipCapture /
     flipRelease, inbox-window.js) ca să alunece odată cu el. */
  transition:
    width var(--inbox-dur) var(--inbox-ease),
    height var(--inbox-dur) var(--inbox-ease),
    left var(--inbox-dur) var(--inbox-ease),
    top var(--inbox-dur) var(--inbox-ease),
    transform var(--inbox-dur) var(--inbox-ease),
    box-shadow var(--inbox-dur) var(--inbox-ease),
    border-color 0.15s ease;
}
/* Extins PE LOCUL LUI din coloană: mai lat decât ea, lipit cu dreapta, ridicat
   peste conținutul din mijloc. Celălalt canal coboară sub el și rămâne vizibil,
   în forma mică. */
.inbox-card.expanded {
  width: 434px;
  max-width: calc(100vw - 2 * var(--se-space-16));
  align-self: flex-end;
  position: relative;
  z-index: 290;
  border-color: var(--se-color-border-default);
  box-shadow: var(--shadow-float);
}
/* Tras de bara de sus — de-acum stă pe ecran, nu în coloană. */
.inbox-card.expanded.detached {
  position: fixed;
  align-self: auto;
}
/* Cât e tras sau redimensionat, tranziția l-ar face să alerge în urma
   cursorului. */
.inbox-card.dragging,
.inbox-card.resizing {
  transition: none;
}

/* LOCUL REZERVAT în coloană cât timp cardul e desprins, ca celălalt widget să nu
   sară în sus și-napoi. `align-self: stretch` e OBLIGATORIU și e ușor de crezut
   decorativ: stiva plutitoare pune `align-items: flex-end`, iar un div gol ar
   avea atunci lățime zero — strângerea, care se întoarce animat exact în
   dreptunghiul lui, ar subția panoul până la nimic în loc să-l readucă la forma
   mică. */
.inbox-slot {
  flex: none;
  height: var(--inbox-collapsed-h);
  align-self: stretch;
}

/* Redimensionarea manuală: se trage de marginea din stânga (lățime), de cea de
   jos (înălțime) sau de colțul dintre ele (amândouă). Dreapta și sus stau pe
   loc, deci panoul crește spre stânga și-n jos, exact cum crește în design.
   Benzile sunt invizibile — le arată doar cursorul, ca la orice fereastră — iar
   colțul poartă un semn discret. Apar doar când mărirea chiar ajută (vezi
   resizeUseful): pe un fir deschis mereu, pe listă doar când sunt mai multe
   conversații decât încap. */
.inbox-resize {
  position: absolute;
  z-index: 6;
  display: none;
}
.inbox-card.expanded.resizable .inbox-resize {
  display: block;
}
.inbox-resize-w {
  left: 0;
  top: 0;
  bottom: 0;
  width: 6px;
  cursor: ew-resize;
}
.inbox-resize-s {
  left: 0;
  right: 0;
  bottom: 0;
  height: 6px;
  cursor: ns-resize;
}
.inbox-resize-sw {
  left: 0;
  bottom: 0;
  width: 16px;
  height: 16px;
  cursor: nesw-resize;
}
.inbox-resize-sw::before {
  content: "";
  position: absolute;
  left: 5px;
  bottom: 5px;
  width: 8px;
  height: 8px;
  border-left: 2px solid var(--se-color-primary-20);
  border-bottom: 2px solid var(--se-color-primary-20);
}
.inbox-head {
  display: flex;
  align-items: center;
  gap: var(--se-space-8);
  padding: var(--se-space-8) var(--se-space-12);
  /* `flex: none` e ce lasă corpul să ia restul înălțimii puse de JS pe card.
     Fără el antetul s-ar strânge și lista ar câștiga rânduri care nu există. */
  flex: none;
}
.inbox-main {
  display: flex;
  align-items: center;
  gap: var(--se-space-12);
  flex: 1 1 auto;
  min-width: 0;
  background: none;
  border: none;
  padding: 0;
  text-align: left;
}
/* Semnul canalului e LOGO-UL LUI, nu o iconiță funcțională într-o pastilă: marca
   ScanExpert și marca WhatsApp, 41×40, exact ca-n prototip
   (`.inbox-widget-mark` + `.inbox-widget-logo`, :1880-1881). De-aceea marca nu mai
   are nici fundal, nici rotunjire, nici mărime proprie — desenul le poartă pe ale
   lui, iar o pastilă în jurul unui logo de brand ar fi chrome adăugat peste ceva
   deja terminat. `position: relative` rămâne: bulina de necitite se agață de ea. */
.inbox-mark {
  position: relative;
  display: flex;
  flex: 0 0 auto;
}
.inbox-logo {
  flex: 0 0 auto;
  width: 41px;
  height: 40px;
}
/* Cifra e plafonată la 9+ în JS ca bulina să rămână mică și rotundă. */
.inbox-count {
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 18px;
  padding: 0 5px;
  border-radius: var(--se-radius-pill);
  background: var(--se-color-accent-pink);
  color: var(--se-color-text-on-dark);
  font-size: var(--se-type-micromed-size);
  line-height: var(--se-type-micromed-line);
  font-weight: var(--se-type-micromed-weight);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.inbox-count.hidden {
  display: none;
}
.inbox-info {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.inbox-title {
  font-size: var(--se-type-bodymed-size);
  line-height: var(--se-type-bodymed-line);
  font-weight: var(--se-type-bodymed-weight);
  color: var(--se-color-text-title);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Sub-eticheta unui rând, ca `.r-sub` din components — aceeași treaptă, ca
   docul să nu introducă un al doilea fel de rând pe același ecran. */
.inbox-sub {
  font-size: var(--se-type-captionreg-size);
  line-height: var(--se-type-captionreg-line);
  color: var(--se-color-text-description);
}
.inbox-back,
.inbox-expand {
  background: none;
  border: none;
  padding: 0;
  width: var(--se-size-hit-target);
  height: var(--se-size-hit-target);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  color: var(--se-color-text-muted);
}
.inbox-back:hover,
.inbox-expand:hover {
  color: var(--se-color-text-title);
}
.inbox-back .ph,
.inbox-expand .ph {
  width: var(--se-size-icon-functional);
  height: var(--se-size-icon-functional);
}
.inbox-back.hidden {
  display: none;
}

/* Strâns, corpul nu există; desfășurat, se derulează în el, niciodată crescând
   cardul peste ce e sub el — aceeași regulă ca `.list` (LAYOUT.md §3).
   Nu mai are un `max-height` propriu: înălțimea o dă cardul, pusă în px de
   sizeInboxWidget. Două plafoane pentru același lucru s-ar contrazice exact
   când operatorul trage de marginea de jos ca să vadă mai mult. */
.inbox-body {
  display: none;
}
.inbox-card.expanded .inbox-body {
  display: flex;
  flex-direction: column;
  gap: var(--se-space-8);
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: var(--se-space-12);
  border-top: 1px solid var(--se-color-border-divider);
}
/* Starea goală umple corpul de la margine la margine, ca-n prototip, unde lista
   n-are padding și `.inbox-empty` se centrează în tot ce a rămas
   (`.inbox-thread-list:has(> .inbox-empty)`, :1971). Padding-ul rândurilor ar
   adăuga 24px pe verticală unei stări care oricum trebuie să încapă. */
.inbox-card.expanded .inbox-body:has(> .inbox-empty) {
  padding: 0;
}

/* NICIO CONVERSAȚIE PE CANAL. Aceeași ilustrație și aceeași compoziție ca restul
   stărilor goale din consolă — de-aia poartă `.empty-state`, vocabularul care
   desenează deja golul din Conversație și din fișă, în loc de un al doilea fel de
   stare goală pe același ecran.

   NU ESTE ACELAȘI LUCRU CU LINIA DIN ANTET, ȘI CELE DOUĂ TREBUIE SĂ RĂMÂNĂ DOUĂ.
   Antetul canalului Aplicație spune „Fără sursă în consolă" — nimeni n-are pe unde
   să scrie; „0 mesaje noi" spune că n-a scris nimeni. Textul de aici e al
   designului, cuvânt cu cuvânt, și e despre conversații, nu despre sursă; el stă
   sub antet, deci afirmația canalului fără sursă rămâne pe ecran lângă el
   (renderHead, inbox.js). Vezi CLAUDE.md, „Docul de mesaje: canalele goale rămân". */
.inbox-empty {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: var(--se-space-16);
  background: var(--se-color-bg-console);
}
.inbox-empty p {
  max-width: 280px;
}

.inbox-thread {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--se-space-8);
  width: 100%;
  padding: 11px var(--se-space-12);
  background: var(--se-color-bg-surface);
  border: 1px solid var(--se-color-border-default);
  border-radius: var(--se-radius-md);
  text-align: left;
  flex: 0 0 auto;
}
.inbox-thread:hover {
  border-color: var(--se-color-primary-30);
}
.inbox-thread-who {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.inbox-thread .r-main {
  font-size: var(--se-type-bodyreg-size);
  line-height: var(--se-type-bodyreg-line);
  font-weight: var(--se-type-bodymed-weight);
  color: var(--se-color-text-title);
}
.inbox-thread .r-sub {
  font-size: var(--se-type-captionreg-size);
  line-height: var(--se-type-captionreg-line);
  color: var(--se-color-text-description);
}
/* Necitit poartă un punct ȘI o îngroșare — culoarea nu e niciodată singurul
   purtător (LAYOUT.md §3). */
.inbox-thread.is-unread .r-main {
  font-weight: var(--se-type-bodysb-weight);
}
.inbox-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--se-radius-pill);
  background: var(--se-color-accent-pink);
  flex: 0 0 auto;
}

.inbox-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px var(--se-space-12);
  background: var(--se-color-bg-surface);
  border: 1px solid var(--se-color-border-default);
  border-radius: var(--se-radius-md);
  flex: 0 0 auto;
}
.inbox-item[data-open-customer] {
  cursor: pointer;
}
.inbox-item[data-open-customer]:hover {
  border-color: var(--se-color-primary-30);
}
.inbox-item-main {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.inbox-item-ic {
  width: var(--se-size-icon-functional);
  height: var(--se-size-icon-functional);
  color: var(--se-color-primary-60);
  flex: 0 0 auto;
}
/* O sosire fără număr nu se poate deschide: regula firului spune că fără număr
   n-avem cui atașa conversația. Se vede retrasă, nu ascunsă. */
.inbox-item.is-orphan {
  border-style: dashed;
}
.inbox-item.is-orphan .inbox-item-ic {
  color: var(--se-color-text-muted);
}

/* Zvâcnetul de la sosire. Scurt și o singură dată — o cerere de atenție care se
   repetă încetează să mai fie una. */
@keyframes inbox-pulse {
  0% {
    transform: translateY(0);
  }
  35% {
    transform: translateY(-6px);
  }
  70% {
    transform: translateY(2px);
  }
  100% {
    transform: translateY(0);
  }
}
/* Durata și curba vin din sistemul de mișcare (--motion-*, definit o singură
   dată în styles-workspace.css): aceleași valori pentru toată consola. */
.inbox-card.pulse {
  animation: inbox-pulse var(--motion-dur-pulse) var(--motion-ease-spring);
}
@media (prefers-reduced-motion: reduce) {
  .inbox-card.pulse {
    animation: none;
  }
  /* Deschiderea și strângerea rămân, dar instantanee. Tranziția e ce cere
     mișcare; rezultatul ei nu. */
  .inbox-card {
    transition: none;
  }
}

/* O fotografie STAGED (W5, whatsapp.js) — locul iconiței de agrafă, doar când
   mesajul chiar poartă una. `object-fit: cover` peste o dimensiune fixă, ca
   rândul să nu sară în înălțime când o poză vine lată sau înaltă. */
.inbox-item-photo {
  width: var(--se-size-icon-functional);
  height: var(--se-size-icon-functional);
  border-radius: var(--se-radius-sm);
  object-fit: cover;
  flex: 0 0 auto;
}

/* Un mesaj vocal (W7) — în locul aceleiași agrafe, dar un player nu e o iconiță:
   îi trebuie lățime ca să aibă butoane, așa că ia rândul, nu casetă pătrată.
   `max-width` ca docul redimensionat îngust să nu-l împingă afară. */
.inbox-item-audio {
  height: var(--se-size-icon-functional);
  max-width: 100%;
  flex: 1 1 auto;
  min-width: 0;
}

/* Starea unui mesaj TRIMIS (W9, whatsapp-events-plan.js `failure`), după ora lui:
   „…" în coadă, „✓" plecat, „✓✓" livrat, „✓✓" colorat citit. Culoarea nu e
   singurul purtător — fiecare bifă are eticheta ei (title/aria-label). */
.inbox-item-status {
  margin-left: var(--se-space-8);
  color: var(--se-color-text-muted);
  white-space: nowrap;
}
.inbox-item-status[data-status='read'] {
  color: var(--se-color-primary-60);
}
/* Un mesaj netrimis: propoziția lui Meta și, când pagina mai are ce trimite,
   butonul „Reîncearcă" lângă ea, pe aceeași linie cât încape. */
.inbox-item-failed {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--se-space-8);
}

/* Răspunsul (W5, whatsapp.js) — ÎN AFARA #inboxBody-whatsapp dinadins, vezi
   overlays.html: acela e adus la zi rând cu rând (inbox-render.js), iar cutia
   nu e un rând. Arătat/ascuns numai de whatsapp.js, cât un fir WhatsApp e
   deschis. */
.inbox-reply {
  display: flex;
  flex-direction: column;
  gap: var(--se-space-8);
  padding: var(--se-space-12);
  border-top: 1px solid var(--se-color-border-divider);
  flex: 0 0 auto;
}
.inbox-reply[hidden] {
  display: none;
}
.inbox-reply-status {
  font-size: var(--se-type-captionreg-size);
  line-height: var(--se-type-captionreg-line);
  color: var(--se-color-text-description);
  min-height: 1em;
}
.inbox-reply-row {
  display: flex;
  gap: var(--se-space-8);
}
.inbox-reply-row input {
  flex: 1 1 auto;
  min-width: 0;
}

/* Sub 1150px coloanele de pe Panou principal se pun una sub alta (LAYOUT.md §2),
   deci docul ocupă toată lățimea. Panoul deschis n-are de ce să mai fie 434px
   lipiți în dreapta — se întinde cât ține locul lui. */
@media (max-width: 1150px) {
  .inbox-card.expanded {
    width: 100%;
    max-width: 100%;
    align-self: stretch;
  }
  .inbox-card.expanded.detached {
    width: calc(100vw - 2 * var(--se-space-16));
    max-width: calc(100vw - 2 * var(--se-space-16));
  }
}
/* Sub 700px panoul e deja cât ecranul, iar benzile de 6px de pe margini ar fura
   din zona de atins a listei. */
@media (max-width: 700px) {
  .inbox-card.expanded.resizable .inbox-resize {
    display: none;
  }
}
