/* components.css — owned by the Styling/UX agent.
 * Rich component styling on top of base.css. Uses ONLY design tokens from
 * variables.css. Mobile-first; dark mode via prefers-color-scheme at the end.
 *
 * Targets the real markup in index.html:
 *   .task-card.state-<status>, .task-toggle, .btn-camera, .temp-display.ok/.bad,
 *   .numpad, .ring, .bar, .badge.s-<status>, .chip.active, .sheet/.sheet-backdrop,
 *   .tabbar, cards/rows, breadcrumb, toast, empty, disclaimer.
 *
 * Status colour/icon/text are encoded DOUBLY in markup; CSS reinforces with the
 * coloured left border, tinted toggle, badge colour and subtle background.
 */

/* =========================================================================
 * 0. Status palette helper (single source for the 6 task states)
 *    pending = "De facut" | done = "Facuta" | alert = "Neconforma"
 *    missed = "Restanta"  | await = "Asteptare dovada"
 *    (a 6th visual "alerta/!" reuses the alert family per the brief)
 * ====================================================================== */

/* =========================================================================
 * 1. App header polish
 * ====================================================================== */
.app-header {
  box-shadow: var(--shadow-sm);
  backdrop-filter: saturate(1.1);
}
.app-header .title h1 {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: -0.01em;
}
/* Header location switcher: an explicit pill button so "change location" is
   obvious (was just a subtle ▾ chevron on the plain title). */
.app-header .title { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-1); }
.loc-btn { display: inline-flex; align-items: center; gap: var(--sp-1); max-width: 100%; padding: var(--sp-1) var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-full); background: var(--surface); color: var(--text); font: inherit; cursor: pointer; transition: background .12s, border-color .12s; }
.loc-btn:hover { background: var(--surface-2); border-color: var(--brand); }
.loc-btn:active { transform: scale(.98); }
.loc-btn-pin { width: 15px; height: 15px; flex: none; color: var(--brand); }
/* Lab logo in the header location button (replaces the pin when a logo is set). */
.loc-btn-logo { width: 22px; height: 22px; flex: none; border-radius: var(--radius-full); object-fit: cover; }
.loc-btn-name { font-size: var(--fs-lg); font-weight: 700; line-height: 1.1; letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.loc-btn-cta { flex: none; font-size: var(--fs-xs); font-weight: 700; color: var(--brand); text-transform: uppercase; letter-spacing: .03em; padding-left: var(--sp-2); border-left: 1px solid var(--border); }
.app-header .icon-btn {
  font-size: 28px;
  line-height: 1;
  color: var(--brand);
  margin-left: calc(var(--sp-2) * -1);
}

/* =========================================================================
 * 2. Buttons — tactile feedback, accessible focus, primary depth
 * ====================================================================== */
.btn {
  border: 1px solid transparent;
  transition: transform .06s ease, background-color .12s ease, box-shadow .12s ease;
  user-select: none;
  -webkit-user-select: none;
}
.btn:active { transform: scale(.97); }
.btn:not(.btn-ghost) { box-shadow: var(--shadow-sm); }

.btn-primary { background: var(--brand); color: var(--on-color); }
.btn-primary:active { background: var(--brand-dark); box-shadow: none; }

.btn-ok { background: var(--ok); color: var(--on-color); }
.btn-ok:active { filter: brightness(.93); }

.btn-danger { background: var(--error); color: var(--on-color); }
.btn-danger:active { filter: brightness(.93); }

.btn:not(.btn-primary):not(.btn-ok):not(.btn-danger):not(.btn-ghost) {
  background: var(--bg);
  color: var(--text);
  border-color: var(--border);
}
/* Ghost buttons used to be transparent + transparent border → invisible on
   white cards. Give them a light fill + visible border so they always read as
   buttons (no white-on-white). */
.btn-ghost { box-shadow: none; background: var(--surface); border-color: var(--border); color: var(--text); }
@media (hover: hover) { .btn-ghost:hover { background: var(--surface-2); } }
.btn-ghost:active { background: var(--surface-2); }
/* keep the destructive ghost actions tinted red */
.btn-ghost[style*="--error"] { color: var(--error); }
/* Destructive variants used app-wide (instead of ad-hoc inline error styles):
   ghost/outline for row-level delete actions, icon-only for trash icon-btns. */
.btn-ghost-danger { color: var(--error); }
.btn-danger-outline { background: var(--bg); border-color: var(--error); color: var(--error); }
.icon-btn-danger { color: var(--error); }

.icon-btn {
  transition: background-color .12s ease, transform .06s ease;
}
.icon-btn:active { transform: scale(.92); }

/* =========================================================================
 * 3. Cards & rows — softer surface, clear tap affordance for navigable rows
 * ====================================================================== */
.card {
  transition: box-shadow .15s ease;
}

.row {
  min-height: var(--touch-primary);
  transition: background-color .12s ease, transform .06s ease;
  text-align: left;
  width: 100%;
}
button.row { font: inherit; color: inherit; }
button.row:active { background: var(--surface); transform: scale(.995); }
.row > span:last-child {
  color: var(--text-muted);
  font-size: var(--fs-lg);
  flex: none;
}
.row small { color: var(--text-muted); }

/* =========================================================================
 * 4. Filter chips — pill toggles, scrollable on narrow screens
 * ====================================================================== */
.chips {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--sp-1);
}
.chips::-webkit-scrollbar { display: none; }
/* When chips sit inline in a flex row (e.g. next to a heading as a view
   switcher), the default bottom margin skews vertical centering — drop it. */
.flex > .chips { margin-bottom: 0; }
/* Opt-out of the scroll-strip behaviour: chips that must all stay visible
   (month pickers, tab strips inside sheets) wrap instead of scrolling. */
.chips.flex-wrap { flex-wrap: wrap; overflow: visible; }
/* Tab strips inside sheets (object hub: Sarcini/Documente/Detalii/Comentarii/
   Istoric) must never hide tabs off-screen behind an invisible scroll. */
.sheet .chips { flex-wrap: wrap; overflow: visible; }
.chip {
  flex: none;
  cursor: pointer;
  transition: background-color .12s ease, color .12s ease, border-color .12s ease, transform .06s ease;
}
.chip:active { transform: scale(.96); }
.chip.active {
  background: var(--brand);
  color: var(--on-color);
  border-color: var(--brand);
  box-shadow: var(--shadow-sm);
}

/* =========================================================================
 * 5. Progress — global ring + linear bar
 * ====================================================================== */
.ring svg circle:last-child {
  transition: stroke-dashoffset .4s ease;
}
.ring .ring-label {
  font-variant-numeric: tabular-nums;
  color: var(--brand-dark);
  font-size: var(--fs-sm);
}
.bar {
  height: 10px;
  background: var(--surface-2);
}
.bar > i {
  background: linear-gradient(90deg, var(--brand), var(--ok));
  transition: width .35s ease;
}

/* Progress summary card — give its numbers presence. Scoped by class so it
   doesn't leak into every other dashboard card (task-card titles inherited
   the big size before and wrapped worse on phones). */
.progress-stat strong { font-size: var(--fs-lg); }
/* One-line progress strip at the very top of "De făcut". Sticks below the app
   header while scrolling (mobile AND desktop — the document is the scroll
   container on both, see .app-main note in responsive.css) so today's progress
   stays in view. Styled as a card (border + radius + shadow) to match the
   surrounding elements; opaque background covers content scrolling underneath.
   Fixed height (--progress-strip-h) lets the feed's sticky zone headers stack
   exactly beneath it. */
.progress-strip {
  display: flex; align-items: center; gap: var(--sp-1) var(--sp-2); font-size: var(--fs-sm);
  position: sticky; top: var(--header-h); z-index: 4;
  height: var(--progress-strip-h);
  padding: 0 var(--sp-3);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--sp-3);
}
.progress-strip strong { font-size: var(--fs-base); font-variant-numeric: tabular-nums; }
/* min-width keeps the bar readable — it must not collapse next to the badges. */
.progress-strip .bar { height: 6px; min-width: 48px; border-radius: var(--radius-full); overflow: hidden; }
.progress-strip .badge { flex: none; }
/* Separate the "azi" signals from the historical CAPA register and the location
   shortcut so the sticky strip reads as three groups, not one crowded line. */
/* Registru CAPA — buton compact în bandă (a înlocuit cardul pe rând propriu). */
.progress-strip-capa {
  display: inline-flex; align-items: center; gap: var(--sp-1); flex: none;
  margin-left: var(--sp-2); padding: 2px var(--sp-2);
  border: 1px solid var(--border); border-radius: var(--radius-full);
  background: var(--surface); color: var(--text); font-size: var(--fs-sm); cursor: pointer;
}
.progress-strip-capa:active { transform: scale(.97); }
.progress-strip-capa .badge { min-height: 0; padding: 0 var(--sp-1); }
/* Cu neconformități active: evidențiat roșu (același limbaj ca .feed-note-alert). */
.progress-strip-capa.is-alert {
  color: var(--error-text);
  background: color-mix(in srgb, var(--error) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--error) 35%, var(--border));
}
.progress-strip-capa.is-alert .icn { color: var(--error); }
.progress-strip-loc { margin-left: var(--sp-2); }
/* Multi-location overview shortcut, tucked at the end of the progress strip
   (replaces the old full-width "Prezentare toate locațiile" block button). The
   subtle border keeps it discoverable as a tap target next to the progress bar. */
.progress-strip-loc { flex: none; border: 1px solid var(--border); background: var(--surface); color: var(--text-muted); }
.progress-strip-loc:active { transform: scale(.94); }

/* --- "De făcut" feed filters: dropdown-uri Status + Categorie pe UN rând ------
   Au înlocuit cele două benzi de chips (ocupau 2-3 rânduri). Pe același rând stă
   și bannerul „Filtru activ" (.ff-inline) — pe ecrane înguste trece pe rândul
   următor prin wrap. Chrome-ul <select> (mărime, caret, 16px iOS) vine din
   regulile de bază — aici doar layout + captions. */
.feed-filters-m { display: flex; align-items: flex-end; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.ff-m-field { flex: 1 1 150px; min-width: 0; max-width: 240px; display: flex; flex-direction: column; gap: var(--sp-1); }
.ff-m-field > span { font-size: var(--fs-xs); font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .03em; }
/* Bannerul „Filtru activ" în varianta inline din rândul de filtre: ocupă restul
   rândului și preia geometria select-urilor (aceeași înălțime/rază/padding),
   păstrând doar tenta accent ca semnal de filtru activ. */
.feed-active-filter.ff-inline {
  flex: 1 1 260px; margin-bottom: 0;
  align-self: flex-end; align-items: center;
  min-height: var(--touch-min);
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--radius-sm);
}
.feed-active-filter.ff-inline .btn { padding: var(--sp-1) var(--sp-2); min-height: 0; }
/* Fixed-width severity badge in queues ("critic"/"atenție"/"info") so row
   labels start at the same x and the list scans as a column. */
.badge-sev { min-width: 4.5em; justify-content: center; }

/* =========================================================================
 * 6. Status badges — keep colour + provide subtle ring for contrast
 * ====================================================================== */
.badge {
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge.s-pending { background: var(--info-light); color: var(--info-text);  border-color: color-mix(in srgb, var(--info) 25%, transparent); }
.badge.s-done,
.badge.s-ok      { background: var(--ok-light);   color: var(--ok-text);    border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
.badge.s-alert   { background: var(--error-light); color: var(--error-text); border-color: color-mix(in srgb, var(--error) 30%, transparent); }
.badge.s-missed  { background: var(--warn-light);  color: var(--warn-text);  border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.badge.s-await   { background: var(--await-light); color: var(--await-text); border-color: color-mix(in srgb, var(--await) 30%, transparent); }
.badge.s-skipped,
.badge.s-none    { background: var(--surface-2); color: var(--text-muted); border-color: var(--border); }
/* CCP marker badge — distinct from the alert (non-conformity) fill: an OUTLINED
   red chip so a solid red fill means "problem", while CCP means "critical point". */
.badge.ccp { background: transparent; color: var(--error-text); border: 1px solid var(--error); font-weight: 700; letter-spacing: .04em; }
/* Asset code badge — visible neutral chip (a bare .badge has transparent
   background/border and reads as floating bold text). Used app-wide.
   FIXED width (not min-width): every code chip is the same size regardless of
   the code inside, so code-first rows align into a scannable column. Codes
   longer than the chip get ellipsed (the full code stays in the row tooltip). */
.badge-code {
  background: var(--surface-2); color: var(--text-muted); border-color: var(--border);
  font-variant-numeric: tabular-nums;
  display: inline-block; width: 4.25rem; max-width: 4.25rem;
  text-align: center; overflow: hidden; text-overflow: ellipsis; vertical-align: middle;
}
/* importance level badge */
.badge.imp { background: var(--surface-2); color: var(--text-muted); border-color: var(--border); }
.badge.imp.imp-5 { background: var(--error-light); color: var(--error-text); }
.badge.imp.imp-4 { background: var(--warn-light); color: var(--warn-text); }
/* Minor = solid neutral chip; Optional = faded + dashed so "can be skipped" reads
   at a glance and it's clearly distinct from Minor. */
.badge.imp.imp-2 { background: var(--surface-2); color: var(--text-muted); }
.badge.imp.imp-1 { background: transparent; color: var(--text-muted); border: 1px dashed var(--border); opacity: .9; }
/* CCP badge sits on alert family in markup but means "critical" — make it bold */
.task-card .badge.s-alert[title] { letter-spacing: .04em; font-weight: 700; }

/* =========================================================================
 * 7. TASK CARD — 6 states, coloured left border, tinted surface
 *    Status colours come from --st-<status> tokens in variables.css.
 * ====================================================================== */
.task-card {
  position: relative;
  border-left: 6px solid var(--border);     /* inline style sets exact colour */
  padding: var(--sp-3);
  transition: box-shadow .15s ease, opacity .2s ease, background-color .2s ease;
}
.task-card strong { font-size: var(--fs-base); line-height: 1.25; overflow-wrap: anywhere; }

/* Meta row under the title: status + CCP/importance/photo/assignee + threshold
   share ONE wrapping line (was two stacked badge rows — with long labels each
   badge wrapped onto its own line and cards grew very tall on phones).
   Badges on cards are informative, not tap targets → xs size is fine. */
.task-card-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-2); margin-top: var(--sp-1); }
.task-card .badge { font-size: var(--fs-xs); padding: 2px var(--sp-2); }
.task-card .badge .icn { width: 11px; height: 11px; }
/* Secondary actions cluster (revert / skip / nonconform / sign / photo). Lives
   in a reserved-height footer below the card body (not a side column), so:
   (a) it never squeezes the title, and (b) revealing the photo/revert buttons
   after a task is completed does NOT change the card height — every card keeps a
   consistent footer height regardless of how many actions currently apply. */
.task-card-actions { display: flex; align-items: center; gap: var(--sp-1); flex: none; }
.task-card-footer {
  margin-top: var(--sp-2);
  padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
  min-height: calc(var(--touch-min) + var(--sp-2));
  flex-wrap: nowrap;
  overflow-x: auto;
}
/* Footer actions now carry a label (not icon-only) — keep them compact so a few
   fit on one row; the footer scrolls horizontally if there are many. */
.task-card-footer .btn { font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); gap: var(--sp-1); white-space: nowrap; flex: none; }
.task-card-footer .btn .icn { width: 15px; height: 15px; }

/* subtle tinted background per state to reinforce colour coding */
.task-card.state-pending { background: var(--bg); }
.task-card.state-done {
  background: linear-gradient(90deg, var(--ok-light) 0%, var(--bg) 60%);
}
.task-card.state-alert {
  background: linear-gradient(90deg, var(--error-light) 0%, var(--bg) 60%);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--error) 18%, transparent), var(--shadow-sm);
}
.task-card.state-missed {
  background: linear-gradient(90deg, var(--warn-light) 0%, var(--bg) 60%);
}
.task-card.state-await {
  background:
    repeating-linear-gradient(45deg, var(--ok-light) 0 6px, color-mix(in srgb, var(--ok) 10%, var(--bg)) 6px 12px);
}

/* Done tasks visually recede (collapsed-at-bottom feel) */
.task-card.state-done strong { color: var(--text); }
.task-card.state-done { opacity: .92; }

/* =========================================================================
 * 8. TASK TOGGLE — 56–64px circle with animated checkmark per state
 * ====================================================================== */
.task-toggle {
  flex: none;
  /* Bifa stă SUS, aliniată cu titlul (nu centrată pe înălțimea cardului) —
   * pe cardurile înalte (descriere/foto/intrare inline) centrarea o plimba. */
  align-self: flex-start;
  width: var(--touch-primary);
  height: var(--touch-primary);
  border-radius: var(--radius-full);
  border: 2px solid var(--border);
  background: var(--bg);
  font-size: 24px;
  font-weight: 700;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  transition: transform .12s ease, background-color .15s ease, border-color .15s ease, color .15s ease;
}
@media (min-width: 600px) {
  .task-toggle { width: var(--touch-lg); height: var(--touch-lg); }
}
.task-toggle:active { transform: scale(.9); }
/* Locked outside its completion window (interval orar) — not tappable. */
.task-toggle:disabled { opacity: .45; cursor: not-allowed; filter: grayscale(.5); }
.task-toggle:disabled:active { transform: none; }
.task-toggle span { display: inline-block; animation: pop .22s ease; }

/* per-state toggle skin (parent .task-card carries the state class) */
.state-pending .task-toggle { color: var(--info); border-color: var(--info); }
.state-done .task-toggle {
  background: var(--ok); border-color: var(--ok); color: var(--on-color);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--ok) 35%, transparent);
}
.state-done .task-toggle span { animation: checkPop .3s cubic-bezier(.2,.8,.3,1.4); }
.state-alert .task-toggle {
  background: var(--error); border-color: var(--error); color: var(--on-color);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--error) 35%, transparent);
}
.state-missed .task-toggle { background: var(--warn); border-color: var(--warn); color: var(--on-color); }
.state-await .task-toggle {
  background: var(--bg); color: var(--ok);
  border-style: dashed; border-color: var(--ok);
}

@keyframes pop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes checkPop {
  0%   { transform: scale(0) rotate(-25deg); opacity: 0; }
  60%  { transform: scale(1.25) rotate(0deg); opacity: 1; }
  100% { transform: scale(1) rotate(0deg); }
}

/* =========================================================================
 * 9. CAMERA BUTTON
 * ====================================================================== */
.btn-camera {
  flex: none;
  width: var(--touch-min);
  height: var(--touch-min);
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  font-size: 22px;
  color: var(--brand-dark);
}
.btn-camera:active { background: var(--surface-2); }
.state-await .btn-camera {
  background: var(--ok-light);
  border-color: var(--ok);
  color: var(--ok);
  animation: nudge 1.6s ease-in-out infinite;
}
@keyframes nudge { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }

/* =========================================================================
 * 10. BOTTOM SHEET — temperature input + AI
 * ====================================================================== */
.sheet-backdrop { animation: fadeIn .18s ease; }
.sheet {
  max-width: 560px;
  margin: 0 auto;
  animation: slideUp .26s cubic-bezier(.2,.8,.2,1);
}
.sheet h2 { letter-spacing: -0.01em; }
.sheet-handle { cursor: grab; }
/* Wider sheet for the template manager (more horizontal room for the editor) */
.sheet.sheet-wide { max-width: 640px; }

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }

/* -------------------------------------------------------------------------
 * Modal dialog — centered on desktop/tablet, bottom-sheet on mobile.
 * Reuses the sheet backdrop/z-layer; used by the Tipuri editors.
 * ---------------------------------------------------------------------- */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-sheet);
  background: var(--overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  animation: fadeIn .18s ease;
}
/* Confirm dialogs open ON TOP of an already-open modal/sheet (e.g. the
 * link-assets confirm launched from inside the asset edit modal — both are
 * .modal-backdrop at --z-sheet, so DOM order used to decide and the edit modal
 * won). One layer up, still under toasts (--z-toast: 400). */
.modal-backdrop.modal-confirm { z-index: calc(var(--z-sheet) + 50); }
.modal {
  width: 100%;
  max-width: 560px;
  max-height: 90dvh;
  overflow-y: auto;
  background: var(--bg);
  border-radius: var(--radius-lg);
  padding: var(--sp-4);
  box-shadow: var(--shadow-lg);
  animation: popIn .2s cubic-bezier(.2,.8,.2,1);
}
.modal-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.modal-head h2, .modal-head h3 { margin: 0; flex: 1; letter-spacing: -0.01em; }
.modal-close { flex: none; }

@keyframes popIn { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }

/* On phones a centered dialog is cramped → dock it to the bottom like a sheet. */
@media (max-width: 599px) {
  .modal-backdrop { align-items: flex-end; padding: 0; }
  .modal {
    max-width: none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    padding-bottom: calc(var(--sp-4) + env(safe-area-inset-bottom));
    animation: slideUp .26s cubic-bezier(.2,.8,.2,1);
  }
}

/* -------------------------------------------------------------------------
 * Tipuri (#screen-types) — denser layout: smaller fonts + tighter spacing,
 * across the page and its editor modals. Scoped so other screens keep their
 * touch-friendly sizing.
 * ---------------------------------------------------------------------- */
/* Inset sub-card (a card nested inside another card) — e.g. the channel-readiness
   panel on Notificări. Subtle recessed surface so it reads as a grouped sub-block. */
.sub-card { background: var(--surface-2, color-mix(in srgb, var(--text) 4%, var(--surface))); border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--sp-2) var(--sp-3); }

#screen-types { font-size: var(--fs-sm); }
/* "Re-aplică la activele existente" card — accented so the retroactive step
   (the thing users miss after Save) stands out from the plain form. */
#screen-types .ty-reapply { border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--border)); background: color-mix(in srgb, var(--accent) 7%, var(--surface)); }
/* Type editor: two columns on a wide modal — type fields (left) + standard task
   list (right); stacks to one column on narrow screens. */
.ty-edit-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: var(--sp-4); align-items: start; }
.ty-edit-col { min-width: 0; }
@media (max-width: 899px) { .ty-edit-grid { grid-template-columns: 1fr; } }

/* Editare activ (Structura) — modal lat pe 2 coloane la EDITARE (identitate |
 * grup legat + acțiuni); la creare rămâne modalul îngust clasic. */
/* Aceeași lățime (1280) ca sheet-urile Sarcini/Documente/fișă/Detalii — cele 5
 * vederi per-activ sunt legate prin bara de chips și nu trebuie să „sară". */
.modal.modal-wide.obj-edit-modal { max-width: min(96vw, 1280px); }
.obj-edit-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--sp-4); align-items: start; }
.obj-edit-grid > div { min-width: 0; }
@media (max-width: 899px) { .obj-edit-grid { grid-template-columns: 1fr; } }
#screen-types h2 { font-size: var(--fs-base); }
#screen-types h3 { font-size: var(--fs-sm); }
#screen-types p { font-size: var(--fs-sm); line-height: 1.4; margin-bottom: var(--sp-2); }
#screen-types .breadcrumb { margin-bottom: var(--sp-2); }
#screen-types .data-table th { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }
#screen-types .data-table td { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }
#screen-types .data-table small { font-size: var(--fs-sm); }
#screen-types .data-table .btn { min-height: var(--touch-min); padding: var(--sp-1) var(--sp-2); }
#screen-types .data-table .btn .icn { width: 14px; height: 14px; }
#screen-types .badge { font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); }
#screen-types .card { padding: var(--sp-3); margin-bottom: var(--sp-2); }
#screen-types .field { margin-bottom: var(--sp-2); }
#screen-types .field > span { font-size: var(--fs-sm); margin-bottom: var(--sp-1); }
#screen-types input,
#screen-types select { min-height: var(--touch-min); font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); }
#screen-types .check { font-size: var(--fs-sm); }
#screen-types .btn { min-height: var(--touch-min); }
#screen-types .modal-head h3 { font-size: var(--fs-base); }
/* Fields paired in editor rows keep a usable minimum and wrap on phones
   (with min-width:0 they shrank to ~100px and clipped select labels). */
#screen-types .modal .flex > .field { min-width: 130px; }
/* Category keys can be long slugs — never let <code> crush the rename input. */
#screen-types .modal code { max-width: 9ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle; }
/* Category header row in the Tipuri list (grouping). */
#screen-types .data-table tr.ttype-cat td { background: var(--surface); font-weight: 700; text-transform: uppercase; letter-spacing: .03em; font-size: var(--fs-sm); color: var(--text-muted); }
/* Rândul tipului DESCHIS acum în editor: tentă de brand + bară-accent la stânga,
   ca navigarea (‹ ›) și click-ul pe rânduri să arate clar unde ești. */
#screen-types .data-table tr.ty-row-open > td { background: var(--brand-light); }
#screen-types .data-table tr.ty-row-open > td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
/* Rândul activului DESCHIS acum în editor (pagina Structura/Active) — la fel ca la tipuri. */
#screen-structure tr.asset-row-open > td { background: var(--brand-light); }
#screen-structure tr.asset-row-open > td:first-child { box-shadow: inset 3px 0 0 var(--brand); }

/* Settings: keep short numeric/time/tel inputs from stretching to the full
   (very wide) 2-column masonry track. */
#screen-settings input[type="number"],
#screen-settings input[type="time"],
#screen-settings input[type="tel"] { max-width: 14rem; }

/* Documents page: match the other config screens' density on ALL devices
   (not only desktop via the pointer:fine media). */
#screen-documents h2 { font-size: var(--fs-base); }
#screen-documents .doc-card .btn { min-height: var(--touch-min); font-size: var(--fs-sm); }

/* Compact fonts across the Structura screen (denser tables + controls). */
#screen-structure h2 { font-size: var(--fs-sm); }
#screen-structure h4 { font-size: var(--fs-base); margin-bottom: var(--sp-1); }
#screen-structure p,
#screen-structure .muted { font-size: var(--fs-sm); }
#screen-structure .breadcrumb { font-size: var(--fs-sm); margin-bottom: var(--sp-2); }
#screen-structure .chip { font-size: var(--fs-sm); }
#screen-structure .field > span { font-size: var(--fs-sm); }
#screen-structure input,
#screen-structure select,
#screen-structure textarea { font-size: var(--fs-sm); }
#screen-structure .zone-head strong { font-size: var(--fs-sm); }
#screen-structure .data-table th { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }
#screen-structure .data-table td { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }
#screen-structure .data-table strong { font-weight: 600; }
#screen-structure .data-table small { font-size: var(--fs-sm); }
#screen-structure .data-table .btn { min-height: var(--touch-min); padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }
/* Compact ALL Structura buttons/chips on EVERY device — not just table ones.
   The touch/tablet base otherwise keeps action buttons (zone accordion, toolbar)
   tall & padded, so the screen looked dense only on desktop, where the
   (hover:hover)&(pointer:fine) media already compacts every .btn. */
#screen-structure .btn { font-size: var(--fs-sm); min-height: var(--touch-min); padding: var(--sp-1) var(--sp-2); }
#screen-structure .btn .icn { width: 13px; height: 13px; }
#screen-structure .chip { min-height: var(--touch-min); }
#screen-structure .badge { font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); }
#screen-structure .reorder-btn { font-size: .72rem; }
/* Compact rows (same fix as the wide tasks modal): side-by-side reorder arrows
   + natural-height buttons instead of the 2-button stack + touch-height rows. */
#screen-structure .reorder { flex-direction: row; }
/* Compact heights are a desktop-density optimization; on touch they'd push the
   most frequent actions (Editează, Sarcini, reorder) under --touch-min, so
   they're scoped to fine pointers. Touch keeps the default tappable sizes. */
@media (hover: hover) and (pointer: fine) {
  #screen-structure .reorder-btn { height: 1.6rem; width: 1.7rem; }
  #screen-structure .data-table .btn,
  #screen-structure .row-actions .btn { min-height: 0; padding: var(--sp-1) var(--sp-2); }
  /* keep the inline "Mută în…" select the same height as its row neighbours */
  #screen-structure .row-actions .mini-move { min-height: 0; }
}
@media (hover: none), (pointer: coarse) {
  #screen-structure .reorder-btn,
  #screen-types .reorder-btn { width: var(--touch-min); height: var(--touch-min); font-size: var(--fs-sm); }
}
#screen-types .reorder { flex-direction: row; }
#screen-structure .row-actions { align-items: center; }
#screen-structure .drag-handle { font-size: .8rem; }
/* small spacing between the action buttons (were visually glued together) */
#screen-structure .row-actions { gap: var(--sp-2); row-gap: var(--sp-2); }
/* object/zone edit modals opened from Structura */
#screen-structure .modal-head h3 { font-size: var(--fs-base); }
#screen-structure .modal .field > span { font-size: var(--fs-sm); }
/* Structura quality-of-life (S1–S8): sort bar, bulk bar, inline move select */
/* Bara unică Structura: filtrele frecvente (Zonă/Tip) ca selecturi inline compacte
 * (fără etichete plutitoare) + restul filtrelor în popover-ul „Filtre". */
#screen-structure .inline-filter { min-height: var(--touch-min); font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); max-width: 180px; }
.struct-filter-pop { min-width: 250px; padding: var(--sp-2) var(--sp-3); }
.struct-filter-pop .field { margin-bottom: var(--sp-2); }

/* Sortarea activelor — chips compacte în popover-ul „Filtre" (o singură instanță). */
.struct-filter-pop .sort-chips .btn { min-height: 0; padding: 2px var(--sp-2); font-size: var(--fs-xs); }
.struct-filter-pop .sort-chips .btn.active { background: var(--brand-light); border-color: var(--brand); color: var(--brand-dark); }
.struct-filter-pop > small { font-size: var(--fs-xs); }
#screen-structure .mini-move { min-height: var(--touch-min); font-size: var(--fs-sm); max-width: 140px; padding: var(--sp-1) var(--sp-2); }
#screen-structure .th-sort { user-select: none; white-space: nowrap; }
/* Per-row "⋯ Mai multe" overflow menu — moves the rare row actions off the main
   row so the frequent ones (Sarcini, Editează) aren't lost in a wall of buttons. */
.row-menu { position: relative; flex: none; }
.row-menu-btn { font-size: var(--fs-lg); line-height: 1; padding: var(--sp-1) var(--sp-2); min-width: var(--touch-min); }
.row-menu-pop {
  position: absolute; right: 0; top: calc(100% + 2px); z-index: 30;
  min-width: 12.5rem; padding: var(--sp-1);
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  display: flex; flex-direction: column;
}
.row-menu-item {
  display: flex; align-items: center; gap: var(--sp-2);
  width: 100%; text-align: left; white-space: nowrap;
  padding: var(--sp-2); min-height: var(--touch-min);
  background: none; border: 0; border-radius: var(--radius-sm);
  color: var(--text); font-size: var(--fs-sm); cursor: pointer;
}
.row-menu-item:hover, .row-menu-item:focus-visible { background: var(--surface-2); }
.row-menu-item.danger { color: var(--error-text); }
.row-menu-item.danger:hover { background: color-mix(in srgb, var(--error) 14%, var(--surface)); }
.row-menu-item .icn { flex: none; width: 15px; height: 15px; opacity: .8; }
/* Variantă pe două rânduri (titlu + explicație) — pentru meniuri cu acțiuni
   care au nevoie de o propoziție de context (ex. „Seturi de sarcini"). */
.row-menu-item-2l { white-space: normal; align-items: flex-start; line-height: 1.35; }
.row-menu-item-2l small { display: inline-block; margin-top: var(--sp-1); }
.row-menu-item .mini-move { margin-left: auto; max-width: 8rem; }
/* Linked-asset-group badge: clickable, carries the group's colour dot (same
 * dot = same group). The popover anchors LEFT (the badge sits in the name
 * cell, so a right-anchored pop would run off-screen). */
.grp-badge { cursor: pointer; }
.grp-badge .cat-dot { width: 8px; height: 8px; }
.grp-pop { left: 0; right: auto; max-width: min(20rem, 90vw); }
.grp-pop .row-menu-item span { white-space: normal; }
/* Settings scope badge: makes clear whether a group is per-device (localStorage)
   or unit-wide (server). Placed in each card header. */
.set-scope {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--fs-xs); font-weight: 600; white-space: nowrap;
  padding: 1px var(--sp-2); border-radius: var(--radius-full);
  border: 1px solid var(--border);
}
.set-scope .icn { width: 12px; height: 12px; }
.set-scope-device { color: var(--text-muted); background: var(--surface-2); }
.set-scope-server { color: var(--brand); background: color-mix(in srgb, var(--brand) 10%, var(--surface)); border-color: color-mix(in srgb, var(--brand) 30%, var(--border)); }
.set-card-head { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-2); }
.set-card-head h3 { margin: 0; }
/* Explicit "which work point you're editing" context bar on the Zone & active view. */
.struct-wp-context {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: var(--sp-1) var(--sp-2); margin-bottom: var(--sp-2);
  font-size: var(--fs-sm);
  background: color-mix(in srgb, var(--brand) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--brand) 28%, var(--border));
  border-radius: var(--radius);
}
.struct-wp-context > .icn { flex: none; color: var(--brand); }
.struct-wp-context .btn { flex: none; }
/* Bulk-select bar: brand tint EVERYWHERE it appears (Structura, Alerte…), so
   the sticky bar reads as "selection mode", distinct from plain cards. */
.bulk-bar { background: var(--brand-light); border-color: color-mix(in srgb, var(--brand) 30%, transparent); padding: var(--sp-2) var(--sp-3); }
.bulk-bar select { min-height: var(--touch-min); font-size: var(--fs-sm); }
/* One size for every bulk-select checkbox (was 13/16/18/20px per screen). */
.zone-head input[type="checkbox"],
.data-table input[type="checkbox"] { width: 18px; height: 18px; flex: none; }
/* 44px tap wrapper for a row checkbox (alerts list, tables). */
.bulk-check {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--touch-min); min-height: var(--touch-min); flex: none; cursor: pointer;
}
.bulk-check input[type="checkbox"] { width: 18px; height: 18px; }
/* Failed outbox rows pop without needing the Status column on screen. */
.data-table tr.row-failed td { background: var(--error-light); }

/* Equipment-type icon (Tipuri table + object lists). Monochrome, brand-tinted. */
.type-ico { width: 22px; height: 22px; color: var(--brand-dark); flex: none; vertical-align: middle; }
.type-ico-lg { width: 40px; height: 40px; }
#screen-types .data-table .type-ico { width: 20px; height: 20px; }

/* =========================================================================
 * 11. TEMP DISPLAY — big 48px+ value, live green/red
 * ====================================================================== */
.temp-display {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 4px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  border: 2px solid var(--border);
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.temp-display.ok  { border-color: var(--ok); }
.temp-display.bad { border-color: var(--error); animation: shake .3s ease; }
.temp-display span:first-child { letter-spacing: -0.02em; }

@keyframes shake {
  0%,100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}

/* =========================================================================
 * 12. NUMERIC PAD — large keys, ergonomic, backspace spans full width
 * ====================================================================== */
.numpad button {
  border: 1px solid var(--border);
  background: var(--bg);
  transition: background-color .1s ease, transform .06s ease;
  font-variant-numeric: tabular-nums;
}
.numpad button:active { background: var(--surface-2); transform: scale(.95); }
/* last child = ⌫ backspace → span all three columns */
.numpad button:last-child {
  grid-column: 1 / -1;
  background: var(--surface);
  color: var(--error);
  font-size: var(--fs-lg);
}

/* step buttons (+/-0.5) — neutral only; never override coloured buttons
 * (btn-primary/ok/danger/ghost), otherwise e.g. "Adaugă sarcină" got grey bg. */
#screen-tasks ~ * .sheet .flex > .btn:not(.btn-primary):not(.btn-ok):not(.btn-danger):not(.btn-ghost),
.sheet .flex.gap-2 > .btn:not(.btn-primary):not(.btn-ok):not(.btn-danger):not(.btn-ghost) {
  background: var(--surface);
  border: 1px solid var(--border);
  font-weight: 700;
}

/* corrective action textarea highlight */
#corrective-input { border-color: var(--error); background: var(--bg); }
#corrective-input:focus-visible { outline-color: var(--error); }

/* =========================================================================
 * 13. TAB BAR — bottom navigation, active indicator
 * ====================================================================== */
.tabbar {
  box-shadow: 0 -1px 8px var(--shadow-color);
}
.tabbar button {
  transition: color .12s ease;
  position: relative;
  font-weight: 500;
}
.tabbar button .ico {
  font-size: 22px;
  transition: transform .12s ease;
}
.tabbar button:active .ico { transform: scale(.88); }
.tabbar button.active::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 28px;
  height: 3px;
  border-radius: 0 0 var(--radius-full) var(--radius-full);
  background: var(--accent);
}
.tabbar button.active .ico { transform: translateY(-1px); }
/* small count badge on a tab (e.g. Registre scadențe) */
.tabbar .tab-badge {
  position: absolute; top: var(--sp-1); right: 50%; transform: translateX(20px);
  min-width: var(--sp-4); height: var(--sp-4); padding: 0 var(--sp-1); border-radius: var(--radius-full);
  background: var(--error); color: var(--on-color); font-size: var(--fs-sm); font-weight: 700; line-height: var(--sp-4); text-align: center;
}

/* =========================================================================
 * 14. TOAST — auto-save confirmation
 * ====================================================================== */
.toast {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  max-width: calc(100% - var(--sp-8));
  font-weight: 600;
}
.toast::before { content: "✓"; color: var(--ok); font-weight: 800; }
.toast.is-error { background: var(--toast-error-bg); }
.toast.is-error::before { content: "⚠"; color: var(--error); }
.toast.is-info::before { content: "ℹ"; color: var(--info); }
.toast-action { margin-left: var(--sp-3); color: var(--brand-light); font-weight: 700; text-decoration: underline; white-space: nowrap; }

/* Data table (Structura objects) — scrolls horizontally on narrow screens */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--border); border-radius: var(--radius); }
.data-table { width: 100%; border-collapse: collapse; background: var(--bg); }
.data-table th, .data-table td { padding: var(--sp-1) var(--sp-2); text-align: left; border-bottom: 1px solid var(--border); vertical-align: middle; font-size: var(--fs-sm); }
.data-table thead th { background: var(--surface); font-size: var(--fs-sm); color: var(--text-muted); white-space: nowrap; position: sticky; top: 0; }
.data-table tbody tr:last-child td { border-bottom: none; }
@media (hover: hover) { .data-table tbody tr:hover { background: var(--surface); } }
.data-table .btn { min-height: var(--touch-min); padding: var(--sp-1) var(--sp-2); box-shadow: none; }
.data-table .empty { padding: var(--sp-6); }

/* ▲▼ reorder controls (Structura zone/obiecte + editor sarcini) — compact,
   stacked, still tappable on tablet (total PAIR height ~ touch min). */
.reorder { display: inline-flex; flex-direction: column; gap: var(--sp-1); vertical-align: middle; }
.reorder-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.1rem; height: 1.35rem; padding: 0; line-height: 1; font-size: .72rem;
  border: 1px solid var(--border); background: var(--bg); color: var(--text);
  border-radius: var(--radius-sm); cursor: pointer;
}
.reorder-btn:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.reorder-btn:disabled { opacity: .3; cursor: default; }

/* lightweight loading placeholder (reports etc.) */
.skeleton-card { position: relative; overflow: hidden; }
.skeleton-card::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, var(--shimmer), transparent);
  transform: translateX(-100%); animation: skeleton-sweep 1.1s infinite;
}
@keyframes skeleton-sweep { to { transform: translateX(100%); } }

/* selected alert card (bulk selection) */
.card.sel { outline: 2px solid var(--brand); outline-offset: -2px; }
/* The app-header is sticky (64px, z-index:100) on EVERY breakpoint, so the bar
   must pin below it — with top:var(--sp-2) it slid behind the header on desktop. */
.bulk-bar { position: sticky; top: calc(var(--header-h) + var(--sp-2)); z-index: 5; }
/* Pe telefon wrapper-ul .struct-sticky NU e sticky — fără box-ul lui (display:
   contents) bara de bulk rămâne sticky față de pagină; altfel sticky-ul ei
   s-ar termina la marginea wrapper-ului scurt și bara ar defila afară. */
@media (max-width: 767.98px) {
  .struct-sticky { display: contents; }
}

/* Structura: sub-navigare + căutare + filtre + bara de bulk fixate sub header
   la scroll, doar pe ≥768px (pe telefon toolbar-ul împachetat pe 2-3 rânduri ar
   mânca prea mult ecran — acolo rămâne sticky doar .bulk-bar, regula de sus).
   flow-root: fără el, mb-ul ultimului copil ar colapsa în afara wrapper-ului și
   conținutul s-ar vedea prin fanta transparentă de sub bară în timpul scroll-ului. */
@media (min-width: 768px) {
  .struct-sticky {
    display: flow-root;
    position: sticky; top: var(--header-h); z-index: 6;
    background: var(--bg);
    /* respirație sub header când e lipită + bleed lateral: fundalul depășește
       puțin conținutul, ca umbrele/outline-urile cardurilor care trec pe
       dedesubt să nu se vadă pe lângă marginile barei */
    padding: var(--sp-2) var(--sp-3) 0;
    margin-inline: calc(-1 * var(--sp-3));
    box-shadow: 0 8px 8px -8px color-mix(in srgb, var(--text) 12%, transparent);
  }
  .struct-sticky .bulk-bar { position: static; }
}

/* Toolbar-ul Structurii pe ferestre desktop mai înguste (768–1399px): modul
   compact, ca bara sticky să nu se împacheteze pe 2-3 rânduri care mănâncă
   ecranul — toolbar-ul și bara de bulk încap fiecare pe UN rând:
   - butoanele lungi trec pe eticheta scurtă („Adaugă zonă"→„Zonă",
     „Etichete & QR"→doar iconița; title-ul păstrează explicația completă);
   - filtrele inline Zonă/Tip se mută în popover-ul „Filtre" (dublurile
     .pop-narrow-filter, același x-model — ține sincron cu matchMedia din
     hiddenFilterActive, app.js);
   - selecturile barei de bulk devin elastice. */
.narrow-label { display: none; }
.struct-filter-pop .pop-narrow-filter { display: none; }
/* flex-basis explicit: decizia de wrap se ia la 150px (nu la lățimea de
   conținut a inputului), apoi câmpul crește până la max-width — altfel
   căutarea rupea rândul deși ar fi încăput comprimată */
.struct-toolbar > .field.grow { flex: 1 1 150px; }
/* dimensiunile selecturilor din bara de bulk (fost stiluri inline) */
.struct-sticky .bulk-bar select { min-width: 120px; max-width: 180px; }
.struct-sticky .bulk-bar select.grow { min-width: 130px; max-width: 200px; }
/* Neconformități: bara de bulk edit a dosarelor CAPA */
.capa-bulk select { min-width: 140px; max-width: 200px; }
.capa-bulk input[type="date"] { max-width: 170px; }
@media (min-width: 768px) and (max-width: 1399px) {
  .struct-toolbar .wide-label { display: none; }
  .struct-toolbar .narrow-label { display: inline; }
  .struct-toolbar .inline-filter { display: none; }
  .struct-filter-pop .pop-narrow-filter { display: block; }
  .struct-sticky .bulk-bar .wide-label { display: none; }
  .struct-sticky .bulk-bar select { min-width: 96px; flex: 1 1 96px; }
}

/* drag-and-drop reordering (SortableJS) — handle initiates drag; the rest of
   the row keeps default touch-action so the list still scrolls on tablet. */
.drag-handle { cursor: grab; color: var(--text-muted); user-select: none; touch-action: none; padding: 0 .2rem; font-size: 1rem; line-height: 1; display: inline-block; vertical-align: middle; }
.drag-handle:active { cursor: grabbing; }
tr.sortable-ghost { opacity: .4; }
tr.sortable-ghost td { background: var(--surface); }
tr.sortable-chosen td { background: var(--surface); }
tr.sortable-drag { opacity: .95; }

/* Structura: acordeon „Zone & obiecte" */
.zone-accordion { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-3); }
/* .card aduce margin-bottom global — s-ar ADUNA cu gap-ul flex de mai sus. */
.zone-card { padding: 0; margin-bottom: 0; }
.zone-card.sortable-ghost { opacity: .4; }
.zone-head { display: flex; align-items: center; gap: .4rem; padding: var(--sp-2) var(--sp-3); cursor: pointer; flex-wrap: wrap; }
@media (hover: hover) { .zone-head:hover { background: var(--surface); } }
.zone-caret { width: 1rem; text-align: center; color: var(--text-muted); flex: none; }
.zone-handle { cursor: grab; flex: none; }
.zone-body { padding: 0 var(--sp-2) var(--sp-2); border-top: 1px solid var(--border); }
/* Tabelul de active stătea lipit de antetul zonei după mutarea barei de sortare
 * (v420) în popover-ul „Filtre" — ea dădea spațierea de sus. */
.zone-body .table-wrap { margin-top: var(--sp-2); }

/* Live plain-words explanation of a chosen recurrence (task). */
.rec-explain { margin-top: var(--sp-2); padding: var(--sp-2) var(--sp-3); background: var(--brand-light); border-left: 3px solid var(--brand); border-radius: var(--radius-sm); }
/* Live "În cuvinte" preview at the TOP of the editor as the main feedback loop. */
.rec-explain-top { margin-top: 0; margin-bottom: var(--sp-3); }
/* Grouped sections (Cât de des · Când exact · Interval orar) — stable containers
   so switching frequency doesn't visually shuffle the whole form. */
.rec-group { border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-3); margin-bottom: var(--sp-3); }
.rec-group > .field:last-child, .rec-group > div:last-child { margin-bottom: 0; }
.rec-group-h { display: block; font-size: var(--fs-sm); font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .03em; margin-bottom: var(--sp-2); }
.rec-explain-h { display: block; font-size: var(--fs-sm); font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--brand-dark); margin-bottom: var(--sp-1); }
.rec-explain > div { font-size: var(--fs-sm); color: var(--text); }
/* Collapsible advanced recurrence sections (seasonality, exceptions). */
.rec-adv { margin-top: var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0 var(--sp-2); }
.rec-adv > summary { cursor: pointer; padding: var(--sp-2) 0; font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted); }
.rec-adv[open] > summary { border-bottom: 1px solid var(--border); margin-bottom: var(--sp-2); }
.rec-adv > *:last-child { margin-bottom: var(--sp-2); }
/* Sub-group headings inside "Avansat" (Mod de repetare · Restricții · Limite) —
   with a divider so the three conceptual blocks scan apart. */
.rec-adv-h { display: block; font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); margin: var(--sp-3) 0 var(--sp-2); padding-top: var(--sp-3); border-top: 1px solid var(--border); }
.rec-adv-h:first-of-type { margin-top: 0; padding-top: 0; border-top: none; }

/* =========================================================================
 * 15. Breadcrumb, empty state, disclaimer, loading
 * ====================================================================== */
.breadcrumb button:active { text-decoration: underline; }

.empty { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); }
.empty .ico { opacity: .8; }
.empty h2 { font-size: var(--fs-lg); }

.disclaimer { line-height: 1.45; }
.disclaimer::before { content: "⚠ "; }

.loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
}
.loading::before {
  content: "";
  width: 18px; height: 18px;
  border: 2px solid var(--surface-2);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* =========================================================================
 * 16. Forms — 16px inputs (no iOS zoom), branded focus
 * ====================================================================== */
.input, input[type="text"], input[type="number"], input[type="search"], input[type="date"],
input[type="time"], input[type="url"], input[type="email"], input[type="tel"], input[type="password"],
textarea, select {
  font-size: 16px;                /* prevent iOS zoom */
  transition: border-color .12s ease, box-shadow .12s ease;
}
.input:focus, input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-light);
}
select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
                    linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: var(--sp-8);
}

/* =========================================================================
 * 17. Reduced motion
 * ====================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* =========================================================================
 * 18. DARK MODE
 *     Re-maps tokens; components inherit automatically. Aplicat in doua cazuri:
 *       a) FORTAT din Setari:  html[data-theme="dark"]  (oricand)
 *       b) AUTO (urmeaza sistemul): html:not([data-theme]) sub prefers dark
 *     Tema "light" = absenta override-ului (tokenii impliciti din variables.css),
 *     iar html[data-theme="light"] bate media query-ul de mai jos.
 * ====================================================================== */
:root[data-theme="dark"],
.dark-tokens {
  /* Only NEUTRALS + a lighten of the chosen palette + brighter semantics change
     for dark. All -light/-dark tints DERIVE (they read the dark --surface), so
     any preset / custom color works here with no per-theme tint table. */
  --text: #E6ECF1;
  --text-muted: #93A2AF;
  --bg: #141B22;
  --surface: #1C242D;
  --surface-2: #29333D;
  --border: #33414C;

  --brand:  color-mix(in srgb, var(--brand-base), #fff 14%);
  --accent: color-mix(in srgb, var(--accent-base), #fff 12%);

  --ok: #3CB873;
  --error: #E2615F;
  --warn: #F0B429;
  --info: #93A2AF;
  --await: #6AA0FF;   /* lightened so "așteptare dovadă" text reads on dark tint */
  /* Badge/label text sits on the (dark) derived tints → use the bright hue. */
  --ok-text: var(--ok);
  --error-text: var(--error);
  --warn-text: var(--warn);
  --info-text: var(--info);
  --await-text: var(--await);

  --on-color: #FFFFFF;
  --overlay: rgba(0, 0, 0, 0.6);
  --shimmer: rgba(255, 255, 255, 0.06);
  --tint-weak: rgba(255, 255, 255, 0.12);
  --shadow-color: rgba(0, 0, 0, 0.5);
  --toast-error-bg: #3A1B1C;

  --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
  --shadow:    0 2px 8px rgba(0,0,0,0.5);
  --shadow-lg: 0 8px 28px rgba(0,0,0,0.6);
}

/* AUTO: doar cand utilizatorul nu a fortat o tema (fara atribut data-theme). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --text: #E6ECF1;
    --text-muted: #93A2AF;
    --bg: #141B22;
    --surface: #1C242D;
    --surface-2: #29333D;
    --border: #33414C;

    --brand:  color-mix(in srgb, var(--brand-base), #fff 14%);
    --accent: color-mix(in srgb, var(--accent-base), #fff 12%);

    --ok: #3CB873;
    --error: #E2615F;
    --warn: #F0B429;
    --info: #93A2AF;
    --await: #6AA0FF;
    --ok-text: var(--ok);
    --error-text: var(--error);
    --warn-text: var(--warn);
    --info-text: var(--info);
    --await-text: var(--await);

    --on-color: #FFFFFF;
    --overlay: rgba(0, 0, 0, 0.6);
    --shimmer: rgba(255, 255, 255, 0.06);
    --tint-weak: rgba(255, 255, 255, 0.12);

    --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
    --shadow:    0 2px 8px rgba(0,0,0,0.5);
    --shadow-lg: 0 8px 28px rgba(0,0,0,0.6);
  }
}

/* Ajustari de componente in tema intunecata (ambele cazuri). Tokenii sunt deja
 * remapati mai sus, deci aceste reguli folosesc doar gradiente/efecte specifice. */
:root[data-theme="dark"] .task-card.state-done   { background: linear-gradient(90deg, var(--ok-light) 0%, var(--bg) 60%); }
:root[data-theme="dark"] .task-card.state-alert  { background: linear-gradient(90deg, var(--error-light) 0%, var(--bg) 60%); }
:root[data-theme="dark"] .task-card.state-missed { background: linear-gradient(90deg, var(--warn-light) 0%, var(--bg) 60%); }
:root[data-theme="dark"] .task-card.state-await  { background: repeating-linear-gradient(45deg, var(--ok-light) 0 6px, color-mix(in srgb, var(--ok) 20%, var(--bg)) 6px 12px); }
:root[data-theme="dark"] #corrective-input { background: var(--surface); }
:root[data-theme="dark"] .app-header { backdrop-filter: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .task-card.state-done   { background: linear-gradient(90deg, var(--ok-light) 0%, var(--bg) 60%); }
  :root:not([data-theme]) .task-card.state-alert  { background: linear-gradient(90deg, var(--error-light) 0%, var(--bg) 60%); }
  :root:not([data-theme]) .task-card.state-missed { background: linear-gradient(90deg, var(--warn-light) 0%, var(--bg) 60%); }
  :root:not([data-theme]) .task-card.state-await  { background: repeating-linear-gradient(45deg, var(--ok-light) 0 6px, color-mix(in srgb, var(--ok) 20%, var(--bg)) 6px 12px); }
  :root:not([data-theme]) #corrective-input { background: var(--surface); }
  :root:not([data-theme]) .app-header { backdrop-filter: none; }
}

/* =========================================================================
 * 12. PLAN 2D (harta per punct de lucru) — vizualizare
 *     Un singur <svg> cu viewBox reactiv. Straturi: fundal -> zone -> pereti
 *     -> usi -> markere echipament. Statusul live reia paleta --st-<status>.
 * ====================================================================== */
.map-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1);
  margin-bottom: var(--sp-2);
}
.map-legend .badge { font-size: var(--fs-sm); padding: 2px var(--sp-2); }
/* In the overlay the badges are tap targets (status filters) — give them a
   decent hit area instead of the ~22px informational-badge height. */
.map-legend-overlay .badge { min-height: 32px; padding: var(--sp-1) var(--sp-2); }
/* Pe telefon: legenda pe UN rând scrollabil (nu 2-3 rânduri care acoperă
   banda de sus a planului și intră sub pastila de căutare). */
@media (max-width: 599px) {
  .map-legend-overlay { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .map-legend-overlay::-webkit-scrollbar { display: none; }
  .map-legend-overlay .badge { flex: none; }
}
/* Legendă/filtru ca overlay peste plan (colț stânga-sus al .map-wrap). */
.map-legend-overlay {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 5;
  margin-bottom: 0;
  max-width: calc(100% - 16px);
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  box-shadow: var(--shadow-sm);
  pointer-events: auto;
}
.map-wrap {
  position: relative;
  width: 100%;
  height: clamp(340px, 62vh, 720px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: auto;                 /* scrollbar când planul depășește containerul */
  box-shadow: var(--shadow-sm);
}
.map-svg {
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;        /* we own pan/zoom via pointer events */
  background: var(--bg);     /* metric grid is the toggleable SVG layer (showGrid) */
  cursor: grab;
  user-select: none;         /* dragging elements must not select plan text/labels */
  -webkit-user-select: none;
}
.map-svg:active { cursor: grabbing; }

/* Zone polygons: colour from data (inline fill), status outline from class. */
.map-zone {
  fill-opacity: .22;
  stroke: var(--border);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  cursor: pointer;
}
.map-zone.s-alert   { stroke: var(--st-alert);   stroke-width: 3; }
.map-zone.s-missed  { stroke: var(--st-missed);  stroke-width: 3; }
.map-zone.s-await   { stroke: var(--st-await); }
.map-zone.s-pending { stroke: var(--st-pending); }
.map-zone.s-done    { stroke: var(--st-done); }
.map-zone.s-none    { stroke: var(--border); }
.map-zone-label {
  fill: var(--text);
  font-size: 16px;
  font-weight: 600;
  text-anchor: middle;
  pointer-events: none;
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 3px;
  vector-effect: non-scaling-stroke;
}

/* Walls & doors */
.map-wall {
  stroke: var(--text);
  stroke-width: 6;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.map-door {
  stroke: var(--brand);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 2 6;
  vector-effect: non-scaling-stroke;
}

/* Equipment markers (world-space; scale with the plan) */
.map-marker { cursor: pointer; }
.map-marker .mk-hit { fill: transparent; }
.map-marker .ring {
  fill: var(--bg);
  stroke: var(--st-pending);
  stroke-width: 3;
  vector-effect: non-scaling-stroke;
}
.map-marker.s-alert   .ring { stroke: var(--st-alert); }
.map-marker.s-missed  .ring { stroke: var(--st-missed); }
.map-marker.s-await   .ring { stroke: var(--st-await); }
.map-marker.s-pending .ring { stroke: var(--st-pending); }
.map-marker.s-done    .ring { stroke: var(--st-done); }
.map-marker.s-none    .ring { stroke: var(--border); }
.map-marker .mk-ico {
  fill: none;
  stroke: var(--text);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--text);
  pointer-events: none;
}
.map-marker .mk-badge circle { fill: var(--error); }
.map-marker .mk-badge text {
  fill: var(--on-color);
  font-weight: 700;
  text-anchor: middle;
  pointer-events: none;
}
.map-marker .mk-name {
  fill: var(--text);
  text-anchor: middle;
  pointer-events: none;
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 3px;
  vector-effect: non-scaling-stroke;
}
/* Denumirea tipului deasupra bulei (toggle „Tipuri" în legendă): pastilă cu
   colțuri rotunjite (rect) + text — fără halo pe font. CLICKABILĂ: grupul e în
   interiorul markerului cu data-eq, deci un tap pe pastilă deschide fișa
   activului exact ca un tap pe bulă (onClick urcă până la data-eq). */
.map-marker .mk-typebox { cursor: pointer; }
.map-marker .mk-typebox rect {
  fill: var(--surface);
  fill-opacity: .92;
  stroke: var(--border);
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}
.map-marker .mk-type {
  fill: var(--text-muted);
  font-weight: 600;
  text-anchor: middle;
  pointer-events: none;   /* click-ul îl prinde dreptunghiul de dedesubt */
}

/* Floating zoom toolbar — offset BELOW the search pill (same corner, ~52px
   tall) so "+" is never buried under it. Shifts left with the Elemente panel. */
.map-toolbar {
  position: absolute;
  top: calc(var(--sp-2) + 52px + env(safe-area-inset-top, 0px));
  right: calc(var(--sp-2) + env(safe-area-inset-right, 0px));
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  z-index: 2;
}
.map-toolbar.shifted { right: calc(min(244px, 76vw) + var(--sp-2)); }
.map-toolbar .icon-btn {
  background: var(--bg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  width: var(--touch-min);
  height: var(--touch-min);
  border-radius: var(--radius-sm);
}
.map-toolbar .map-zoom-out { font-size: 26px; line-height: 1; font-weight: 700; }

/* ---- edit mode (Phase 3) ---- */
.map-edit { margin-bottom: var(--sp-2); min-width: 0; }
/* BANDA CONTEXTUALĂ: un singur rând stabil sub paletă (order 20, după butonul
 * „Fundal & plan" care rămâne pe rândul paletei). Ține ÎMPREUNĂ sub-controalele
 * uneltei și hint-ul; înălțimea minimă = un control (touch-min), deci comutarea
 * uneltelor nu redimensionează bara și nu împinge harta. */
.map-ctxrow {
  order: 20;
  flex: 1 1 100%;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-3);
  min-height: var(--touch-min);
}
.map-ctxrow .map-subtools { margin-top: 0; min-width: 0; }
/* Listele pot avea nume lungi de active/zone — nu au voie să lățească pagina. */
.map-ctxrow select { max-width: min(18rem, 60vw); }
/* Hint-ul curge după sub-controale și înghite restul rândului. */
.map-edit-head { flex: 1 1 12rem; min-width: 0; text-align: left; margin: 0; }
.map-edit-head .muted { font-size: var(--fs-sm); line-height: 1.3; }
/* Loud hint when the active tool can't act yet (no target / no wall / no zone). */
.map-hint-warn { color: var(--warn-text); font-weight: 600; }
/* A required dropdown the user hasn't picked yet (zone/asset tool gate). */
select.needs-pick { outline: 2px solid var(--warn); outline-offset: 1px; border-radius: var(--radius-sm, 6px); }
.map-tools {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin-top: var(--sp-1);
}
.map-tools .icon-btn {
  width: auto;
  min-width: var(--touch-min);
  height: auto;
  min-height: var(--touch-min);
  padding: var(--sp-1);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  font-size: var(--fs-xs);
  line-height: 1.05;
}
.map-tools .icon-btn .icn { width: 16px; height: 16px; }
.map-tool-ico { font-size: var(--fs-sm); line-height: 1; }
.map-tool-label { font-size: var(--fs-xs); white-space: nowrap; }
.map-tools .icon-btn.active {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-color);
}
.map-tools .icon-btn.active .icn { stroke: var(--on-color); color: var(--on-color); }
/* Grupuri segmentate în paletă (istoric / desen / active / moduri): la lipsă de
 * spațiu se împachetează BLOCURI întregi, nu butoane răzlețe; chenarul comun
 * spune „astea merg împreună". Grupurile sunt MICI (max 4 butoane) ca să încapă
 * pe orice lățime; flex-wrap intern e plasa de siguranță pe ecrane minuscule. */
.map-toolgrp {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  min-width: 0;
}
.map-toolgrp .icon-btn { border-color: transparent; background: transparent; }
.map-tools .map-tool-end.icon-btn { background: var(--st-done); border-color: var(--st-done); color: var(--on-color); }
.map-tools .map-tool-end.icon-btn .icn { stroke: var(--on-color); }
.map-subtools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-1);
}
.map-subtools label { display: inline-flex; align-items: center; gap: var(--sp-1); }
.map-subtools select { min-height: var(--touch-min); }
.map-bg-tools .hidden-file { display: none; }

/* In-progress drawing overlay */
.map-draft-line {
  fill: none;
  stroke: var(--brand);
  stroke-width: 2;
  stroke-dasharray: 6 4;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.map-draft-pt {
  fill: var(--bg);
  stroke: var(--brand);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.map-draft-pt.first { fill: var(--brand); }

/* Selected marker + rotation handle (move tool) */
.map-marker.sel .ring { stroke-dasharray: 4 3; }
/* Multi-selection (align/distribute): same dashed ring, brand-tinted. */
.map-marker.msel .ring { stroke-dasharray: 4 3; stroke: var(--brand); }
/* Rubber-band selection rectangle (move tool on empty canvas). */
.map-marquee .mq-rect { fill: color-mix(in srgb, var(--brand) 12%, transparent); stroke: var(--brand); stroke-dasharray: 5 4; stroke-width: 1.5; vector-effect: non-scaling-stroke; pointer-events: none; }
/* Grouped align/distribute buttons in the floating multi-selection bar. */
.map-alignbar .map-aligngrp { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--border); border-radius: var(--radius-sm); }

/* Brief highlight when a "Vezi pe plan" hook centres on a marker. */
.map-marker.pulse .ring { animation: map-pulse .8s ease-out 3; }
@keyframes map-pulse {
  0%   { stroke-width: 3; }
  50%  { stroke-width: 10; }
  100% { stroke-width: 3; }
}

.map-help-btn { font-size: 18px; font-weight: 700; line-height: 1; }
.map-rot-stem {
  stroke: var(--brand);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}
.map-rot-handle {
  fill: var(--brand);
  stroke: var(--bg);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  cursor: grab;
}

/* ---- overlay images placed on the plan (PNG/JPEG/GIF, alpha preserved) ---- */
.map-overlay { pointer-events: none; }              /* image never blocks markers/zones */
.map-ovhit { fill: transparent; cursor: move; }     /* edit-mode grab area (whole image) */
.map-ovbox {
  fill: none;
  stroke: var(--brand);
  stroke-width: 2;
  stroke-dasharray: 6 4;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.map-ovresize {
  fill: var(--brand);
  stroke: var(--bg);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  cursor: nwse-resize;
}

/* ---- plan legend modal (concrete live-SVG examples) ---- */
/* Multi-column layout: sections flow into 300px-wide columns (1 on phones,
 * 2–3 in the wide modal) and never break mid-section. */
.mlg-cols { column-width: 300px; column-gap: var(--sp-5); }
.mlg-sec { break-inside: avoid; margin-bottom: var(--sp-3); }
.mlg-title { margin: 0 0 var(--sp-1); }
.mlg-hint { margin-bottom: var(--sp-2); font-size: var(--fs-sm); }
.mlg-row { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-2); font-size: var(--fs-sm); }
.mlg-ex { flex: none; width: 48px; display: flex; justify-content: center; }
.mlg-ex svg { width: 44px; height: 44px; overflow: visible; }
.mlg-list { padding-left: var(--sp-4); font-size: var(--fs-sm); line-height: 1.7; }

/* ---- delayed hover info card on plan markers (~1s) ---- */
.map-hovercard {
  position: absolute;
  z-index: 6;
  min-width: 216px;
  max-width: 300px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-sm);
  pointer-events: none;   /* never steals the pointer from the plan below */
}
.map-hovercard .mhc-head { display: flex; align-items: center; gap: var(--sp-1); margin-bottom: var(--sp-1); }
.map-hovercard .mhc-ico .icn { width: 18px; height: 18px; }
.map-hovercard .mhc-row { display: flex; justify-content: space-between; gap: var(--sp-2); }
.map-hovercard .mhc-row + .mhc-row { margin-top: var(--sp-1); }
.map-hovercard .mhc-row > .muted { flex: none; }
.map-hovercard .mhc-alert { color: var(--error); font-weight: 600; }

/* ---- right-click context menu on plan elements ---- */
.map-ctxmenu {
  position: absolute;
  z-index: 6;
  min-width: 184px;
  max-width: calc(100% - var(--sp-4));
  max-height: 70vh;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--sp-1);
}
.map-ctxmenu ul { list-style: none; margin: 0; padding: 0; }
.map-ctxitem {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-radius: calc(var(--radius) - 2px);
  padding: var(--sp-2) var(--sp-3);
  font: inherit;
  color: var(--text);
  cursor: pointer;
}
.map-ctxitem:hover { background: var(--surface-2); }
/* keep the global :focus-visible ring for keyboard users (was killed by outline:none) */
.map-ctxitem.danger { color: var(--error); }
.btn.is-busy { opacity: .6; pointer-events: none; }

/* ---- "Adaugă imagine" modal: gallery of uploaded images + upload control ---- */
.map-imgmodal .hidden-file,
.map-imgupload .hidden-file { display: none; }
.map-imggrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: var(--sp-2);
  max-height: 46vh;
  overflow-y: auto;
}
.map-imgtile {
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  cursor: pointer;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.map-imgtile:hover { border-color: var(--brand); }
.map-imgtile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.map-imgtile-add {
  flex-direction: column;
  gap: var(--sp-1);
  border-style: dashed;
  color: var(--brand);
  font-size: var(--fs-sm);
  line-height: 1.15;
  text-align: center;
  padding: var(--sp-1);
}
.map-imgtile-add .icn { width: 22px; height: 22px; }
/* Gallery tile with a corner delete button (disabled when the image is in use). */
.map-imgtile-img { position: relative; cursor: default; }
.map-imgtile-del {
  position: absolute; top: 4px; right: 4px;
  width: 26px; height: 26px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--text) 70%, transparent); color: var(--on-color); border: none; cursor: pointer;
}
.map-imgtile-del .icn { width: 15px; height: 15px; }
.map-imgtile-del:disabled { opacity: .35; cursor: not-allowed; }
.map-imgtile-del:not(:disabled):hover { background: var(--error); }
/* „Mai multe" reglaje ca modal (scrollabil dacă e prea înalt). */
.map-moremodal { max-height: 85vh; overflow-y: auto; }

/* ---- wider plan: the map screen fills the main area edge-to-edge ---- */
.app-main.main-wide { max-width: none; padding-left: 0; padding-right: 0; }
/* Wide-but-padded variant (Structura): lift the 1280px cap, keep the gutters. */
.app-main.main-xwide { max-width: none; }
#screen-map { padding: 0 var(--sp-4); }
#screen-map .map-wrap {
  height: clamp(460px, 84vh, 1500px);
  margin-left: calc(-1 * var(--sp-4));
  margin-right: calc(-1 * var(--sp-4));
  width: auto;
  border-radius: 0;
}

/* Plan screen: umple fereastra — planul ocupă spațiul rămas (scrollabil), iar
   acțiunile (Printează / Exportă / Editează / Salvează / Ajutor) stau JOS și
   rămân mereu vizibile, fără să derulezi toată pagina. */
#screen-map .map-body {
  display: flex;
  flex-direction: column;
  height: calc(100dvh - var(--header-h) - var(--tabbar-h) - var(--sp-8));
  min-height: 380px;
}
#screen-map .map-body > .map-wrap { flex: 1 1 auto; height: auto; min-height: 0; }
#screen-map .map-body > .map-controls { order: 10; flex: 0 0 auto; margin-top: var(--sp-2); margin-bottom: 0; }

/* ---- metric (cm) grid, world-fixed ---- */
.map-grid { pointer-events: none; }   /* decorative — clicks pass through to below-grid images */
/* Locked-element padlock badge (edit mode). */
.map-lockbadge { pointer-events: none; }
.map-lockbadge-bg { fill: var(--warn); stroke: var(--bg); }
.map-lockbadge-body { fill: var(--bg); }
.map-lockbadge-sh { stroke: var(--bg); }
.map-grid-bg { fill: transparent; pointer-events: none; }
.map-grid-line {
  stroke: var(--border);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  opacity: .5;
  pointer-events: none;
}
.map-grid-line.maj { stroke: var(--text-muted); opacity: .6; }

/* ---- per-object status light (always visible) ---- */
.map-marker .mk-status { stroke: var(--bg); stroke-width: 2; vector-effect: non-scaling-stroke; pointer-events: none; }
.map-marker .mk-status.s-alert   { fill: var(--st-alert); }
.map-marker .mk-status.s-missed  { fill: var(--st-missed); }
.map-marker .mk-status.s-await   { fill: var(--st-await); }
.map-marker .mk-status.s-pending { fill: var(--st-pending); }
.map-marker .mk-status.s-done    { fill: var(--st-done); }
.map-marker .mk-status.s-none    { fill: var(--surface-2); stroke: var(--border); stroke-width: 1; }
.map-marker .mk-status.s-none    { fill: var(--surface-2); }

/* composite health dot (zone cards / object lists): verde / atenție / problemă */
.health-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; display: inline-block; margin-right: 8px; background: var(--surface-2); }
.health-dot.h-ok      { background: var(--st-done); }
.health-dot.h-warn    { background: var(--st-missed); }
.health-dot.h-alert   { background: var(--st-alert); }
.health-dot.h-await   { background: var(--st-await); }
.health-dot.h-pending { background: var(--st-pending); }
.health-dot.h-none    { background: var(--surface-2); }

/* calendar — full-width screen */
body.on-screen-calendar .app-main { max-width: 1700px; }

/* Month grid + persistent day-agenda side by side (stacked on phones). */
.cal-layout { display: grid; grid-template-columns: 1fr; gap: var(--sp-4); align-items: start; }
@media (min-width: 900px) { .cal-layout { grid-template-columns: minmax(0, 2.4fr) minmax(300px, 1fr); } }

.cal-head { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--sp-1); margin-bottom: var(--sp-1); font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted); text-align: center; }
/* Fixed, RESPONSIVE row height per breakpoint — cell content scrolls inside. */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--sp-1); grid-auto-rows: 68px; }
@media (min-width: 560px)  { .cal-grid { grid-auto-rows: 104px; } }
@media (min-width: 1024px) { .cal-grid { grid-auto-rows: 128px; } }
@media (min-width: 1440px) { .cal-grid { grid-auto-rows: 148px; } }
.cal-cell {
  position: relative; height: 100%; min-height: 0; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg); padding: var(--sp-1); display: flex; flex-direction: column; gap: var(--sp-1);
  cursor: pointer; text-align: left; overflow: hidden; transition: border-color .12s ease, background-color .12s ease;
}
.cal-cell:hover { border-color: var(--accent); }
.cal-cell.off { opacity: .45; }
.cal-cell.weekend { background: var(--surface); }
.cal-cell.sel { outline: 2px solid var(--accent); outline-offset: -1px; }
.cal-daynum {
  display: inline-flex; align-items: center; justify-content: center; align-self: flex-start; flex: none;
  min-width: 20px; height: 20px; padding: 0 var(--sp-1); border-radius: var(--radius-full);
  font-size: var(--fs-sm); font-weight: 700;
}
.cal-cell.today .cal-daynum { background: var(--brand); color: var(--on-color); }
/* Day number + real-status badge on one row. */
.cal-cell-top { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-1); flex: none; }
/* Real recorded status for past/today days (what actually happened). */
.cal-stat { font-size: var(--fs-xs); font-weight: 700; line-height: 1.5; padding: 0 var(--sp-1); border-radius: var(--radius-full); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60%; }
.cal-stat.s-done   { color: var(--st-done); }
.cal-stat.s-alert  { color: var(--on-color); background: var(--st-alert); }
.cal-stat.s-missed { color: var(--warn-text); background: var(--st-missed); }
.cal-stat.s-await  { color: var(--warn-text); background: var(--st-await); }
.cal-stat.s-pending { color: var(--text-muted); }
/* Future days are projections → de-emphasise the projected pills a touch. */
.cal-cell.cal-future .cal-objs { opacity: .6; }
.cal-cell.cal-future { background: repeating-linear-gradient(135deg, transparent, transparent 7px, color-mix(in srgb, var(--border) 22%, transparent) 7px, color-mix(in srgb, var(--border) 22%, transparent) 8px), var(--bg); }
/* Active-filter summary bar (calendar) + shared legend wrapper. */
.cal-filter-summary { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; padding: var(--sp-1) var(--sp-2); margin-bottom: var(--sp-2); font-size: var(--fs-sm); background: color-mix(in srgb, var(--accent) 12%, var(--surface)); border: 1px solid color-mix(in srgb, var(--accent) 32%, var(--border)); border-radius: var(--radius); }
.cal-filter-summary > .icn { flex: none; color: var(--accent); }
.cal-legend-wrap { margin-bottom: var(--sp-2); }

/* per-day OBJECT list (scrollable) — object name + (task count), small font */
.cal-objs { display: flex; flex-direction: column; gap: var(--sp-1); flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.cal-obj {
  display: flex; align-items: baseline; gap: var(--sp-1); font-size: var(--fs-xs); line-height: 1.25;
  padding: 0 var(--sp-1); border-left: 3px solid var(--info); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
}
.cal-obj .cal-obj-n { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-obj b { flex: none; color: var(--text-muted); font-weight: 700; }
/* Calendar colours by task CATEGORY (not status) — routed through --st-* so the
   palette stays identical to the rest of the app (see .cal-legend "Culoare = tip"). */
.cal-obj.t-ccp   { border-left-color: var(--st-alert); }
.cal-obj.t-ccp b { color: var(--error-text); }
.cal-obj.t-task  { border-left-color: var(--st-pending); }
.cal-obj.t-clean { border-left-color: var(--st-await); }
.cal-obj.t-due   { border-left-color: var(--st-missed); }
/* "+N" overflow row — the cell caps at 4 object groups (see cellObjs). */
.cal-obj-more { font-size: var(--fs-xs); font-weight: 700; color: var(--text-muted); padding: 0 var(--sp-1); flex: none; }
/* Rutina zilnică colapsată sub pastilele „speciale" ale zilei. */
.cal-routine { font-size: var(--fs-xs); color: var(--text-muted); padding: 0 var(--sp-1); }
/* Contorul de încărcare al zilei (verificări planificate) — heat pe praguri. */
.cal-load {
  font-size: var(--fs-xs); font-weight: 700; line-height: 1;
  padding: 2px var(--sp-1); border-radius: var(--radius-full);
  background: var(--surface-2); color: var(--text-muted); flex: none;
}
.cal-load.q2 { background: color-mix(in srgb, var(--st-missed) 22%, var(--surface)); color: var(--text); }
.cal-load.q3 { background: color-mix(in srgb, var(--st-alert) 22%, var(--surface)); color: var(--error-text); }
/* Month title in the toolbar row. */
.cal-month-title { margin: 0; text-align: center; text-transform: capitalize; }
/* Weekend cells share --surface with the pills — swap the pill bg so it keeps
   its contour (pill mode only; on phones the dots carry their own colour). */
@media (min-width: 560px) {
  .cal-cell.weekend .cal-obj { background: var(--bg); }
}
/* PHONE (<560px): the ~43px cells cannot hold named pills (names truncate to
   1-2 chars) — degrade each object group to a coloured dot; details live in
   the day-agenda pane below the grid. */
@media (max-width: 559px) {
  /* leave room at the bottom for the always-visible +N so dots never clip it */
  .cal-objs { flex-direction: row; flex-wrap: wrap; align-content: flex-start; gap: var(--sp-1); overflow: hidden; padding-bottom: 12px; }
  .cal-obj { width: 8px; height: 8px; padding: 0; border: none; border-radius: var(--radius-full); background: var(--info); flex: none; }
  .cal-obj .cal-obj-n, .cal-obj b { display: none; }
  .cal-obj.t-ccp   { background: var(--error); }
  .cal-obj.t-task  { background: var(--info); }
  .cal-obj.t-clean { background: var(--await); }
  .cal-obj.t-due   { background: var(--warn); }
  /* pin +N to the cell corner so a busy day always shows the overflow count */
  .cal-obj-more { position: absolute; right: 2px; bottom: 1px; padding: 0 var(--sp-1); line-height: 1.3; background: var(--bg); border-radius: var(--radius-sm); }
  .cal-stat { max-width: 50%; }
}
/* Assignee/meta badges on event rows: never crush the task label. */
.cal-ev .badge { max-width: 38%; overflow: hidden; text-overflow: ellipsis; flex: none; }

/* legend */
.cal-legend { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); margin-top: var(--sp-2); font-size: var(--fs-sm); color: var(--text-muted); }
.cal-legend span { display: inline-flex; align-items: center; gap: var(--sp-1); }
.cal-legend i { width: 10px; height: 10px; border-radius: var(--radius-full); flex: none; }
.cal-legend .cal-legend-label { font-weight: 600; }
/* Shared status-colour legend (dashboard). The plan reuses its .map-legend. */
.status-legend-wrap { font-size: var(--fs-sm); }
.status-legend-wrap > summary { cursor: pointer; color: var(--text-muted); font-size: var(--fs-sm); }
.status-legend { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); margin-top: var(--sp-2); font-size: var(--fs-sm); color: var(--text-muted); }
.status-legend span { display: inline-flex; align-items: center; gap: var(--sp-1); }
.status-legend i { width: 10px; height: 10px; border-radius: var(--radius-full); flex: none; }

/* persistent day-agenda pane + agenda list view share the event row */
.cal-agenda { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); overflow: hidden; position: sticky; top: var(--sp-2); }
.cal-agenda-head { padding: var(--sp-3); border-bottom: 1px solid var(--border); font-weight: 700; text-transform: capitalize; background: var(--surface); }
.cal-agenda-body { padding: var(--sp-2); display: flex; flex-direction: column; gap: var(--sp-2); max-height: 62vh; overflow: auto; }

/* right-pane grouping: one card per object/asset, its tasks listed under it */
/* flex-shrink:0 is REQUIRED — the parent (.cal-agenda-body) is a fixed-height
   flex column, so without it many groups shrink to a few px each and their
   overflow:hidden clips every row into empty grey bars. Keep natural height,
   let the body scroll instead. */
.cal-grp { border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; flex-shrink: 0; }
.cal-grp-head { display: flex; align-items: center; gap: var(--sp-2); width: 100%; text-align: left; padding: var(--sp-2); background: var(--surface); border: none; border-bottom: 1px solid var(--border); font-weight: 700; font-size: var(--fs-sm); color: var(--text); }
.cal-grp-head .grow { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-grp-head.tappable { cursor: pointer; }
.cal-grp-head.tappable:hover { background: var(--surface-2); }
.cal-grp .cal-ev { padding: var(--sp-1) var(--sp-2); }

.cal-agenda-list { display: flex; flex-direction: column; gap: var(--sp-3); }
.cal-agenda-day { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.cal-agenda-day > h4 { margin: 0; padding: var(--sp-2) var(--sp-3); background: var(--surface); font-size: var(--fs-sm); text-transform: capitalize; border-bottom: 1px solid var(--border); }
.cal-agenda-day.is-today > h4 { color: var(--brand); }

.cal-ev { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2); border-radius: var(--radius-sm); cursor: default; }
.cal-ev.tappable { cursor: pointer; }
.cal-ev.tappable:hover { background: var(--surface); }
.cal-ev-bar { width: 4px; align-self: stretch; min-height: 28px; border-radius: var(--radius-full); background: var(--info); flex: none; }
.cal-ev-bar.t-ccp { background: var(--error); }
.cal-ev-bar.t-task { background: var(--info); }
.cal-ev-bar.t-clean { background: var(--await); }
.cal-ev-bar.t-due { background: var(--warn); }
.cal-ev .grow { min-width: 0; }
.cal-ev strong { font-weight: 600; }

/* ---- dynamic scale bar overlay ---- */
.map-scalebar {
  position: absolute;
  left: calc(var(--sp-3) + env(safe-area-inset-left, 0px));
  bottom: calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
  display: flex;
  align-items: flex-end;
  gap: var(--sp-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--sp-1) var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--text);
  pointer-events: none;
  z-index: 2;
  box-shadow: var(--shadow-sm);
}
.map-scalebar-line { height: 7px; border: 2px solid var(--text); border-top: none; }

/* grid toggle active state in the floating toolbar */
.map-toolbar .icon-btn.active { background: var(--brand); border-color: var(--brand); color: var(--on-color); }
.map-toolbar .icon-btn.active .icn { stroke: var(--on-color); color: var(--on-color); }
.map-measure-tools input[type="range"] { vertical-align: middle; }

/* ---- actions + (în editare) paleta de unelte pe un singur rand ---- */
.map-controls { display: flex; align-items: flex-start; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-2); min-width: 0; }
/* flex 1 1 auto + min-width 0 (nu 0 0 auto): pe îngust, rândul de acțiuni are
 * voie să se STRÂNGĂ, ceea ce îi activează wrap-ul intern — altfel rămânea la
 * lățimea conținutului și ieșea din ecran (scrollbar orizontal). */
.map-controls-actions { display: flex; gap: var(--sp-2); flex: 1 1 auto; min-width: 0; flex-wrap: wrap; }
/* Paleta de editare stă pe RÂNDUL EI, mereu de la marginea stângă: cu
 * flex-basis auto lățimea ei de conținut varia cu textul hint-ului și toată
 * paleta „sărea" orizontal la schimbarea uneltei (verificat live). */
.map-controls .map-edit { flex: 1 1 100%; min-width: 0; margin-bottom: 0; }
.map-controls .map-edit .map-toolrow { margin-top: 0; }

/* ---- selectable / deletable placed items ---- */
/* visible wall/door ignore pointer; a transparent thick hit line catches taps */
.map-wall, .map-door { pointer-events: none; }
.map-hit { stroke: transparent; fill: none; cursor: pointer; }
.map-wall.sel { stroke: var(--brand); }
.map-door.sel { stroke: var(--brand); }
.map-zone.sel { stroke: var(--brand); stroke-width: 4; stroke-dasharray: 6 4; }
.map-selbar { align-items: center; }
.map-selbar .btn { min-height: var(--touch-min); }

/* all edit tool groups (palette + subtools + bg + measure) flow on one row */
.map-toolrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-3);
  margin-top: var(--sp-1);
}
.map-toolrow > .map-tools { margin-top: 0; min-width: 0; }

/* "⚙ Mai multe": keep the edit bar on one row; secondary controls (background,
   dimensions/grid, marker size) live in a popover anchored to the gear button. */
.map-more { position: relative; margin-left: auto; }
/* Butonul „Fundal & plan" e ÎN AFARA .map-tools, deci moștenea lățimea FIXĂ
 * (40px) a .icon-btn de bază → eticheta de ~68px ieșea din buton și împingea
 * pagina în scroll orizontal (bug verificat live). Îl aliniem la stilul
 * butoanelor din paletă: coloană icon+etichetă, lățime după conținut. */
.map-more-btn.icon-btn {
  width: auto;
  height: auto;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  padding: var(--sp-1);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  font-size: var(--fs-xs);
  line-height: 1.05;
}
.map-more-btn.active { background: var(--brand); border-color: var(--brand); }
.map-more-btn.active .icn { stroke: var(--on-color); color: var(--on-color); }
.map-morepanel {
  position: absolute;
  top: calc(100% + var(--sp-1));
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  width: max-content;
  max-width: min(92vw, 32rem);
  padding: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}
.map-more-group { display: flex; flex-direction: column; gap: var(--sp-2); }
.map-more-group + .map-more-group { padding-top: var(--sp-3); border-top: 1px solid var(--border); }
.map-more-title { font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted); }
.map-morepanel .map-subtools { margin-top: 0; }

/* ---- "Elemente plasate" list (explicit edit/delete of placed items) ---- */
/* Responsive grid: rows flow into more columns as the sidebar is widened
 * (drag handle). Narrow → 1 per row; wide → several. Header spans all columns. */
.map-placed-group { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); gap: var(--sp-1); align-content: start; }
.map-placed-group > small { grid-column: 1 / -1; }
.map-placed-row { display: flex; align-items: center; gap: var(--sp-1); min-width: 0; }
.map-placed-row .grow { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.map-placed-row .btn { min-height: var(--touch-min); flex: none; }
.map-placed-group small { font-size: var(--fs-sm); }
.map-placed-row .btn.grow { flex: 1 1 auto; min-width: 0; white-space: normal; overflow-wrap: anywhere; justify-content: flex-start; text-align: left; line-height: 1.25; }
.map-placed-row.sel { background: color-mix(in srgb, var(--brand) 12%, transparent); border-radius: var(--radius-sm); box-shadow: inset 3px 0 0 var(--brand); }
/* Map search box (find a placed asset by name/code) — overlay top-right. */
.map-search-overlay { position: absolute; top: var(--sp-2); right: var(--sp-2); z-index: 4; display: flex; align-items: center; gap: var(--sp-1); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-full); padding: var(--sp-1) var(--sp-2); box-shadow: var(--shadow-sm); max-width: 66vw; }
input.map-search-input { border: none; background: none; font-size: var(--fs-sm); min-width: 0; width: 170px; max-width: 46vw; padding: var(--sp-1); }
input.map-search-input:focus { outline: none; box-shadow: none; }
.map-search-overlay .icon-btn { flex: none; }
.map-infocard-trend { margin: var(--sp-2) 0; }
/* Quick-glance summary strip at the top of the object modal (moved from the map peek). */
.obj-glance { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--sp-2); margin-bottom: var(--sp-2); background: var(--surface); }
.obj-glance .map-infocard-trend { margin: var(--sp-1) 0 0; }
/* Clamp long descriptions in list rows (full text lives in the editor). */
.desc-clamp { display: -webkit-box !important; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* ===== Combobox cu căutare pentru filtre (tpl-combo / comboFilter) ===== */
.combo { position: relative; }
.combo input { width: 100%; padding-right: var(--sp-4); }
.combo-clear { position: absolute; right: var(--sp-1); top: 50%; transform: translateY(-50%); background: none; border: 0; color: var(--text-muted); cursor: pointer; font-size: var(--fs-sm); padding: var(--sp-1); line-height: 1; }
.combo-list { position: absolute; top: calc(100% + var(--sp-1)); left: 0; min-width: 100%; max-height: 260px; overflow: auto; z-index: calc(var(--z-header) + 10); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); }
.combo-item { display: block; width: 100%; text-align: left; background: none; border: 0; padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); color: var(--text); cursor: pointer; white-space: nowrap; }
.combo-item:hover, .combo-item.hi { background: color-mix(in srgb, var(--brand) 12%, transparent); }
.combo-item.sel { font-weight: 600; color: var(--brand); }
.combo-empty { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }

/* ===== Tururi ghidate (tutorial.js) ===== */
/* Rădăcina e mereu în DOM după primul tur; .open o afișează. Spotlight-ul e un
   div peste țintă cu box-shadow uriaș (decupaj); backdrop-ul transparent separat
   blochează click-urile pe pagină. Peste sheets/modale (--z-sheet + 60). */
.tut-root { display: none; }
.tut-root.open { display: block; }
.tut-backdrop { position: fixed; inset: 0; z-index: calc(var(--z-sheet) + 60); background: transparent; }
.tut-spot { position: fixed; z-index: calc(var(--z-sheet) + 61); border-radius: var(--radius-sm);
  box-shadow: 0 0 0 9999px color-mix(in srgb, #000 55%, transparent), 0 0 0 2px var(--brand);
  pointer-events: none; transition: all .25s ease; }
.tut-card { position: fixed; z-index: calc(var(--z-sheet) + 62); width: min(360px, calc(100vw - 24px));
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  padding: var(--sp-3); transition: top .25s ease, left .25s ease; }
.tut-card:focus { outline: none; }
.tut-title { margin: 0 var(--sp-4) var(--sp-1) 0; font-size: var(--fs-base); }
.tut-body { font-size: var(--fs-sm); color: var(--text-muted); line-height: 1.5; }
.tut-x { position: absolute; top: var(--sp-1); right: var(--sp-1); background: none; border: 0;
  color: var(--text-muted); font-size: var(--fs-base); cursor: pointer; padding: var(--sp-1); line-height: 1; }
.tut-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); margin-top: var(--sp-2); }
.tut-count { color: var(--text-muted); font-size: var(--fs-xs); }
.tut-btns { display: flex; gap: var(--sp-2); }
.tut-prev, .tut-next { border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: var(--sp-1) var(--sp-3); font-size: var(--fs-sm); cursor: pointer; background: var(--surface); color: var(--text); }
.tut-next { background: var(--brand); border-color: var(--brand); color: var(--on-color); font-weight: 600; }

/* „Afișează mai mult / mai puțin" — comută .desc-clamp pe descrierea de deasupra. */
.desc-more { background: none; border: 0; padding: 0; margin-top: var(--sp-1); color: var(--brand); font-size: var(--fs-xs); font-weight: 600; cursor: pointer; display: inline-block; }
.desc-more:hover { text-decoration: underline; }
/* Operator filter bar (De făcut) — own row under the chips, highlighted when active. */
/* Rând lat cu select de operator — folosit de bara de atribuire în masă din
   lista de sarcini (filtrul „Responsabil" din feed a devenit .feed-assignee-inline). */
.feed-assignee-row { display: flex; align-items: center; gap: var(--sp-2); margin: var(--sp-2) 0; padding: var(--sp-1) var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.feed-assignee-row .icn { width: 15px; height: 15px; flex: none; }
.feed-assignee-row label { font-size: var(--fs-sm); flex: none; }
.feed-assignee-row select { flex: 1 1 auto; min-width: 0; max-width: 280px; font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); }
.feed-assignee-row .icon-btn { flex: none; }
.feed-assignee-row.on { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 8%, var(--surface)); }

/* "Elemente" sidebar — collapsible overlay on the right edge of the plan. */
.map-elem { position: absolute; top: 0; right: 0; height: 100%; z-index: 5; display: flex; align-items: stretch; max-width: 95%; pointer-events: none; }
.map-elem > * { pointer-events: auto; }
.map-elem-toggle { flex: none; align-self: center; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-1); background: var(--bg); color: var(--text); border: 1px solid var(--border); border-right: none; border-radius: var(--radius) 0 0 var(--radius); padding: var(--sp-2) var(--sp-1); min-width: var(--touch-min); cursor: pointer; box-shadow: var(--shadow-sm); font-weight: 600; }
.map-elem-tablabel { writing-mode: vertical-rl; font-size: var(--fs-sm); }
/* Drag handle on the sidebar's left edge — resize the list wider/narrower. */
.map-elem-resize { position: relative; flex: none; width: 10px; align-self: stretch; cursor: ew-resize; background: var(--border); opacity: .7; touch-action: none; transition: opacity .12s, background .12s; }
/* Visible grip dots so the drag-to-resize edge is discoverable. */
.map-elem-resize::before {
  content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 2px; height: 26px; border-radius: var(--radius-full);
  background: radial-gradient(circle, var(--text-muted) 1px, transparent 1.4px) 0 0 / 2px 5px repeat-y;
}
.map-elem-resize:hover, .map-elem-resize.dragging { opacity: 1; background: var(--brand); }

/* Inline keyboard-key hints (help modal). */
kbd { display: inline-block; padding: .05em .4em; font: inherit; font-size: .85em; line-height: 1.4; color: var(--text); background: var(--surface-2); border: 1px solid var(--border); border-bottom-width: 2px; border-radius: var(--radius-sm); white-space: nowrap; }
.map-elem-body { flex: 1 1 auto; width: 244px; max-width: 100%; max-height: 100%; overflow-y: auto; display: flex; flex-direction: column; gap: var(--sp-1); background: var(--bg); border-left: 1px solid var(--border); box-shadow: var(--shadow-lg); padding: var(--sp-2); font-size: var(--fs-sm); }
.map-elem-head { font-weight: 600; font-size: var(--fs-base); }
/* Compact list rows: smaller targets + font than the app-wide touch minimum. */
.map-placed-row .btn.grow { min-height: 0; padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }
.map-placed-row .icon-btn { min-height: 0; width: 26px; height: 26px; padding: 0; }
/* Uniform icon slot: every element icon occupies the same fixed box so labels
 * line up, regardless of the icon's intrinsic size. */
.map-placed-row > span:first-child { flex: none; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; }
.map-placed-row [x-html] svg, .map-placed-row > span:first-child svg, .map-placed-row .icn { width: 16px; height: 16px; }
.map-placed-group small { font-size: var(--fs-xs); }
.map-elem-add { flex: none; min-height: 0; font-size: var(--fs-xs); padding: 2px var(--sp-1); }
/* Zone-grouped element list: a zone header (click to center) + its objects. */
.map-elem-zonegroup { display: flex; flex-direction: column; gap: var(--sp-1); }
.map-elem-zonehead { display: flex; align-items: center; gap: var(--sp-1); border-bottom: 1px solid var(--border); }
.map-elem-zonehead .grow { flex: 1 1 auto; min-width: 0; font-weight: 600; }
.map-elem-zonehead .map-zonehead-btn { min-height: 0; padding: var(--sp-1) var(--sp-2); justify-content: flex-start; text-align: left; }
.map-elem-zonehead .map-zonehead-lbl { padding: var(--sp-1) var(--sp-2); overflow-wrap: anywhere; }
.map-elem-zonehead.sel { background: color-mix(in srgb, var(--brand) 12%, transparent); border-radius: var(--radius-sm); }
.map-elem-tag { flex: none; align-self: center; font-size: var(--fs-xs); color: var(--text-muted); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0 var(--sp-1); white-space: nowrap; }

/* "Sarcini pe tip de activ" overview page */
.tt-typeico { display: inline-flex; width: 22px; height: 22px; align-items: center; justify-content: center; flex: none; }
.tt-typeico svg { width: 20px; height: 20px; }
.tt-tasklist { display: flex; flex-direction: column; gap: var(--sp-2); }
.tt-taskrow { border-top: 1px solid var(--border); padding-top: var(--sp-2); }
.tt-taskrow:first-child { border-top: 0; padding-top: 0; }
.tt-taskhead { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-1); }
.tt-objs { display: flex; flex-wrap: wrap; gap: var(--sp-1); }
.tt-objname { min-height: 0; padding: 2px var(--sp-1); justify-content: flex-start; text-align: left; }
.tt-objtasks { list-style: none; margin: 0; padding: 0 0 0 var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-1); }
.tt-objtasks li { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.tt-objtasks li::before { content: "•"; color: var(--text-muted); }
.tt-task-title { flex: 1 1 auto; min-width: 0; }
/* Responsible-person chip (asset / task) — muted, icon + name. */
.tt-who { background: var(--surface-2); color: var(--text-muted); border-color: var(--border); }
.tt-who .icn { width: 12px; height: 12px; }
/* Coverage gaps (v491): tasks other assets of the same type have, this one doesn't. */
.tt-gaps { list-style: none; margin: var(--sp-1) 0 0; padding: 0 0 0 var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-1); }
.tt-gaps li { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.tt-gaps li::before { content: "+"; color: var(--warn-text); font-weight: 700; }
.tt-gaps .btn { min-height: 0; padding: 2px var(--sp-2); font-size: var(--fs-sm); }
.tt-gap-note { font-size: var(--fs-xs); white-space: nowrap; }
/* Copy-tasks-to-other-assets target picker (in the object task manager). */
.copy-targets { max-height: 46vh; overflow-y: auto; display: flex; flex-direction: column; gap: var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--sp-2); }
.copy-grp-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-1); }
.copy-grp-items { display: flex; flex-wrap: wrap; gap: var(--sp-1); }
.copy-item { display: inline-flex; align-items: center; gap: var(--sp-1); padding: var(--sp-1) var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--fs-sm); background: var(--surface); }
.copy-item.sel { background: var(--brand-light); border-color: var(--brand); }
.copy-item input { margin: 0; }
/* Per-asset QR preview in the object modal. */
.asset-qr { width: 220px; max-width: 70vw; margin: 0 auto; aspect-ratio: 1; background: #fff; padding: 8px; border-radius: var(--radius-sm); border: 1px solid var(--border); }
.asset-qr svg { display: block; width: 100%; height: 100%; }
.qr3d { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--sp-1) var(--sp-2); }
.qr3d > summary { cursor: pointer; font-weight: 600; font-size: var(--fs-sm); }
.qr3d-body { padding-top: var(--sp-2); }
/* Etichete & Coduri QR hub — compact grid, several tiles per row. */
.qrl-h { font-size: var(--fs-sm); margin: 0 0 var(--sp-1); }
.qrl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: var(--sp-2); align-items: stretch; }
.qrl-tile { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-md, 10px); background: var(--surface-2); min-width: 0; }
.qrl-tile.sel { background: var(--brand-light); border-color: var(--brand); }
.qrl-tile-top { display: flex; align-items: flex-start; gap: var(--sp-2); cursor: pointer; }
.qrl-chk { flex: none; margin: var(--sp-1) 0 0; }
.qrl-tile-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1); }
/* Full names — wrap, no truncation. */
.qrl-tile-body strong { font-size: var(--fs-sm); line-height: 1.25; overflow-wrap: anywhere; }
.qrl-meta { display: flex; flex-wrap: wrap; gap: var(--sp-1); align-items: center; }
.qrl-meta .badge { overflow-wrap: anywhere; white-space: normal; }
.qrl-tile-act { display: flex; gap: var(--sp-1); margin-top: auto; }
.qrl-tile-act .btn { min-height: 34px; padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }
/* Sticky selection action bar. */
.qrl-bar { position: sticky; top: var(--sp-1); z-index: 5; display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; padding: var(--sp-2); margin-bottom: var(--sp-2); background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow); }
/* Per-type status summary chips (day mode) — wrap under the heading on narrow. */
.tt-agg { display: inline-flex; flex-wrap: wrap; gap: var(--sp-1); }
/* Day navigator: keep the day name from being squeezed by the arrows. */
.tt-daynav .tt-dayname { min-width: 11em; text-align: center; white-space: nowrap; }
input.map-elem-search { width: 100%; font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
/* Keep the search box clear of the sidebar while it's open. */
.map-search-overlay.shifted { right: calc(min(244px, 76vw) + var(--sp-2)); }

/* ---- on-map delete "×" handle + floating action bar ---- */
.map-del { cursor: pointer; }
.map-del circle { fill: var(--error); stroke: var(--bg); stroke-width: 2; vector-effect: non-scaling-stroke; }
.map-del line { stroke: var(--on-color); stroke-width: 2.5; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.map-selfloat {
  position: absolute;
  left: 50%;
  bottom: calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2);
  row-gap: var(--sp-1);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--sp-1) var(--sp-2);
  z-index: 3;
  max-width: calc(100% - var(--sp-4));
}
.map-selfloat .btn { min-height: var(--touch-min); flex: none; }
.map-selfloat .muted { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 38vw; }

/* "Drawing in progress" banner — keeps Termină/Anulează always visible while a
   wall/zone is being drawn (top-centre, under the MOD EDITARE badge). */
.map-draftbar {
  position: absolute;
  left: 50%;
  top: calc(var(--sp-3) + 2rem);
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2);
  background: var(--brand);
  color: var(--on-color, #fff);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--sp-1) var(--sp-2);
  z-index: 4;
  max-width: calc(100% - var(--sp-4));
  font-size: var(--fs-sm);
}
.map-draftbar .btn { min-height: var(--touch-min); flex: none; }

/* ---- zone geometry editing handles ---- */
.map-vtx {
  fill: var(--bg);
  stroke: var(--brand);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
  cursor: grab;
}
.map-vtx.sel { fill: var(--brand); }
.map-mid {
  fill: var(--brand-light);
  stroke: var(--brand);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  cursor: copy;
  opacity: .85;
}
.map-undo { font-size: 20px; line-height: 1; font-weight: 700; }
.icon-btn:disabled, .btn:disabled { opacity: .4; cursor: default; }

/* ---- "MOD EDITARE" badge (banner over the canvas while editing) ---- */
.map-editbadge {
  position: absolute;
  top: calc(var(--sp-2) + env(safe-area-inset-top, 0px));
  /* centered so it doesn't collide with the top-left legend overlay (z-index:5) */
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  pointer-events: none;
  background: var(--brand);
  color: var(--on-color);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: .04em;
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
}

/* ---- "Salvat" flash near the zoom toolbar ---- */
.map-saved {
  position: absolute;
  top: calc(var(--sp-2) + env(safe-area-inset-top, 0px));
  right: calc(var(--touch-min) + var(--sp-3) + env(safe-area-inset-right, 0px));
  z-index: 3;
  pointer-events: none;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  background: var(--st-done);
  color: var(--on-color);
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: 4px var(--sp-2);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
}
.map-saved .icn { width: 16px; height: 16px; stroke: var(--on-color); color: var(--on-color); }

/* ---- type legend (perete / ușă / zonă) ---- */
.map-typelegend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-2);
  align-items: center;
  margin-top: var(--sp-1);
  font-size: var(--fs-sm);
}
.map-typelegend span { display: inline-flex; align-items: center; gap: var(--sp-1); }
.map-legico { width: 20px; height: 14px; flex: none; overflow: visible; }
.map-legico .lg-wall { stroke: var(--text); stroke-width: 5; stroke-linecap: round; }
.map-legico .lg-door { stroke: var(--brand); stroke-width: 3; stroke-linecap: round; stroke-dasharray: 2 4; }
.map-legico .lg-zone { fill: var(--brand); fill-opacity: .22; stroke: var(--brand); stroke-width: 1.5; }

/* ---- slider readout + rotation input ---- */
.map-val { font-variant-numeric: tabular-nums; font-weight: 600; }
.map-rotfield { gap: var(--sp-1); }
.map-rotinput { width: 4.5rem; min-height: var(--touch-min); }

/* ---- Faza B: CCP highlight, citire pe marker, filtru status, info popover ---- */

/* H4 — CCP double-ring + "CCP" tag on the marker */
/* CCP designation ring: DASHED so it reads as a "critical control point" marker,
   not a solid alarm ring. Alert state below turns it solid + semantic red. */
.map-marker .mk-ccp-ring {
  fill: none;
  stroke: var(--brand);
  stroke-width: 2;
  stroke-dasharray: 3 2.4;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
  opacity: .8;
}
.map-marker .mk-ccp-ring.alert {
  stroke: var(--st-alert);
  stroke-width: 3;
  stroke-dasharray: none;   /* solid + thicker = a CCP actually in alert */
  opacity: 1;
}
.map-marker .mk-ccp rect { fill: var(--st-alert); }
.map-marker .mk-ccp text {
  fill: var(--on-color);
  font-weight: 700;
  text-anchor: middle;
  pointer-events: none;
  letter-spacing: .02em;
}

/* H5 — latest numeric reading under the marker name, coloured by status */
.map-marker .mk-reading {
  text-anchor: middle;
  pointer-events: none;
  font-weight: 700;
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 3px;
  vector-effect: non-scaling-stroke;
  fill: var(--text-muted);
}
.map-marker .mk-reading.s-done  { fill: var(--st-done); }
.map-marker .mk-reading.s-alert { fill: var(--st-alert); }
.map-marker .mk-reading.s-none  { fill: var(--text-muted); }

/* H3 — clickable status legend + dimmed (filtered-out) elements */
.map-legend .badge[role="button"] { cursor: pointer; user-select: none; }
.map-legend .badge.off { opacity: .4; filter: grayscale(.6); }
.map-legend-all { min-height: var(--touch-min); padding: 0 var(--sp-2); }
.map-marker.dim { opacity: .18; }
/* Evidențiere pe TIP (Plan 2D): halo în culoarea brandului pe tipul ales — element
   separat de inelul de status, ca acela să rămână lizibil (codifică statusul azi). */
.map-marker .mk-hi-halo {
  fill: none; stroke: var(--brand); stroke-width: 3;
  vector-effect: non-scaling-stroke; opacity: .6; pointer-events: none;
}
/* selectorul „Tip" din legenda-overlay — compact, în ton cu badge-urile */
.map-legend .map-type-hi {
  min-height: 0; padding: 2px var(--sp-2); font-size: var(--fs-xs);
  max-width: 170px; border-radius: var(--radius-full);
  border: 1px solid var(--border); background: var(--bg); color: var(--text);
}
/* Out-of-service object (defect/mentenanță/scos din uz): faded + dashed ring + tag,
   but still visible (it's physically on the plan). */
.map-marker.oos:not(.dim) { opacity: .55; }
.map-marker.oos .ring { stroke-dasharray: 3 2.5; }
.map-marker .mk-oos rect { fill: var(--text-muted); }
.map-marker .mk-oos text { fill: var(--on-color); text-anchor: middle; font-weight: 700; }
.map-zone.dim { opacity: .25; fill-opacity: .06; }

/* H6 — marker info popover (view mode): last reading + who/when */
.map-infocard {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(320px, calc(100% - var(--sp-4)));
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--sp-2) var(--sp-3) var(--sp-3);
  z-index: 4;
}
.map-infocard-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); margin-bottom: var(--sp-1); }
.map-infocard-head strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.map-infocard-body { display: flex; flex-direction: column; gap: var(--sp-1); margin-bottom: var(--sp-2); }
.map-infoval {
  font-size: 1.5rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.map-infoval.s-done  { color: var(--st-done); }
.map-infoval.s-alert { color: var(--st-alert); }
.map-infoval.s-none  { color: var(--text-muted); }

/* ---- Faza C: geometry helpers (dimensions, door swing, wall handles) ---- */

/* G3 — zone area at centroid + generic dimension labels (wall len / draft) */
.map-zone-area {
  fill: var(--text-muted);
  text-anchor: middle;
  font-weight: 600;
  pointer-events: none;
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 3px;
  vector-effect: non-scaling-stroke;
}
.map-dim-label {
  fill: var(--brand);
  text-anchor: middle;
  font-weight: 700;
  pointer-events: none;
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 3px;
  vector-effect: non-scaling-stroke;
}

/* G6 — quarter-circle door swing arc */
.map-door-arc {
  fill: none;
  stroke: var(--brand);
  stroke-width: 1.5;
  stroke-dasharray: 3 4;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
  opacity: .7;
}

/* G2 — draggable wall endpoint handles (reuse the vertex-handle look) */
.map-wend {
  fill: var(--bg);
  stroke: var(--brand);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
  cursor: grab;
}

/* Structura — text+icon action buttons per row (Obiecte/Zone/Puncte) */
.data-table .row-actions { justify-content: flex-end; flex-wrap: wrap; gap: var(--sp-1); }
.data-table .row-actions .btn { min-height: var(--touch-min); padding: var(--sp-1) var(--sp-2); }

/* Task sheet: wider container + 2-column task editor modal */
.sheet.sheet-xwide { max-width: min(1280px, 96vw); }
/* Compact the wide task-manager table so its text row-actions fit without forcing
   the whole 7-column table to horizontally scroll on tablet/desktop. */
.sheet-xwide .data-table th { font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); }
.sheet-xwide .data-table td { font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); }
.sheet-xwide .data-table .btn { min-height: var(--touch-min); padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }
.sheet-xwide .data-table .btn .icn { width: 13px; height: 13px; }
/* Outbox notification log: let the wrapper scroll horizontally instead of crushing
   6 columns into a 360px phone. */
#screen-outbox .data-table { min-width: 640px; }
/* Keep the task-list action buttons on one row (the table scrolls horizontally
   if truly too narrow) instead of stacking them. */
.sheet-xwide .data-table .row-actions { flex-wrap: nowrap; align-items: center; }
/* Compact rows: side-by-side reorder arrows + short buttons (was a 2-button
   vertical stack + touch-height buttons -> every row ~3rem tall). */
.sheet-xwide .data-table .reorder { flex-direction: row; }
.sheet-xwide .data-table .reorder-btn { height: 1.6rem; width: 1.7rem; }
.sheet-xwide .data-table .btn,
.sheet-xwide .data-table .row-actions .btn { min-height: 0; padding: var(--sp-1) var(--sp-2); }
.sheet-xwide .data-table .row-actions .btn { white-space: nowrap; }
.modal.modal-wide { max-width: min(96vw, 1280px); }
/* On phones a wide modal should go truly edge-to-edge like a plain modal. */
@media (max-width: 599px) { .modal.modal-wide { max-width: none; } }
/* Compact fonts in the wide task editor so the 2 columns fit comfortably. */
.modal-wide .modal-head h3 { font-size: var(--fs-base); }
.modal-wide .form-col-h { font-size: var(--fs-sm); }
.modal-wide .field { margin-bottom: var(--sp-2); }
.modal-wide .field > span { font-size: var(--fs-sm); margin-bottom: var(--sp-1); }
.modal-wide input, .modal-wide select, .modal-wide textarea { font-size: var(--fs-base); min-height: var(--touch-min); padding: var(--sp-1) var(--sp-2); }
.modal-wide .chip { font-size: var(--fs-sm); }
.modal-wide .check { font-size: var(--fs-base); }
.modal-wide .rec-explain > div { font-size: var(--fs-base); }
.modal-wide .btn { min-height: var(--touch-min); }

/* Per-operator notification matrix (type × channel) in the operator modal.
 * All channel columns stay visible; a column is dimmed + its checkbox disabled
 * until the operator has that contact (email/phone) or a Telegram binding. */
.notif-matrix { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.notif-matrix th,
.notif-matrix td { padding: var(--sp-1) var(--sp-2); text-align: center; border-bottom: 1px solid var(--border); }
.notif-matrix thead th { font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.notif-matrix th:first-child,
.notif-matrix td.lbl { text-align: left; white-space: nowrap; }
.notif-matrix tbody tr:last-child td { border-bottom: 0; }
.notif-matrix .off { color: var(--text-muted); opacity: 0.45; }
.notif-matrix input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; margin: 0; }
.notif-matrix input[type="checkbox"]:disabled { cursor: not-allowed; }
/* AI proposals sheet (Sarcini HACCP propuse): compact rows so many proposals fit
   without excess whitespace. Tighter gap + card padding; expanded editor stays roomy. */
.ai-props { gap: var(--sp-1); }
.ai-props > .card { padding: var(--sp-2) var(--sp-3); margin-bottom: 0; box-shadow: none; }
.ai-props > .card .badge { padding: 0 var(--sp-1); }
/* dimmed pre-checked disabled boxes read as "on but inert" → make them look pending */
.notif-matrix td.off input[type="checkbox"] { opacity: .5; filter: grayscale(1); }
.notif-rowall { min-height: 0; padding: 0 var(--sp-1); font-size: var(--fs-xs); vertical-align: middle; }

/* Invalid contact input (email / RO phone) — red border + subtle glow. */
.input-invalid,
.input-invalid:focus { border-color: var(--error); box-shadow: 0 0 0 2px var(--error-light); }

/* Asset-category cue (dot + label). Colour is a SECONDARY cue set inline via
   `--cat-c`; the label stays readable in normal text colour. Used across the
   feed (category headers/filter), Structura badges, and the reports rollup. */
.cat-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--cat-c, var(--text-muted)); flex: none; }
.cat-badge {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  font-size: var(--fs-xs); font-weight: 600; color: var(--text-muted);
  padding: 1px var(--sp-1); border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--cat-c, var(--text-muted)) 14%, transparent);
}
.cat-badge .cat-dot { width: 8px; height: 8px; }
.cat-chip .cat-dot { width: 9px; height: 9px; }
/* Reports: per-category compliance rows (dot + label + bar + %). */
.cat-compliance-row { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.cat-compliance-label { min-width: 110px; font-size: var(--fs-sm); }
.cat-compliance-pct { font-size: var(--fs-sm); min-width: 38px; text-align: right; }
/* Compact colour swatch in the category editor. */
.cat-color-input { width: 34px; height: 34px; min-height: 34px; padding: var(--sp-1); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); cursor: pointer; flex: none; }

.form-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-4); }
.form-col-h { margin: 0 0 var(--sp-1); font-size: var(--fs-sm); color: var(--text-muted); font-weight: 600; }
@media (max-width: 599px) { .form-2col { grid-template-columns: 1fr; } }

/* Manager "Tipuri de registre" — fonturi compacte */
.kind-mgr .modal-head h3 { font-size: var(--fs-lg); }
.kind-mgr h4 { font-size: var(--fs-base); }
.kind-mgr .field span { font-size: var(--fs-sm); }
.kind-mgr .field input { font-size: var(--fs-sm); min-height: var(--touch-min); }
.kind-mgr .card strong { font-size: var(--fs-sm); }
.kind-mgr .btn { font-size: var(--fs-sm); min-height: var(--touch-min); }
.kind-mgr p.muted { font-size: var(--fs-sm); }

/* „De făcut" — feed plat cu antete de zonă sticky */
.task-feed { display: flex; flex-direction: column; gap: var(--sp-3); }
/* Each zone is a real container that visually WRAPS its objects + tasks. */
.feed-zone {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  /* NO overflow:hidden here — it would kill the sticky zone header below.
     Corner clipping is done with a matching radius on the head itself. */
}
.feed-zone-head {
  /* Two-tier sticky: the progress strip owns the top slot, so zone headers stick
     just BELOW it. The document scrolls on both mobile and desktop, so the offset
     is header + strip everywhere (see .app-main note in responsive.css). */
  position: sticky; top: calc(var(--header-h) + var(--progress-strip-h)); z-index: 2;
  border-radius: var(--radius) var(--radius) 0 0;
  display: flex; align-items: center; gap: var(--sp-2);
  background: var(--bg); padding: var(--sp-2) var(--sp-2);
  font-size: var(--fs-sm); font-weight: 700; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .03em;
  border-bottom: 1px solid var(--border);
  /* it's a <button> now (keyboard-accessible collapse) — reset the chrome */
  width: 100%; text-align: left; cursor: pointer; font-family: inherit;
  border-left: none; border-right: none; border-top: none;
  min-height: var(--touch-min);
}
.feed-zone-head:hover { background: var(--surface-2); }
/* Object collapse toggle: a real button with a ≥40px tap target (was a 14px span). */
.feed-obj-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--touch-min); min-height: var(--touch-min);
  margin: calc(var(--sp-2) * -1) 0; padding: 0;
  background: none; border: none; cursor: pointer; color: var(--text-muted);
  font-size: var(--fs-base);
}
.feed-obj-toggle:hover { color: var(--text); }
.feed-zone-body { padding: var(--sp-2); display: flex; flex-direction: column; gap: var(--sp-2); }
/* Team/general tasks section: brand-tinted so it reads as distinct from the
   asset (zone/object) task groups. */
.feed-zone-team { background: color-mix(in srgb, var(--brand) 7%, var(--surface)); border-color: color-mix(in srgb, var(--brand) 35%, var(--border)); }
.feed-zone-team .feed-zone-head { background: color-mix(in srgb, var(--brand) 12%, var(--bg)); color: var(--brand); }
/* Objects sit inside the zone box, indented with an accent rail so it's clear
   they belong to that zone. */
.feed-obj {
  border-left: var(--sp-1) solid var(--border);
  padding: var(--sp-2);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--surface-2);
}
/* Colored grouping per asset, tinted by its worst task status (fo-<status>).
   Colours come from the shared --st-* status tokens (single source of truth). */
.feed-obj.fo-done    { background: color-mix(in srgb, var(--st-done) 12%, var(--surface));    border-left-color: var(--st-done); }
.feed-obj.fo-alert   { background: color-mix(in srgb, var(--st-alert) 12%, var(--surface));   border-left-color: var(--st-alert); }
.feed-obj.fo-missed  { background: color-mix(in srgb, var(--st-missed) 16%, var(--surface));  border-left-color: var(--st-missed); }
.feed-obj.fo-await   { background: color-mix(in srgb, var(--st-await) 12%, var(--surface));   border-left-color: var(--st-await); }
.feed-obj.fo-pending { background: color-mix(in srgb, var(--st-pending) 10%, var(--surface)); border-left-color: var(--st-pending); }
.feed-obj-head {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); font-weight: 700; color: var(--text);
  padding: 0 0 var(--sp-1);
}
/* Object name is a real button (opens the asset hub) — looks like the old text
   label but is clearly tappable/focusable. Inert for team scope (no hub). */
.feed-obj-name {
  flex: 1 1 auto; min-width: 0; text-align: left;
  font: inherit; color: inherit; padding: var(--sp-1) 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  cursor: pointer; border-radius: var(--radius-sm);
}
.feed-obj-name:not(.is-inert):hover { text-decoration: underline; }
.feed-obj-name.is-inert { cursor: default; pointer-events: none; }
/* Denumirea tipului în antetul de obiect — metadată discretă lângă cod. */
.feed-obj-type { flex: none; font-size: var(--fs-sm); font-weight: 400; white-space: nowrap; }
/* Per-object "bifează toate conforme" shortcut — compact, low-emphasis. */
.feed-obj-bulk { flex: none; padding: 2px var(--sp-2); font-size: var(--fs-sm); min-height: var(--touch-min); }
/* "Filtru activ" banner — visible echo of the active status/category filter so
   hidden tasks never read as missing (esp. on mobile where filters are selects). */
.feed-active-filter {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: var(--sp-1) var(--sp-2); margin-bottom: var(--sp-2);
  font-size: var(--fs-sm);
  background: color-mix(in srgb, var(--accent) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
  border-radius: var(--radius);
}
.feed-active-filter .icn { flex: none; color: var(--accent); }
.feed-active-filter .btn { flex: none; }
/* Slim "your team tasks" summary line (replaces a full card that only redirected). */
.feed-mytasks {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2); margin-bottom: var(--sp-2);
  font-size: var(--fs-sm); color: var(--text-muted);
  border-left: 3px solid var(--brand); background: var(--surface);
  border-radius: var(--radius-sm);
}
.feed-mytasks .icn { flex: none; color: var(--brand); }
/* x/y progress counter on zone/object heads — plain muted figures, exempt from
   the uppercase styling of the zone head, tabular so columns don't wiggle. */
.feed-count {
  color: var(--text-muted); font-size: var(--fs-sm); font-weight: 600;
  text-transform: none; letter-spacing: 0; font-variant-numeric: tabular-nums;
}
/* Small dimmed hint icon (13px) used inline in heads and rows. */
.icn-hint { width: 13px; height: 13px; opacity: .5; }
/* One-line dismissable-feel note at the top of the feed (suspended assets). */
.feed-note {
  display: flex; align-items: center; gap: var(--sp-2);
  width: 100%; text-align: left; cursor: pointer;
  color: var(--text-muted); font-size: var(--fs-sm);
  padding: var(--sp-1) 0; background: none; border: none;
}
.feed-note .icn { width: 13px; height: 13px; flex: none; }
.feed-note > span:last-child { margin-left: auto; font-size: var(--fs-lg); line-height: 1; }
/* Chip-ul compact „restanțe azi" din capul feed-ului (buton cu corp de card;
   anulează width:100% din .feed-note). Neconformitățile stau doar în banda de
   progres — butonul .progress-strip-capa.is-alert. */
.feed-note-missed {
  width: auto; flex: 0 1 260px; min-width: 0;
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
}
/* Sheet acțiune corectivă: cardul „Recomandat pentru această sarcină" (textul din
   șablonul sarcinii) + chips-urile „folosite recent" (conturate cu liniuță). */
.ca-sug-rec {
  display: flex; flex-direction: column; gap: var(--sp-1);
  padding: var(--sp-2); margin-bottom: var(--sp-2);
  font-size: var(--fs-sm);
  border: 1px solid color-mix(in srgb, var(--brand) 35%, var(--border));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--brand) 8%, var(--surface));
}
.ca-sug-rec .btn { align-self: flex-start; }
.chip-recent { border-style: dashed; }
/* Tasks within one object: responsive grid so several cards sit on a row on
   wider screens and collapse to a single column on phones (auto-fill by width).
   `min(300px, 100%)` is load-bearing: a bare minmax(300px,…) track cannot shrink
   below 300px, so inside the nested zone/object padding it overflowed the card
   column on ≤360px phones (whole feed scrolled sideways). min(…,100%) lets the
   single column collapse to the available width on narrow screens. */
.feed-obj-tasks { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: var(--sp-2); align-items: start; }
/* Density: the feed shows many cards per day — tighten padding vs a standalone
   card so the daily list scrolls less (multi-column reflow already handled above). */
.task-feed .task-card { padding: var(--sp-2); }
/* Inline temperature/text entry on the card — save a reading without opening a
   sheet. The "…" button still opens the full numpad for steppers/typical value. */
.task-inline-entry { display: flex; align-items: center; gap: var(--sp-1); flex-wrap: wrap; margin-top: var(--sp-2); }
.task-inline-input {
  flex: 1 1 7rem; min-width: 5rem; max-width: 14rem;
  min-height: var(--touch-min); padding: var(--sp-1) var(--sp-2);
  font-size: var(--fs-base); border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
}
.task-inline-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.task-inline-entry .btn { flex: none; min-height: var(--touch-min); }
/* The grid gap owns the spacing between cards — the .card bottom margin would
   stack on top of it (real distance was 20px, not the 8px the gap suggests). */
.feed-obj-tasks .card { margin-bottom: 0; }
.feed-row { width: 100%; text-align: left; }

/* Documente — grilă de carduri cu thumbnail/preview */
.doc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: var(--sp-3); }
.doc-card { display: flex; flex-direction: column; }
/* Space-less filenames (IMG_20260704_123.jpg) must wrap, not blow the 180px card. */
.doc-card strong { overflow-wrap: anywhere; }
/* Selected-file name inside upload buttons: ellipsize instead of widening the button. */
.file-name { max-width: 14ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: bottom; }
.doc-thumb {
  width: 100%; aspect-ratio: 4 / 3; border-radius: var(--radius); overflow: hidden;
  background: var(--surface-2); border: 1px solid var(--border); cursor: pointer;
  display: flex; align-items: center; justify-content: center; margin-bottom: var(--sp-2);
}
.doc-thumb img { width: 100%; height: 100%; object-fit: cover; }
.doc-file { display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); color: var(--text-muted); }
.doc-file .icn { width: 32px; height: 32px; }
.doc-file span { font-size: var(--fs-sm); font-weight: 600; }

/* Operatori — lista ca grilă de carduri care folosește lățimea ecranului */
.ops-list-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); gap: var(--sp-3); }
.op-card { display: flex; flex-direction: column; }
.op-card .grow { min-width: 0; }

/* Operator add/edit modal: two panels (form | notifications + allowed
   locations) on wide screens, stacked on narrow ones. The class was referenced
   from markup but never defined — the modal collapsed to one 1050px column. */
.reg-form-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: var(--sp-4); align-items: start; }
@media (max-width: 899px) { .reg-form-grid { grid-template-columns: 1fr; } }

/* Pagina Operatori folosește o lățime mai mare decât standardul (1280px).
   Lățim chiar containerul .app-main doar pe acest ecran → fără overflow/transform. */
body.on-screen-operators .app-main { max-width: 1700px; }
body.on-screen-teamTasks .app-main { max-width: 1700px; }

/* Obiecte dezafectate — rând estompat în Organizare Active */
tr.is-decommissioned { opacity: .5; }
tr.is-decommissioned strong { text-decoration: line-through; }

/* CAPA: the add-form opener is the page's primary action — style it like an
   action, not like the muted archive summary below it. */
.capa-add {
  display: flex; align-items: center; gap: var(--sp-2);
  min-height: var(--touch-min); cursor: pointer; list-style: none;
  color: var(--brand-dark); font-weight: 600; font-size: var(--fs-base);
}
.capa-add::-webkit-details-marker { display: none; }

/* Report filter bar: fields inline, bottom-aligned, no per-field margins
   (replaces the repeated style="margin:0" on every field). */
.report-filters { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: flex-end; }
.report-filters .field { margin: 0; }
.report-filters .check { min-height: var(--touch-min); }

/* ---------- Raport ierarhic (punct de lucru → zonă → obiect → sarcini) ---------- */
.hierarchical-report .hr-search { min-width: 160px; }
/* Badge legend above the tree (what ✓/✕/! and % mean). */
.hr-legend { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-2); margin-bottom: var(--sp-2); font-size: var(--fs-sm); }
.hr-legend .badge { font-size: var(--fs-xs); }
.hr-wp, .hr-zone, .hr-eq { border: 1px solid var(--border); border-radius: var(--radius-sm); margin: var(--sp-2) 0; }
.hr-zone { margin-left: var(--sp-3); }
.hr-eq { margin-left: var(--sp-3); border-style: dashed; }
.hr-head {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3); cursor: pointer; list-style: none;
  font-size: var(--fs-base);
  min-height: var(--touch-min);   /* most-tapped control on the report page */
}
.hr-head::-webkit-details-marker { display: none; }
.hr-head::before { content: "▸"; color: var(--text-muted); transition: transform .15s ease; }
details[open] > .hr-head::before { transform: rotate(90deg); }
.hr-wp > .hr-head { background: var(--surface); font-weight: 600; }
.hr-zone > .hr-head { background: color-mix(in srgb, var(--surface) 55%, transparent); }
.hr-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hr-badges { display: flex; align-items: center; gap: var(--sp-1); flex-shrink: 0; }
/* Phones: compact the count badges so the entity name keeps readable width
   (4 full badges + % left ~80px for the name at the equipment level). */
@media (max-width: 599px) {
  .hr-badges .badge { font-size: var(--fs-xs); padding: 0 var(--sp-1); }
  .hr-head { flex-wrap: wrap; }
  .hr-head .hr-name { flex-basis: 55%; }
}
.hr-tasks { padding: var(--sp-1) var(--sp-3) var(--sp-2); }
.hr-task { padding: var(--sp-1) 0; border-top: 1px solid var(--border); }
.hr-task:first-child { border-top: 0; }
.hr-task-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); font-size: var(--fs-sm); }
.hr-occ { display: flex; flex-wrap: wrap; gap: var(--sp-1); margin-top: var(--sp-1); }
.ccp-tag { font-weight: 700; color: var(--error); }

/* ---- rich-text editor (descriptions) + rendered content --------------- */
.rte { border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg); }
.rte-toolbar { display: flex; flex-wrap: wrap; gap: var(--sp-1); padding: var(--sp-1); background: var(--surface); border-bottom: 1px solid var(--border); }
.rte-btn { min-width: 30px; padding: var(--sp-1) var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); color: var(--text); font-size: var(--fs-sm); line-height: 1.1; cursor: pointer; }
.rte-btn:hover { background: var(--surface-2); }
.rte-editable { min-height: 88px; padding: var(--sp-2); font-size: var(--fs-base); color: var(--text); outline: none; }
.rte-editable:empty::before { content: attr(data-placeholder); color: var(--text-muted); }
.rte-editable ul, .rte-editable ol, .rte-content ul, .rte-content ol { margin: var(--sp-1) 0; padding-left: var(--sp-4); }
.rte-editable a, .rte-content a { color: var(--brand); }
.rte-content { line-height: 1.5; }
.rte-content p { margin: var(--sp-1) 0; }

/* ---- AI: improve task title + description --------------------------- */
.ai-improve { margin: 0 0 var(--sp-3); }
.ai-improve-btn { font-size: var(--fs-sm); }
.ai-improve-panel { margin-top: var(--sp-2); padding: var(--sp-3); border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border)); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--accent) 6%, var(--surface)); }
.ai-genimg { padding: var(--sp-2); border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border)); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--accent) 6%, var(--surface)); }
.ai-improve-result { margin-top: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-3); }
.ai-sug { padding: var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); }
.ai-sug .rte-content { margin-top: var(--sp-1); }

/* ---- team-tasks page: KPIs, avatars, progress, people board ----------- */
.kpi-bar { display: grid; grid-template-columns: repeat(auto-fit, minmax(clamp(72px, 20vw, 120px), 1fr)); gap: var(--sp-2); }
.kpi-card { display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); padding: var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
.kpi-n { font-size: var(--fs-xl); font-weight: 700; color: var(--text); line-height: 1.1; }
.kpi-l { font-size: var(--fs-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: .03em; }
.kpi-alert .kpi-n { color: var(--error); }
.kpi-pct .kpi-n { color: var(--brand); }
.avatar { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; min-width: 30px; border-radius: var(--radius-full); font-size: var(--fs-xs); font-weight: 700; }
.progress { height: 8px; background: var(--surface-2); border-radius: var(--radius-full); overflow: hidden; }
.progress-bar { height: 100%; background: var(--brand); border-radius: var(--radius-full); transition: width .2s; }
.people-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-3); }
@media (min-width: 600px) { .people-grid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); } }
@media (min-width: 1000px) { .people-grid { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); } }
.person-card { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--sp-3); background: var(--bg); }
.person-day { flex: none; width: 4em; font-size: var(--fs-xs); white-space: nowrap; }

/* Completion-history pseudo-table: fixed columns so "Cine"/"Stare" align
   across rows AND with the header (auto widths looked ragged). */
.tt-hist-row { display: grid; grid-template-columns: 1fr 9em 7em; align-items: center; gap: var(--sp-2); }
.tt-hist-row > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Done occurrences: fade + strike the title so completion reads at a glance.
   The title is the first span inside .grow (there is no <strong> on these rows). */
.tt-row.tt-done { opacity: .68; }
.tt-row.tt-done strong,
.tt-row.tt-done .grow > span:first-child { text-decoration: line-through; color: var(--text-muted); }

/* Per-day header progress: fixed on desktop, full-width when the header stacks. */
.tt-day-progress { width: 84px; height: 6px; }

/* Badge hierarchy on agenda rows: keep status/importance prominent, mute the
   informational badges (recurrence, due time, photo/attach icons). */
.tt-row .badge:not([class*="s-"]):not(.imp-badge) { opacity: .7; }

/* History heading in the detail modal: match the section headings above it. */
.tt-h4 { margin: 0 0 var(--sp-1); font-size: var(--fs-base); color: var(--text-muted); font-weight: 600; }

/* Attribute grid in the team-task detail modal — icon tiles laid out in columns
   so the info is scannable, not a stacked list of bare badges. */
.tt-info { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--sp-2); }
.tt-info-cell { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); min-width: 0; }
.tt-info-ic { width: 18px; height: 18px; flex: none; color: var(--brand); }
.tt-info-body { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.tt-info-k { font-size: var(--fs-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: .03em; font-weight: 600; }
.tt-info-v { font-size: var(--fs-base); color: var(--text); font-weight: 600; display: flex; align-items: center; gap: var(--sp-1); min-width: 0; }
.tt-info-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tt-hist-head { font-size: var(--fs-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: .03em; font-weight: 600; }

/* Task card: show the template description under the title/status. */
.task-card-desc { display: block; margin-top: var(--sp-1); font-size: var(--fs-sm); line-height: 1.4; }
/* Guidance banner for a task awaiting proof (photo/signature) — makes the next
   step obvious instead of leaving it silently stuck in "await". */
.task-await-hint { margin-top: var(--sp-2); padding: var(--sp-1) var(--sp-2); border-radius: var(--radius-sm); background: var(--await-light); color: var(--await-text); font-size: var(--fs-sm); border: 1px solid color-mix(in srgb, var(--await) 30%, transparent); }
.task-await-hint .icn { width: 15px; height: 15px; flex: none; }
.task-await-hint .btn { min-height: var(--touch-min); font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); flex: none; }
/* Thumbnails of photos attached to a task, shown on the card. */
.task-card-photos { display: flex; flex-wrap: wrap; gap: var(--sp-1); margin-top: var(--sp-2); }
.task-photo { display: block; width: 48px; height: 48px; padding: 0; border-radius: var(--radius-sm); overflow: hidden; border: 1px solid var(--border); background: none; cursor: zoom-in; }
.task-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Report: compliance trend sparkline. */
.trend-svg { display: block; width: 100%; }
/* Per-location mini sparkline in the "Toate locațiile" list rows. */
.loc-agg-spark { width: 100px; height: 28px; flex: 0 0 auto; }
.loc-agg-row .health-dot { align-self: center; }
.trend-line { fill: none; stroke: var(--brand); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.trend-area { fill: color-mix(in srgb, var(--brand) 12%, transparent); stroke: none; }

/* Report: per-operator accountability rows. */
.ops-report-grid { display: flex; flex-direction: column; gap: var(--sp-2); }
.ops-report-row { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.ops-report-row .avatar { width: 26px; height: 26px; min-width: 26px; }

/* "Requires photo" badge on the task card — amber until satisfied, green once a
   photo is attached. */
.badge-photo { display: inline-flex; align-items: center; gap: var(--sp-1); background: var(--warn-light); color: var(--warn-text); border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent); }
.badge-photo .icn { width: 12px; height: 12px; }
.badge-photo.badge-photo-ok { background: var(--ok-light); color: var(--ok-text); border-color: color-mix(in srgb, var(--ok) 40%, transparent); }

/* Fullscreen image viewer. */
.lightbox-backdrop { position: fixed; inset: 0; z-index: var(--z-modal, 1000); display: flex; align-items: center; justify-content: center; padding: var(--sp-4); background: color-mix(in srgb, #000 82%, transparent); }
.lightbox-img { max-width: 96vw; max-height: 92vh; object-fit: contain; border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); cursor: zoom-out; }
.lightbox-close { position: absolute; top: var(--sp-3); right: var(--sp-3); color: var(--on-color); background: color-mix(in srgb, #000 40%, transparent); border-radius: var(--radius-full); }

/* Tablets: don't blow the task editor up to full 1100px — the 2-col form gets
   squeezed. Cap it so fields keep a comfortable width. */
@media (min-width: 600px) and (max-width: 899px) { .modal.modal-wide { max-width: 96vw; } }

/* Phones: stack the per-day header so the badge + progress don't crowd the label. */
@media (max-width: 599px) {
  .kpi-bar { grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: var(--sp-1); }
  .kpi-n { font-size: var(--fs-lg); }
  .tt-day-header { flex-wrap: wrap; }
  .tt-day-progress { width: 100%; flex-basis: 100%; }
}

/* ---- team-tasks tabs: a segmented control instead of loose grey chips --- */
.chips-tabs { gap: var(--sp-1); padding: var(--sp-1); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); display: inline-flex; flex-wrap: wrap; }
/* Notificări + Setări: bara de tab-uri pe toată lățimea, cu tab-uri egale.
 * Setări are layout masonry (CSS columns) → column-span ca bara să nu rămână
 * închisă într-o singură coloană. */
#screen-notifications .chips-tabs,
#screen-settings .chips-tabs { display: flex; column-span: all; }
#screen-notifications .chips-tabs .chip,
#screen-settings .chips-tabs .chip { flex: 1; justify-content: center; }
.chips-tabs .chip { border: 1px solid transparent; background: transparent; }
.chips-tabs .chip:hover { background: var(--surface-2); }
.chips-tabs .chip.active { background: var(--bg); border-color: var(--border); color: var(--brand); box-shadow: var(--shadow-sm); }

/* ---- team-tasks: schedule week time-grid + month --------------------- */
.sched-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); }
.sched-grid { display: grid; grid-template-columns: 54px repeat(7, minmax(96px, 1fr)); overflow: hidden; background: var(--bg); }
.sched-corner { background: var(--surface-2); }
/* Day-head band: a solid header row anchors the grid so it reads as a calendar,
   not a field of grey boxes. */
.sched-dayhead { display: flex; flex-direction: column; align-items: center; padding: var(--sp-2) var(--sp-1); background: var(--surface-2); border-left: 1px solid var(--border); font-size: var(--fs-sm); font-weight: 600; }
.sched-dayhead small { font-weight: 400; }
.sched-dayhead.sched-today { background: var(--brand); color: var(--on-color); }
.sched-dayhead.sched-today .muted { color: color-mix(in srgb, var(--on-color) 82%, transparent); }
.sched-timelbl { padding: var(--sp-1); font-size: var(--fs-xs); color: var(--text-muted); text-align: right; border-top: 1px solid var(--border); background: var(--surface); font-variant-numeric: tabular-nums; }
.sched-cell { min-height: 34px; border-top: 1px solid var(--border); border-left: 1px solid var(--border); padding: var(--sp-1); cursor: pointer; transition: background .12s; }
.sched-cell:hover { background: var(--accent-light); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent); }
.sched-untimed { min-height: 38px; background: color-mix(in srgb, var(--warn) 8%, var(--surface)); }
/* "Toată ziua" band label — most team tasks land here (no precise time), so
   make it read as a real header rather than a muted time tick. */
.sched-allday-lbl { font-size: var(--fs-xs); font-weight: 600; color: var(--text); background: color-mix(in srgb, var(--warn) 12%, var(--surface)); }
.sched-today-col { background: color-mix(in srgb, var(--brand) 6%, transparent); }
.sched-today-col.sched-untimed { background: color-mix(in srgb, var(--brand) 8%, color-mix(in srgb, var(--warn) 8%, var(--surface))); }
/* Past days / elapsed slots: closed for scheduling. Hatched + non-interactive so
   it's clearly unavailable, but existing event pills inside stay visible/clickable. */
.sched-cell.sched-past { cursor: default; background-color: var(--surface); background-image: repeating-linear-gradient(45deg, transparent, transparent 5px, color-mix(in srgb, var(--border) 55%, transparent) 5px, color-mix(in srgb, var(--border) 55%, transparent) 6px); }
.sched-cell.sched-past:hover { background-color: var(--surface); box-shadow: none; }
.sched-dayhead.sched-past { background: var(--surface); color: var(--text-muted); }
/* Event pill: tinted with the assignee's colour (--ev-color set inline) so the
   grid carries meaning at a glance instead of reading as uniform grey. */
.sched-ev { display: flex; align-items: center; gap: var(--sp-1); font-size: var(--fs-xs); padding: 3px var(--sp-1); margin-bottom: var(--sp-1); border-left: 3px solid var(--ev-color, var(--brand)); background: color-mix(in srgb, var(--ev-color, var(--brand)) 14%, var(--bg)); color: var(--text); border-radius: var(--radius-sm); cursor: pointer; transition: background .12s; }
.sched-ev:hover { background: color-mix(in srgb, var(--ev-color, var(--brand)) 26%, var(--bg)); }
.sched-ev-dot { width: 7px; height: 7px; min-width: 7px; border-radius: var(--radius-full); }
/* Assignee mini-avatar in the week grid so who owns the slot reads at a glance. */
.sched-ev-av { width: 18px; height: 18px; min-width: 18px; font-size: var(--fs-xs); font-weight: 700; }
.sched-ev-body { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
.sched-ev-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.sched-ev-who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-muted); }
.sched-month { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--sp-1); }
.sched-mhead { text-align: center; font-size: var(--fs-xs); color: var(--text-muted); font-weight: 600; padding: var(--sp-1); }
.sched-mcell { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-1); min-height: 66px; padding: var(--sp-2) var(--sp-1) var(--sp-1); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); cursor: pointer; transition: background .12s, border-color .12s; }
.sched-mcell:hover { border-color: var(--accent); background: var(--accent-light); }
.sched-mday { font-size: var(--fs-sm); font-weight: 600; color: var(--text); }
.sched-mcell.sched-weekend { background: var(--surface); }
.sched-mcell.sched-out { opacity: .4; }
.sched-mcell.sched-has { border-color: color-mix(in srgb, var(--brand) 40%, var(--border)); }
/* Task count chip: brand-filled so populated days pop out of the month. */
.sched-mcount { align-self: flex-end; margin-top: auto; min-width: 18px; height: 18px; padding: 0 var(--sp-1); display: inline-flex; align-items: center; justify-content: center; font-size: var(--fs-xs); font-weight: 700; color: var(--on-color); background: var(--brand); border-radius: var(--radius-full); }
.sched-mcell.sched-today { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 10%, var(--bg)); }
.sched-mcell.sched-today .sched-mday { width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; background: var(--brand); color: var(--on-color); border-radius: var(--radius-full); }

/* Afiș de perete (Tipuri → Siguranță & întreținere) — previzualizarea vector.
   Fundal mereu alb (afișul e un document de tipar, nu urmează tema). */
.poster-prev { border: 1px solid var(--border); border-radius: var(--radius-sm); background: #fff; overflow: auto; max-height: 62vh; }
.poster-prev svg { display: block; width: 100%; height: auto; }
/* Mesaje SSM read-only (fișa activului): punct colorat pe severitate. */
.saf-ro { display: flex; gap: var(--sp-2); align-items: flex-start; padding: var(--sp-1) 0; border-bottom: 1px dashed var(--border); }
.saf-ro:last-child { border-bottom: 0; }
.saf-ro-dot { width: 10px; height: 10px; min-width: 10px; border-radius: var(--radius-full); margin-top: var(--sp-1); }
/* Editorul de mesaje (modalul „Siguranță & întreținere"): listă unică pe
   verticală, grupată pe secțiuni; fiecare rând poartă dunga severității. */
.saf-sec-h { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-2); padding-bottom: var(--sp-1); border-bottom: 2px solid var(--border); }
.saf-item { border: 1px solid var(--border); border-left: 4px solid var(--saf-c, var(--border)); border-radius: var(--radius-sm); background: var(--bg); padding: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-2); }
.saf-pic { display: inline-flex; width: 26px; height: 26px; min-width: 26px; align-items: center; justify-content: center; }
.saf-dot { width: 9px; height: 9px; min-width: 9px; border-radius: var(--radius-full); display: inline-block; }
.saf-prev-row { display: flex; gap: var(--sp-2); align-items: flex-start; padding: var(--sp-1) var(--sp-2); border-left: 3px solid var(--saf-c, var(--border)); margin-bottom: var(--sp-1); }
/* Chip-ul de severitate ACTIV preia culoarea severității rândului (nu roșul
   brand) — chip-ul activ e mereu chiar severitatea curentă (--saf-c). */
.saf-item .chip.active { background: var(--saf-c); border-color: var(--saf-c); color: #fff; }
.saf-item .chip.active .saf-dot { background: #fff !important; }
.saf-item textarea { min-height: 0; }
