/* ============================================================================
   NAVIOS BRIDGE — Precision Console
   ----------------------------------------------------------------------------
   THESIS: A remote-support operations console for technicians, built as an
   instrument, not a landing page. It refuses admin-console density and dashboard
   card-soup: fleet state is scannable in one pass, one action is always obvious.
   OWN-WORLD: cool neutral ground, one cobalt accent, a strict semantic status
   set. Human text in the UI sans; every machine readout (host, id, ip, metric,
   duration, timestamp) in mono — the signature split. No glass, no gradients,
   no hero, no decoration. Depth is a hairline plus an honest offset shadow.
   STORY: the operator lands, scans the fleet, spots what needs attention, opens
   a machine, and connects — in seconds.
   FIRST VIEWPORT: dark left rail · fleet table center · contextual detail right.
   FORM: enterprise operations console, rendered at instrument fidelity.
   ============================================================================ */

/* ---- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html, body { height: 100%; }
body {
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink);
  background: var(--ground);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: none; }
svg { display: block; }
/* The hidden attribute must always win over component display rules (login
   provider toggles, permission-gated nav items, MFA step, detail panel). */
[hidden] { display: none !important; }
::selection { background: color-mix(in srgb, var(--accent) 26%, transparent); }

/* ---- Tokens: LIGHT (default) --------------------------------------------- */
:root {
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Code", "JetBrains Mono", "Roboto Mono", Menlo, Consolas, monospace;

  --ground:   #eef1f5;
  --panel:    #ffffff;
  --sunken:   #f5f7fa;
  --rail:     #0f1522;
  --rail-ink: #c3ccdb;
  --rail-ink-dim: #98a2b4;

  --line:     #e4e8ee;
  --line-2:   #d3dae3;
  --ink:      #141924;
  --muted:    #59636f;
  --faint:    #5b6472;   /* UX-004: darkened to clear 4.5:1 on panel, ground AND
                            the sunken table header — carries the mono readouts */

  --accent:   #2f5bea;
  --accent-press: #2447c4;
  --accent-tint: #eef2fe;
  --on-accent: #ffffff;

  --ok:      #1f9d57;   --ok-tint:   #e7f5ec;
  --live:    #2f5bea;   --live-tint: #eaf0fe;
  --off:     #8b95a3;   --off-tint:  #eef1f5;
  --warn:    #b5701a;   --warn-tint: #fbf1e2;
  --wait:    #6f52d8;   --wait-tint: #efeafb;

  --shadow-1: 0 1px 2px rgba(20,25,36,.08), 0 1px 1px rgba(20,25,36,.04);
  --shadow-2: 0 8px 28px rgba(18,24,40,.12), 0 2px 8px rgba(18,24,40,.06);
  --radius: 9px;
  --radius-sm: 6px;
  --rail-w: 214px;
  --detail-w: 366px;
  --cols: minmax(112px,132px) minmax(150px,1.5fr) minmax(120px,150px) minmax(118px,160px) minmax(78px,104px) 172px;
  color-scheme: light;
}

/* ---- Tokens: DARK (defined, cool graphite — not navy glass) -------------- */
:root[data-theme="dark"] {
  --ground:   #0b0e14;
  --panel:    #141922;
  --sunken:   #0e131b;
  --rail:     #080b11;
  --rail-ink: #b7c0cf;
  --rail-ink-dim: #838ea2;

  --line:     #222a36;
  --line-2:   #2d3745;
  --ink:      #e7ebf2;
  --muted:    #9aa4b2;
  --faint:    #8793a4;   /* ≥4.5:1 on panel — carries the mono readouts */

  /* UX-004: darkened so white text on the accent (primary buttons, incl. the
     login button) clears 4.5:1 — #4f7bff only reached 3.74:1 with #fff. */
  --accent:   #3a67e0;
  --accent-press: #2d55c8;
  --accent-tint: #16203a;
  --on-accent: #ffffff;

  --ok:      #34c47c;   --ok-tint:   #10241a;
  --live:    #4f7bff;   --live-tint: #131f3a;
  --off:     #6b7686;   --off-tint:  #171c25;
  --warn:    #d69134;   --warn-tint: #2a2113;
  --wait:    #9a80f2;   --wait-tint: #1c1731;

  --shadow-1: 0 1px 2px rgba(0,0,0,.4);
  --shadow-2: 0 12px 34px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.35);
  color-scheme: dark;
}

/* honor OS preference until the user picks a theme explicitly */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    --ground:#0b0e14; --panel:#141922; --sunken:#0e131b; --rail:#080b11;
    --rail-ink:#b7c0cf; --rail-ink-dim:#838ea2;
    --line:#222a36; --line-2:#2d3745; --ink:#e7ebf2; --muted:#9aa4b2; --faint:#8793a4;
    --accent:#3a67e0; --accent-press:#2d55c8; --accent-tint:#16203a;
    --ok:#34c47c; --ok-tint:#10241a; --live:#4f7bff; --live-tint:#131f3a;
    --off:#6b7686; --off-tint:#171c25; --warn:#d69134; --warn-tint:#2a2113;
    --wait:#9a80f2; --wait-tint:#1c1731;
    --shadow-1:0 1px 2px rgba(0,0,0,.4);
    --shadow-2:0 12px 34px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.35);
    color-scheme: dark;
  }
}

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* Visually hidden but exposed to assistive tech — used for the session live
   region that announces connect / reconnect / error / expiration / close. */
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---- Screen switching ----------------------------------------------------- */
#consoleScreen { display: none; }
body[data-screen="console"] #consoleScreen { display: grid; }
body[data-screen="session"] #consoleScreen { display: none; }

/* ============================================================================
   APP FRAME
   ============================================================================ */
#consoleScreen {
  height: 100vh;
  grid-template-columns: var(--rail-w) minmax(0, 1fr) var(--detail-w);
  grid-template-areas: "rail work detail";
  overflow: hidden;
}

/* ---- Left rail ------------------------------------------------------------ */
.rail {
  grid-area: rail;
  background: var(--rail);
  color: var(--rail-ink);
  display: flex;
  flex-direction: column;
  padding: 16px 12px;
  gap: 4px;
  border-right: 1px solid rgba(255,255,255,.04);
}
.rail__brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 18px; }
.rail__logo { width: 26px; height: 26px; flex: none; color: #fff; }
.rail__word { display: flex; flex-direction: column; line-height: 1.1; }
.rail__word b { font-size: 13.5px; font-weight: 650; letter-spacing: .02em; color: #fff; }
.rail__word span { font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--rail-ink-dim); }

.rail__label { font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--rail-ink-dim); padding: 12px 10px 6px; }
.navitem {
  display: flex; align-items: center; gap: 11px;
  width: 100%; padding: 9px 10px; border-radius: var(--radius-sm);
  color: var(--rail-ink); font-size: 13px; font-weight: 500;
  transition: background .12s ease, color .12s ease;
}
.navitem svg { width: 17px; height: 17px; flex: none; stroke: currentColor; stroke-width: 1.7; fill: none; opacity: .85; }
.navitem:hover { background: rgba(255,255,255,.05); color: #fff; }
.navitem.is-active { background: rgba(255,255,255,.08); color: #fff; }
.navitem.is-active svg { opacity: 1; color: var(--accent); }
.navitem__count { margin-left: auto; font-family: var(--mono); font-size: 11px;
  color: var(--rail-ink-dim); background: rgba(255,255,255,.06); padding: 1px 7px; border-radius: 20px; }

.rail__spacer { flex: 1; }
.rail__tech {
  display: flex; align-items: center; gap: 10px;
  padding: 10px; border-radius: var(--radius-sm);
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.05);
}
.rail__tech .avatar { width: 30px; height: 30px; border-radius: 8px; flex: none;
  background: var(--accent);
  color: #fff; display: grid; place-items: center; font-size: 12px; font-weight: 650; }
.rail__tech b { color: #fff; font-size: 12.5px; font-weight: 600; }
.rail__tech span { color: var(--rail-ink-dim); font-size: 11px; }

/* ---- Workspace column ----------------------------------------------------- */
/* min-height:0 stops this grid cell from growing to its content height (grid
   items default to min-height:auto); overflow:hidden keeps scrolling inside the
   inner .fleet__scroll. Without this, a tall view (e.g. Proveedores) overflows
   the 100vh frame and gets clipped with no scrollbar. */
.workspace { grid-area: work; display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; background: var(--ground); }

/* Topbar: search · filters · server status · identity */
.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 20px; height: 60px; flex: none;
  background: var(--panel); border-bottom: 1px solid var(--line);
}
.search { position: relative; flex: 1; max-width: 460px; }
.search svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; stroke: var(--faint); stroke-width: 1.8; fill: none; }
.search input {
  width: 100%; height: 36px; padding: 0 12px 0 34px;
  background: var(--sunken); border: 1px solid var(--line);
  border-radius: 8px; font-size: 13px; color: var(--ink);
  transition: border-color .12s, box-shadow .12s, background .12s;
}
.search input::placeholder { color: var(--faint); }
.search input:focus { outline: none; border-color: var(--accent);
  background: var(--panel); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.search kbd { position: absolute; right: 9px; top: 50%; transform: translateY(-50%);
  font-family: var(--mono); font-size: 10.5px; color: var(--faint);
  border: 1px solid var(--line-2); border-radius: 5px; padding: 1px 6px; background: var(--panel); }

.topbar__spacer { flex: 1; }
.topbar__right { display: flex; align-items: center; gap: 10px; }

.server-pill {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 11px; border-radius: 8px;
  background: var(--ok-tint); border: 1px solid color-mix(in srgb, var(--ok) 26%, transparent);
  font-size: 11.5px; color: color-mix(in srgb, var(--ok) 72%, var(--ink));
}
.server-pill b { font-weight: 650; }
.server-pill .beat { width: 7px; height: 7px; border-radius: 50%; background: var(--ok);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 60%, transparent); animation: beat 2.4s ease-out infinite; }
@keyframes beat { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 55%, transparent); }
  60%,100% { box-shadow: 0 0 0 7px transparent; } }

.iconbtn {
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel);
  color: var(--muted); transition: color .12s, border-color .12s, background .12s;
}
.iconbtn svg { width: 17px; height: 17px; stroke: currentColor; stroke-width: 1.7; fill: none; }
.iconbtn:hover { color: var(--ink); border-color: var(--line-2); background: var(--sunken); }

/* ---- Language picker (Task 12) ------------------------------------------- */
.lang-picker-slot:empty { display: none; }
.lang-picker { display: inline-flex; }
.lang-select {
  height: 36px; padding: 0 10px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  font: inherit; font-size: 12.5px; cursor: pointer;
}
.lang-select:hover { color: var(--ink); border-color: var(--line-2); background: var(--sunken); }
.lang-picker-slot--login { display: flex; justify-content: flex-end; margin-bottom: 10px; }

/* ---- Fleet toolbar (filters) --------------------------------------------- */
.fleet { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.fleet__bar { display: flex; align-items: center; gap: 10px; padding: 14px 20px 12px; flex: none; flex-wrap: wrap; }
.fleet__title { font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.fleet__title span { color: var(--faint); font-weight: 500; font-family: var(--mono); font-size: 12px; margin-left: 8px; }
.fleet__filters { display: flex; align-items: center; gap: 6px; margin-left: auto; flex-wrap: wrap; }

.chipf {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 11px; border-radius: 7px;
  border: 1px solid var(--line); background: var(--panel);
  font-size: 12px; color: var(--muted); transition: all .12s;
}
.chipf svg { width: 13px; height: 13px; stroke: currentColor; stroke-width: 1.8; fill: none; }
.chipf:hover { border-color: var(--line-2); color: var(--ink); }
/* UX-004: the active chip's label sits on --accent-tint; raw --accent only made
   4.3:1 there in dark. Blend toward --ink so it lightens on the dark tint and
   darkens on the light tint — ≥4.5:1 in both themes. */
.chipf.is-on { background: var(--accent-tint); border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: color-mix(in srgb, var(--accent) 60%, var(--ink)); }
.chipf .dot { width: 7px; height: 7px; border-radius: 50%; }
/* UX-004: the count digits inherit the chip colour at full opacity; the old
   .8 opacity blended them toward the panel and dropped normal-text contrast
   below 4.5:1. */
.chipf .n { font-family: var(--mono); font-size: 11px; }

/* ---- Fleet table ---------------------------------------------------------- */
.fleet__scroll { flex: 1; min-height: 0; overflow: auto; padding: 0 20px 20px; }
.table {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-1); overflow: hidden;
}
.thead {
  display: grid; grid-template-columns: var(--cols);
  padding: 0 16px; height: 38px; align-items: center;
  border-bottom: 1px solid var(--line); background: var(--sunken);
  position: sticky; top: 0; z-index: 2;
}
.thead span { font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--faint); font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.thead span.r { text-align: right; }

.row {
  display: grid; grid-template-columns: var(--cols);
  padding: 0 16px; min-height: 58px; align-items: center; gap: 10px;
  border-bottom: 1px solid var(--line);
  position: relative; cursor: pointer; text-align: left; width: 100%;
  transition: background .1s ease;
}
.row > span, .thead > span { min-width: 0; }
.thead { gap: 10px; }
.row::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--accent); transform: scaleY(0); transition: transform .14s ease; }
.row:last-child { border-bottom: none; }
.row:hover { background: var(--sunken); }
.row.is-sel { background: var(--accent-tint); }
.row.is-sel::before { transform: scaleY(1); }
.row.is-off { opacity: .62; }

/* Status cell */
.st { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 550; }
.st .stdot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.st svg { width: 14px; height: 14px; flex: none; }
.st--disponible { color: color-mix(in srgb, var(--ok) 74%, var(--ink)); }
.st--disponible .stdot { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-tint); }
.st--en-sesion { color: color-mix(in srgb, var(--live) 78%, var(--ink)); }
.st--en-sesion .stdot { background: var(--live); box-shadow: 0 0 0 3px var(--live-tint); animation: livepulse 1.8s ease-out infinite; }
.st--desconectado { color: var(--muted); }
.st--desconectado .stdot { background: transparent; border: 1.5px solid var(--off); box-shadow: none; }
.st--atencion { color: color-mix(in srgb, var(--warn) 78%, var(--ink)); }
.st--atencion .stdot { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-tint); }
.st--permisos { color: color-mix(in srgb, var(--wait) 76%, var(--ink)); }
.st--permisos .stdot { background: var(--wait); box-shadow: 0 0 0 3px var(--wait-tint); }
@keyframes livepulse { 0% { box-shadow: 0 0 0 2px var(--live-tint); } 70%,100% { box-shadow: 0 0 0 7px transparent; } }

/* Equipo cell */
.eq { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.eq b { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.eq .host { font-family: var(--mono); font-size: 11px; color: var(--faint);
  display: flex; align-items: center; gap: 6px; min-width: 0; }
.eq .host .hostid { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag { font-family: var(--sans); font-size: 9px; letter-spacing: .06em; text-transform: uppercase; font-weight: 700;
  padding: 1px 5px; border-radius: 4px; flex: none; }
/* UX-004: the "live" tag text is <14px, so it needs 4.5:1 — plain --ok on its
   own tint falls short (~3.1:1). Blend toward --ink so it clears the bar in
   both themes (in dark, --ink is light, so the blend stays legible on the dark tint). */
.tag--live { color: color-mix(in srgb, var(--ok) 68%, var(--ink)); background: var(--ok-tint); }
.tag--demo { color: var(--faint); background: var(--sunken); border: 1px solid var(--line); }

/* OS cell */
.os { display: inline-flex; align-items: center; gap: 9px; color: var(--muted); font-size: 12.5px; min-width: 0; }
.os svg { width: 17px; height: 17px; flex: none; }
.os span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Users cell */
.users { display: flex; align-items: center; gap: 8px; min-width: 0; }
.stack { display: flex; flex: none; }
.stack .ava { width: 24px; height: 24px; border-radius: 50%; margin-left: -6px;
  display: grid; place-items: center; font-size: 10px; font-weight: 650; color: #fff;
  border: 2px solid var(--panel); }
.stack .ava:first-child { margin-left: 0; }
.row:hover .stack .ava { border-color: var(--sunken); }
.row.is-sel .stack .ava { border-color: var(--accent-tint); }
.users .ulabel { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Activity cell */
.act { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.act .metric { font-family: var(--mono); font-size: 11px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.st { max-width: 100%; }
.st .stlabel { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sig { display: flex; align-items: flex-end; gap: 2px; height: 13px; }
.sig i { width: 3px; border-radius: 1px; background: var(--line-2); }
.sig i:nth-child(1){height:4px;} .sig i:nth-child(2){height:7px;}
.sig i:nth-child(3){height:10px;} .sig i:nth-child(4){height:13px;}
.sig[data-lvl="1"] i:nth-child(-n+1),
.sig[data-lvl="2"] i:nth-child(-n+2),
.sig[data-lvl="3"] i:nth-child(-n+3),
.sig[data-lvl="4"] i:nth-child(-n+4) { background: var(--ok); }
.act__wait { display: inline-flex; color: var(--wait); }
.act__wait svg { width: 14px; height: 14px; stroke: currentColor; stroke-width: 1.9; fill: none; }

/* Actions cell — the primary Conectar is always visible (an operator's whole job
   is to connect), but stays a quiet outline until the row is hovered/selected,
   so nine rows don't become a wall of blue. */
.rowact { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
.btn--rowconnect { background: var(--panel); border-color: var(--line-2); color: var(--ink); box-shadow: none; }
.row:hover .btn--rowconnect, .row.is-sel .btn--rowconnect,
.row:focus-within .btn--rowconnect { background: var(--accent); border-color: transparent; color: var(--on-accent); }
.btn--split { opacity: 0; transition: opacity .12s; }
.row:hover .btn--split, .row.is-sel .btn--split, .row:focus-within .btn--split { opacity: 1; }

/* ---- Buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 32px; padding: 0 13px; border-radius: 7px; border: 1px solid transparent;
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
  transition: background .12s, border-color .12s, color .12s, box-shadow .12s, transform .06s;
}
.btn:active { transform: translateY(.5px); }
.btn svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 1.9; fill: none; }
.btn--primary { background: var(--accent); color: var(--on-accent); box-shadow: var(--shadow-1); }
.btn--primary:hover { background: var(--accent-press); }
.btn--primary:disabled { opacity: .55; cursor: not-allowed; }
.btn--ghost { background: var(--panel); border-color: var(--line-2); color: var(--ink); }
.btn--ghost:hover { background: var(--sunken); border-color: var(--faint); }
.btn--split { padding: 0 8px; }
.btn--block { width: 100%; height: 40px; font-size: 13.5px; }

/* connecting progress: button morphs into a scan bar */
.btn.is-connecting { position: relative; color: transparent; pointer-events: none; overflow: hidden; }
.btn.is-connecting::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, #fff 45%, transparent), transparent);
  transform: translateX(-100%); animation: scan 1.1s ease-in-out infinite; }
.btn.is-connecting::before { content: "Conectando"; position: absolute; inset: 0;
  display: grid; place-items: center; color: var(--on-accent); font-size: 12px; font-weight: 600; }
@keyframes scan { to { transform: translateX(100%); } }

/* ---- Detail panel --------------------------------------------------------- */
.detail {
  grid-area: detail; background: var(--panel); border-left: 1px solid var(--line);
  display: flex; flex-direction: column; min-height: 0; overflow: hidden;
  box-shadow: var(--shadow-2);
}
.detail__empty { flex: 1; display: grid; place-items: center; padding: 32px; text-align: center; }
.detail__empty svg { width: 46px; height: 46px; stroke: var(--faint); stroke-width: 1.3; fill: none; margin: 0 auto 14px; opacity: .7; }
.detail__empty p { color: var(--muted); font-size: 13px; }
.detail__empty small { color: var(--faint); font-size: 11.5px; display: block; margin-top: 4px; }
.detail__close { display: none; }

.detail__body { flex: 1; overflow: auto; }
.detail.is-updating .detail__body { animation: dslide .22s ease-out; }
@keyframes dslide { from { opacity: .3; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.dhead { padding: 18px 20px 16px; border-bottom: 1px solid var(--line); position: relative; }
.dhead__os { display: inline-flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--muted); margin-bottom: 9px; }
.dhead__os svg { width: 15px; height: 15px; }
.dhead h2 { font-size: 18px; font-weight: 650; letter-spacing: -.01em; }
.dhead .host { font-family: var(--mono); font-size: 12px; color: var(--faint); margin-top: 2px; }
.dhead__status { margin-top: 12px; }

.statuspill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px; border-radius: 8px; font-size: 12.5px; font-weight: 600;
}
.statuspill svg { width: 15px; height: 15px; }
/* T-08: darkened from 76% to 56% --ok so the small pill text clears WCAG AA 4.5:1
   on the light --ok-tint background (Axe color-contrast gate). */
.statuspill--disponible { background: var(--ok-tint); color: color-mix(in srgb, var(--ok) 56%, var(--ink)); }
.statuspill--en-sesion { background: var(--live-tint); color: color-mix(in srgb, var(--live) 80%, var(--ink)); }
.statuspill--desconectado { background: var(--off-tint); color: var(--muted); }
.statuspill--atencion { background: var(--warn-tint); color: color-mix(in srgb, var(--warn) 80%, var(--ink)); }
.statuspill--permisos { background: var(--wait-tint); color: color-mix(in srgb, var(--wait) 78%, var(--ink)); }
.dhead__note { margin-top: 10px; padding: 9px 11px; border-radius: 7px;
  background: var(--warn-tint); color: color-mix(in srgb, var(--warn) 80%, var(--ink));
  font-size: 12px; display: flex; gap: 8px; align-items: flex-start; }
.dhead__note svg { width: 15px; height: 15px; flex: none; margin-top: 1px; stroke: currentColor; stroke-width: 1.9; fill: none; }

/* metric grid */
.dmetrics { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line);
  border-bottom: 1px solid var(--line); }
.dmetric { background: var(--panel); padding: 11px 20px; }
.dmetric label { display: block; font-size: 10px; letter-spacing: .07em; text-transform: uppercase; color: var(--faint); margin-bottom: 3px; }
.dmetric b { font-family: var(--mono); font-size: 13px; font-weight: 600; color: var(--ink); }

/* section */
.dsec { padding: 16px 20px; border-bottom: 1px solid var(--line); }
.dsec__h { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.dsec__h h3 { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 650; }
.dsec__h .count { font-family: var(--mono); font-size: 11px; color: var(--faint); }

/* users list */
.urow { display: flex; align-items: center; gap: 11px; padding: 8px 0; }
.urow .ava { width: 32px; height: 32px; border-radius: 9px; flex: none; display: grid; place-items: center;
  font-size: 12px; font-weight: 650; color: #fff; }
.urow__body { min-width: 0; flex: 1; }
.urow__body b { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 7px; }
.urow__body .login { font-family: var(--mono); font-size: 11px; color: var(--faint); }
.rolebadge { font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase; font-weight: 650;
  padding: 1px 6px; border-radius: 4px; }
.rolebadge--admin { background: var(--wait-tint); color: color-mix(in srgb, var(--wait) 80%, var(--ink)); }
.rolebadge--active { background: var(--ok-tint); color: color-mix(in srgb, var(--ok) 76%, var(--ink)); }
.urow .btn { height: 28px; padding: 0 10px; font-size: 11.5px; }

/* actions block */
.dactions { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.dactions .btn--block { grid-column: 1 / -1; }
/* Connection-quality picker (shown above the Connect button): full width, label on top. */
.dactions .dquality { grid-column: 1 / -1; flex-direction: column; align-items: stretch; gap: 5px; }
.dactions .dquality > span { font-size: 11px; color: var(--faint); }
.dactions .dquality select { width: 100%; }

/* history */
.hrow { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center;
  padding: 9px 0; border-top: 1px solid var(--line); }
.hrow:first-of-type { border-top: none; }
.hrow__tech { display: flex; align-items: center; gap: 8px; }
.hrow__tech .ava { width: 24px; height: 24px; border-radius: 7px; font-size: 10px; display: grid; place-items: center; color: #fff; font-weight: 650; flex: none; }
.hrow__mid { min-width: 0; }
.hrow__mid b { font-size: 12.5px; font-weight: 550; }
.hrow__mid span { display: block; font-family: var(--mono); font-size: 10.5px; color: var(--faint); }
.result { font-size: 10.5px; font-weight: 650; padding: 2px 8px; border-radius: 5px; white-space: nowrap; }
.result--ok { background: var(--ok-tint); color: color-mix(in srgb, var(--ok) 76%, var(--ink)); }
.result--esc { background: var(--warn-tint); color: color-mix(in srgb, var(--warn) 80%, var(--ink)); }
.result--none { background: var(--off-tint); color: var(--muted); }

/* ---- Audit drawer (visible, unobtrusive) --------------------------------- */
.audit { flex: none; background: var(--panel); border-top: 1px solid var(--line); }
.audit__bar { display: flex; align-items: center; gap: 10px; padding: 9px 20px; cursor: pointer; user-select: none; width: 100%; text-align: left; }
.audit__bar h3 { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 650; flex: none; }
.audit__bar .live { display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; color: var(--faint); flex: none; }
.audit__bar .live i { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); animation: beat 2.4s infinite; }
.audit__latest { flex: 1; font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.audit__latest .mono { color: var(--faint); }
.audit__chev { color: var(--faint); transition: transform .18s; flex: none; }
.audit__chev svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 1.8; fill: none; }
.audit.is-open .audit__chev { transform: rotate(180deg); }
.audit__feed { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .26s ease; }
.audit.is-open .audit__feed { grid-template-rows: 1fr; }
.audit__inner { overflow: hidden; min-height: 0; }
.audit.is-open .audit__inner { overflow: auto; max-height: 216px; }
.arow { display: grid; grid-template-columns: 62px 18px 1fr auto; gap: 10px; align-items: center;
  padding: 7px 20px; border-top: 1px solid var(--line); font-size: 12px; }
.arow time { font-family: var(--mono); font-size: 11px; color: var(--faint); }
.arow .aicon svg { width: 16px; height: 16px; stroke-width: 1.7; fill: none; stroke: currentColor; }
.arow .adesc { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.arow .adesc b { font-weight: 600; }
.arow .adesc .mono { color: var(--muted); }
.arow .ahost { font-family: var(--mono); font-size: 10.5px; color: var(--faint); white-space: nowrap; }
.arow--crit .aicon { color: var(--warn); }
.arow--ok .aicon { color: var(--ok); }
.arow--info .aicon { color: var(--accent); }

/* ---- Skeleton loading ----------------------------------------------------- */
.skrow { display: grid; grid-template-columns: var(--cols); padding: 0 16px; height: 58px; align-items: center;
  border-bottom: 1px solid var(--line); position: relative; overflow: hidden; }
.sk { height: 12px; border-radius: 6px; background: var(--sunken); }
.skrow::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--accent) 8%, transparent), transparent);
  transform: translateX(-100%); animation: scan 1.4s ease-in-out infinite; }

/* ---- Empty fleet ---------------------------------------------------------- */
.fleet__empty { padding: 60px 20px; text-align: center; color: var(--muted); max-width: 520px; margin: 0 auto; }
.fleet__empty svg { width: 42px; height: 42px; stroke: var(--faint); stroke-width: 1.3; fill: none; margin: 0 auto 12px; opacity: .7; }
.fleet__empty p { line-height: 1.55; }

/* ---- History table -------------------------------------------------------- */
:root { --hcols: minmax(160px,1.5fr) minmax(130px,1fr) 140px 110px 120px; }
.thead--hist { grid-template-columns: var(--hcols); }
.row--hist { grid-template-columns: var(--hcols); cursor: default; min-height: 52px; }
.row--hist::before { display: none; }
.row--hist:hover { background: var(--sunken); }
.hcell { display: flex; align-items: center; gap: 8px; min-width: 0; }
.hcell .mono { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.result--live { background: var(--live-tint); color: color-mix(in srgb, var(--live) 80%, var(--ink)); }
@media (max-width: 780px) {
  :root { --hcols: minmax(150px,1.5fr) minmax(110px,1fr) 118px; }
  .thead--hist span:nth-child(3), .row--hist > *:nth-child(3),
  .thead--hist span:nth-child(4), .row--hist > *:nth-child(4) { display: none; }
}

/* ---- Settings ------------------------------------------------------------- */
.settings { max-width: 640px; display: flex; flex-direction: column; gap: 14px; }
.scard { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-1); padding: 4px 18px; }
.scard h3 { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 650; padding: 14px 0 6px; }
.srow { display: flex; align-items: center; gap: 14px; padding: 12px 0; border-top: 1px solid var(--line); flex-wrap: wrap; }
.srow > label { font-size: 13px; color: var(--ink); font-weight: 500; margin-right: auto; }
.shint { font-size: 12px; color: var(--muted); padding: 0 0 12px; line-height: 1.5; }
.sinput { height: 34px; padding: 0 11px; min-width: 220px; background: var(--sunken); border: 1px solid var(--line);
  border-radius: 7px; color: var(--ink); font-size: 13px; }
.sinput:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); background: var(--panel); }
.seg { display: inline-flex; background: var(--sunken); border: 1px solid var(--line); border-radius: 8px; padding: 3px; gap: 2px; }
.seg button { padding: 5px 12px; border-radius: 6px; font-size: 12.5px; color: var(--muted); font-weight: 500; }
.seg button.is-on { background: var(--panel); color: var(--ink); box-shadow: var(--shadow-1); }
.switch { width: 42px; height: 24px; border-radius: 20px; background: var(--line-2); position: relative; transition: background .16s; flex: none; }
.switch span { position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.25); transition: transform .16s; }
.switch.is-on { background: var(--accent); }
.switch.is-on span { transform: translateX(18px); }
.ldapadv { border-top: 1px solid var(--line); margin-top: 4px; }
.ldapadv summary { cursor: pointer; font-size: 12px; color: var(--muted); padding: 10px 0 4px; user-select: none; }
.ldapadv summary:hover { color: var(--ink); }
.seg button, .srow > select.sinput { max-width: 100%; }

/* ============================================================================
   MENU (Conectar como)
   ============================================================================ */
.menu {
  position: fixed; z-index: 60; min-width: 218px;
  background: var(--panel); border: 1px solid var(--line-2); border-radius: 9px;
  box-shadow: var(--shadow-2); padding: 6px; animation: dslide .14s ease-out;
}
.menu__label { font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); padding: 6px 8px 4px; }
.menu button { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px; border-radius: 6px;
  font-size: 12.5px; text-align: left; color: var(--ink); }
.menu button:hover { background: var(--sunken); }
.menu button .ava { width: 26px; height: 26px; border-radius: 7px; font-size: 10px; display: grid; place-items: center; color: #fff; font-weight: 650; flex: none; }
.menu button .m-ic { width: 26px; height: 26px; display: grid; place-items: center; flex: none; }
.menu button svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 1.8; fill: none; color: var(--muted); }
.menu button .mrole { margin-left: auto; }
.menu__sep { height: 1px; background: var(--line); margin: 5px 2px; }

/* ============================================================================
   SESSION VIEW  (chrome recedes; canvas leads — functional IDs preserved)
   ============================================================================ */
.session { display: none; }
body[data-screen="session"] .session { display: grid; grid-template-rows: auto 1fr; height: 100vh; background: #0a0d12; }

.toolbar {
  display: flex; align-items: center; gap: 14px; padding: 8px 14px; height: 52px;
  background: #0f141c; border-bottom: 1px solid #1c2430; color: #cdd5e1;
  /* UX-012 root fix: the toolbar is a GRID ITEM of .session; a grid item defaults
     to min-width:auto (= min-content), so it grows past the viewport and its flex
     children never shrink. min-width:0 lets it size to the track, so the identity
     group actually collapses and the Finalizar action stays in the viewport.
     (NOT overflow:hidden here — the stats/Más dropdowns must escape the 52px bar.) */
  min-width: 0;
}
.toolbar__group { display: flex; align-items: center; gap: 9px; }
/* UX-012: the identity group is the ONLY one allowed to shrink/truncate, at EVERY
   width, so the Finalizar action (in the fixed right group) is never pushed off the
   viewport. min-width:0 defeats the flex/grid min-content floor; overflow:hidden
   clips the truncated identity cleanly. */
.toolbar > .toolbar__group:first-child { min-width: 0; overflow: hidden; }
.toolbar > .toolbar__group:first-child > * { min-width: 0; }
.toolbar__center { margin: 0 auto; flex: 0 0 auto; }
.toolbar__right { margin-left: auto; flex: 0 0 auto; }
.toolbar__brand { font-weight: 650; font-size: 13px; letter-spacing: .01em; color: #fff; display: flex; align-items: center; gap: 8px; }
.toolbar__brand::before { content: ""; width: 8px; height: 8px; border-radius: 2px; background: var(--accent); }
.chip { font-family: var(--mono); font-size: 11.5px; color: #9aa6b6; padding: 3px 9px; border-radius: 6px; background: #141b25; border: 1px solid #212a37; }
.chip--state { display: inline-flex; align-items: center; gap: 6px; color: #34c47c; }
.chip--state i { width: 7px; height: 7px; border-radius: 50%; background: #34c47c; box-shadow: 0 0 0 3px rgba(52,196,124,.16); }
.chip--state.is-down { color: #d67a7a; }
.chip--state.is-down i { background: #d67a7a; box-shadow: 0 0 0 3px rgba(214,122,122,.16); }
.chip--state.is-warn { color: #e6b366; }
.chip--state.is-warn i { background: #e6b366; box-shadow: 0 0 0 3px rgba(230,179,102,.18); }
/* P-05: capture-source badge. Neutral for a real backend; loud red for synthetic. */
.chip--capture { color: #9aa6b6; }
.chip--e2ee { color: #34c47c; border-color: rgba(52,196,124,.4); background: rgba(52,196,124,.12); font-weight: 600; letter-spacing: .1px; }
.chip--e2ee svg { flex: none; }
.chip--capture-synthetic { color: #fff; background: #b3261e; border-color: #7a1811; font-weight: 700; letter-spacing: .2px; }

.select { display: flex; align-items: center; gap: 7px; font-size: 11px; color: #7f8b9c; }
.select select { height: 32px; padding: 0 26px 0 10px; background: #141b25 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%237f8b9c' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 8px center;
  border: 1px solid #212a37; border-radius: 7px; color: #dce3ec; font-size: 12px; -webkit-appearance: none; appearance: none; }
.select select:focus { outline: none; border-color: var(--accent); }

.tbtn {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 11px;
  border: 1px solid #212a37; border-radius: 7px; background: #141b25; color: #b9c2cf; font-size: 12px; font-weight: 500;
  transition: background .12s, border-color .12s, color .12s;
}
.tbtn .ic { width: 16px; height: 16px; stroke: currentColor; stroke-width: 1.8; fill: none; }
.tbtn:hover { background: #1a2230; border-color: #2c3746; color: #fff; }
.tbtn--warn { color: #e0a54c; } .tbtn--warn:hover { border-color: color-mix(in srgb, var(--warn) 50%, #2c3746); }
.tbtn--danger { color: #e08585; } .tbtn--danger:hover { border-color: #5a2b2b; background: #241318; }
.tbtn[hidden] { display: none; }

/* Visual monitor picker (monitorPickerDialog): the remote displays drawn to scale
   in their real relative positions — clearer than any competitor's numeric list. */
.monmap { position: relative; margin: 14px auto 8px; background: #0e141d;
  border: 1px solid #263043; border-radius: 8px; }
.monmap__mon { position: absolute; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 3px; padding: 2px;
  background: #1a2331; border: 2px solid #37455e; border-radius: 5px; color: #c4d0e8;
  cursor: pointer; overflow: hidden; transition: background .12s, border-color .12s, transform .12s; }
.monmap__mon:hover { background: #223047; border-color: var(--accent); transform: translateY(-1px); }
.monmap__mon.is-active { border-color: var(--accent); background: #1c2b45;
  box-shadow: 0 0 0 2px rgba(59,130,246,.35); }
.monmap__mon:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.monmap__name { font-size: 11px; font-weight: 600; line-height: 1.1;
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.monmap__res { font-size: 10px; color: #8493ab; white-space: nowrap; }

.stage { position: relative; display: grid; place-items: center; overflow: hidden;
  background: #080a0e; background-image: repeating-linear-gradient(45deg, #0a0d12 0 12px, #090c11 12px 24px); }
.screen { max-width: 100%; max-height: 100%; cursor: default; background: #000;
  border-radius: 2px; box-shadow: 0 10px 50px rgba(0,0,0,.5); }
.screen:not(.is-live) { display: none; }

/* Fullscreen (operator comfort): reclaim the ENTIRE screen for the remote desktop.
   The 52px toolbar leaves the grid (so the stage gets full height) and returns only
   as a translucent auto-hiding overlay when the pointer nears the top edge — the
   video-player pattern. Canvas insets (radius/shadow) and the diagonal backdrop are
   dropped so the image fills as completely as possible. Driven by _onFullscreenChange. */
.session.is-fs { position: relative; }
/* The stage must take the WHOLE height in fullscreen: one 1fr row, so the canvas fills to
   the bottom edge. This selector MUST out-specify the base `body[data-screen="session"]
   .session { grid-template-rows: auto 1fr }` (0,2,1) — a plain `.session.is-fs` (0,2,0)
   loses to it, leaving the stage in the `auto` row and an empty `1fr` row as a black bar at
   the bottom. Matching the base's `body[data-screen]` prefix makes this (0,3,1) so it wins. */
body[data-screen="session"] .session.is-fs { grid-template-rows: 1fr; }
.session.is-fs .stage { background: #000; }
/* Fullscreen fills edge-to-edge: _fitCanvas sets the canvas to the full stage size, so drop
   the docked `max-*: 100%` cap (and the card insets) to guarantee a pixel-exact fill. */
.session.is-fs .screen { border-radius: 0; box-shadow: none; max-width: none; max-height: none; }
.session.is-fs .toolbar {
  position: absolute; top: 0; left: 0; right: 0; z-index: 40; height: 48px;
  border-bottom: 1px solid rgba(28, 36, 48, .6);
  background: rgba(15, 20, 28, .92); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  transform: translateY(-100%); opacity: 0;
  transition: transform .18s ease, opacity .18s ease;
}
.session.is-fs.fs-bar .toolbar { transform: translateY(0); opacity: 1; }
/* The stats now live in a toolbar menu, so fullscreen hides them with the toolbar
   itself; close the popover on the way into fullscreen so it can't linger over the
   picture. */
.session.is-fs .statsmenu { display: none; }

.stage__idle { position: absolute; inset: 0; display: grid; place-items: center; align-content: center; gap: 16px; color: #8894a6; }
.stage__idle.is-hidden { display: none; }
.stage__idle p { font-size: 13px; }
.loader { width: 40px; height: 40px; border-radius: 50%; border: 3px solid #1e2735; border-top-color: var(--accent); animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Top session-stats menu: a compact button (with a glanceable fps teaser) that
   opens a small readout of resolution / framerate / connection speed / codec. */
.statswrap { position: relative; display: flex; }
.tbtn--stats { gap: 6px; }
.stats-teaser { font-family: var(--mono); font-size: 11px; font-weight: 700; color: #aeb9c9;
  min-width: 12px; text-align: right; letter-spacing: .01em; }
.statsmenu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 30; min-width: 208px;
  padding: 8px; border-radius: 10px; background: #10151d; border: 1px solid #232d3b;
  box-shadow: 0 12px 32px rgba(0,0,0,.5); }
.statsmenu[hidden] { display: none; }
.statsmenu__title { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
  padding: 2px 6px 8px; }
.statsrow { display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 5px 6px; border-radius: 6px; }
.statsrow + .statsrow { border-top: 1px solid #1a2230; }
.statsrow__k { font-size: 12px; color: #8894a6; }
.statsrow__v { font-family: var(--mono); font-size: 12.5px; font-weight: 700; color: #dce3ec;
  font-variant-numeric: tabular-nums; }
.statsrow__u { font-weight: 500; color: #8894a6; }
/* Session chrome is always dark, independent of the app theme, so pin a light
   accent here (≥4.5:1 on the dark surface) rather than the theme --accent token. */
.hud__codec { color: #7d9bff; font-weight: 700; letter-spacing: .04em; }

/* ============================================================================
   LOGIN
   ============================================================================ */
.loginpage { display: grid; place-items: center; min-height: 100vh; background: var(--ground);
  background-image: radial-gradient(1100px 700px at 50% -10%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 60%); }
.login { width: 100%; max-width: 400px; padding: 24px; }
.login__card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow-2); padding: 28px; }
.login__brand { display: flex; align-items: center; gap: 11px; color: var(--ink); margin-bottom: 22px; }
.login__brand b { display: block; font-size: 15px; font-weight: 650; }
.login__brand span { font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--faint); }
.login__form h1 { font-size: 19px; font-weight: 650; margin-bottom: 18px; letter-spacing: -.01em; }
.login__hint { font-size: 12.5px; color: var(--muted); margin-bottom: 16px; }
.login__providers { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.login__sso { justify-content: center; gap: 9px; height: 42px; }
.login__sso svg { width: 18px; height: 18px; }
.login__sep { text-align: center; position: relative; margin: 6px 0 16px; }
.login__sep::before { content: ""; position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: var(--line); }
.login__sep span { position: relative; background: var(--panel); padding: 0 10px; font-size: 11.5px; color: var(--faint); }
.lfield { display: block; margin-bottom: 13px; }
.lfield span { display: block; font-size: 12px; color: var(--muted); margin-bottom: 5px; font-weight: 500; }
.lfield input { width: 100%; height: 40px; padding: 0 12px; background: var(--sunken); border: 1px solid var(--line);
  border-radius: 8px; font-size: 13.5px; color: var(--ink); }
.lfield input:focus { outline: none; border-color: var(--accent); background: var(--panel); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.lcheck { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted); margin-bottom: 16px; cursor: pointer; }
.login__err { margin-top: 12px; padding: 9px 11px; border-radius: 7px; font-size: 12.5px;
  background: color-mix(in srgb, #e0524f 12%, transparent); color: #c0403d; }
:root[data-theme="dark"] .login__err { color: #f19a98; }
.login__foot { margin-top: 20px; text-align: center; font-size: 11.5px; color: var(--faint); }
.login .btn--block { height: 42px; margin-top: 6px; }

/* ============================================================================
   RAIL identity + logout
   ============================================================================ */
.rail__techmeta { min-width: 0; flex: 1; }
.rail__techmeta b { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#techRole { color: var(--rail-ink-dim); font-size: 11px; }
.rail__logout { width: 30px; height: 30px; border-radius: 7px; display: grid; place-items: center; flex: none;
  color: var(--rail-ink-dim); }
.rail__logout:hover { background: rgba(255,255,255,.08); color: #fff; }
.rail__logout svg { width: 17px; height: 17px; }

/* ============================================================================
   ADMIN: users / groups / server audit
   ============================================================================ */
.uform { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 8px 0 14px; }
.uform .sinput { flex: 1; min-width: 130px; }
.sinput--sm { height: 30px; min-width: 120px; flex: none; font-size: 12px; }
.gchks { display: flex; flex-wrap: wrap; gap: 10px; width: 100%; padding: 4px 0; }
.gchk { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.urow--admin { display: grid; grid-template-columns: 34px minmax(120px,1fr) 130px auto; gap: 10px;
  align-items: center; padding: 10px 0; border-top: 1px solid var(--line); }
.urow--admin:first-of-type { border-top: none; }
.urow--admin .btn { height: 30px; padding: 0 10px; font-size: 12px; }
.urow__actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.ugroups { grid-column: 1 / -1; padding: 8px 0 4px; display: flex; flex-direction: column; gap: 8px; }
.thead--audit, .row--audit { grid-template-columns: 130px minmax(120px,1.1fr) minmax(120px,1fr) minmax(110px,1fr) 110px 90px; }
.row--audit { cursor: default; min-height: 44px; }
.row--audit::before { display: none; }
.row--audit:hover { background: var(--sunken); }
@media (max-width: 900px) {
  .urow--admin { grid-template-columns: 34px 1fr; }
  .urow--admin [data-role], .urow--admin .urow__actions { grid-column: 1 / -1; justify-self: start; }
  .thead--audit span:nth-child(4), .row--audit > *:nth-child(4),
  .thead--audit span:nth-child(5), .row--audit > *:nth-child(5) { display: none; }
  .thead--audit, .row--audit { grid-template-columns: 120px 1fr 1fr 90px; }
}

/* ============================================================================
   TOASTS
   ============================================================================ */
.toasts { position: fixed; right: 18px; bottom: 18px; z-index: 80; display: flex; flex-direction: column; gap: 10px; }
.toast { display: flex; gap: 11px; align-items: flex-start; min-width: 260px; max-width: 360px;
  padding: 12px 14px; border-radius: 10px; background: var(--panel); border: 1px solid var(--line);
  box-shadow: var(--shadow-2); animation: toastin .3s cubic-bezier(.2,.9,.3,1); }
.toast__dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 5px; flex: none; background: var(--accent); }
.toast--ok .toast__dot { background: var(--ok); } .toast--warn .toast__dot { background: var(--warn); }
.toast--err .toast__dot { background: #e0524f; }
.toast b { font-size: 13px; font-weight: 600; display: block; }
.toast small { font-size: 12px; color: var(--muted); display: block; margin-top: 1px; }
.toast-action { margin-top: 6px; align-self: flex-start; font-size: 12px; font-weight: 600;
  color: var(--muted); background: transparent; border: 1px solid var(--border); border-radius: 6px;
  padding: 3px 9px; cursor: pointer; }
.toast-action:hover { color: var(--text); border-color: #e0524f; }
.toast-action:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.toast.is-out { animation: toastout .25s ease forwards; }
@keyframes toastin { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes toastout { to { opacity: 0; transform: translateX(12px); } }

/* ============================================================================
   FOCUS · RESPONSIVE · MOTION
   ============================================================================ */
/* UX-004: a solid 2px accent outline (≥3:1 against every surface it lands on,
   incl. the dark rail and the sunken inputs) plus a soft accent halo. Using
   `outline` keeps the ring visible under Windows High-Contrast / forced-colors,
   where box-shadow is dropped. */
:where(button, a, input, select, [tabindex]):focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 30%, transparent); border-radius: 6px;
}
.row:focus-visible { z-index: 1; }
.screen:focus-visible { box-shadow: 0 0 0 3px var(--accent), 0 10px 50px rgba(0,0,0,.5); }

/* Below 1240px the detail panel stops reserving a column and overlays instead,
   so the fleet table always keeps room for its required columns + actions. */
@media (max-width: 1240px) {
  #consoleScreen { grid-template-columns: var(--rail-w) minmax(0,1fr); grid-template-areas: "rail work"; }
  :root { --rail-w: 68px;
    --cols: minmax(108px,124px) minmax(150px,1.5fr) minmax(120px,150px) minmax(120px,160px) minmax(78px,110px) 176px; }
  .rail__word, .rail__label, .rail__tech b, .rail__tech span { display: none; }
  .navitem { justify-content: center; padding: 10px; }
  .navitem span:not(.navitem__count) { display: none; }
  .navitem__count { display: none; }
  .rail__tech { justify-content: center; padding: 8px; }
  /* UX-001: the panel leaves the grid (grid-area reset) and becomes a modal
     drawer, anchored inside the safe area, capped in width, with its own scroll,
     a persistent close button and a scrim behind it. Fully visible + closable at
     1024/768/390px with no horizontal document overflow. */
  .detail {
    position: fixed; grid-area: auto;
    top: env(safe-area-inset-top, 0px); bottom: env(safe-area-inset-bottom, 0px);
    right: env(safe-area-inset-right, 0px); left: auto;
    width: min(392px, 94vw); max-width: 100vw; z-index: 60;
    transform: translateX(100%); transition: transform .24s ease;
  }
  body.detail-open .detail { transform: none; }
  .scrim { position: fixed; inset: 0; z-index: 55; background: rgba(8, 11, 17, .5); }
  @media (prefers-reduced-motion: no-preference) { .scrim { animation: fadein .18s ease-out; } }
  .detail__close { display: grid; place-items: center; position: absolute; top: 14px; right: 16px;
    width: 32px; height: 32px; border-radius: 7px; color: var(--ink); border: 1px solid var(--line-2); background: var(--panel); z-index: 1; }
  .detail__close:hover { background: var(--sunken); }
  .detail__close svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 1.9; fill: none; }
}
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
/* Above the overlay breakpoint the scrim never shows (panel is a grid column). */
.scrim { display: none; }
@media (max-width: 1240px) { body.detail-open .scrim { display: block; } }
@media (max-width: 1024px) {
  /* Drop Actividad first — Estado/Equipo/SO/Usuarios/Acciones stay (5 columns). */
  :root { --cols: minmax(104px,124px) minmax(130px,1.4fr) minmax(112px,150px) minmax(110px,160px) 172px; }
  .thead span:nth-child(5), .row > .act { display: none; }
}
@media (max-width: 760px) {
  /* Then drop SO — Estado/Equipo/Usuarios/Acciones stay (4 columns). */
  :root { --cols: 108px minmax(120px,1fr) minmax(88px,132px) 148px; }
  .thead span:nth-child(3), .row > .os { display: none; }
  .search kbd { display: none; }
  .fleet__filters { display: none; }
}
@media (max-width: 560px) {
  /* Phone: keep only Estado + Equipo + the primary action (3 columns);
     Usuarios/history live in the detail panel a tap away. Acciones never clips. */
  :root { --cols: 96px minmax(0,1fr) 132px; }
  .thead span:nth-child(4), .row > .users { display: none; }
  /* UX-005: the machine alias must be shown IN FULL at phone widths — never
     truncated to an ambiguous ellipsis. Let it wrap (breaking a long single token
     if needed) instead of clipping, so the technician always identifies the machine. */
  .eq b { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; line-height: 1.25; }
  .toolbar__center { display: none; }
  /* UX-002: secondary actions collapse to icons, but identity/status/Finalizar
     stay legible — Finalizar keeps its label at every width down to 390px. */
  .tbtn span { display: none; }
  .tbtn--keeplabel span { display: inline; }
  .toolbar__brand { display: none; }
  .fleet__scroll { padding: 0 12px 16px; }
  .fleet__bar { padding: 12px 12px 10px; }
  /* FUNC-003 entry keeps its icon; the label folds away on the narrowest widths. */
  #codeConnectBtn .codebtn__label { display: none; }
  /* UX-002 @390px: the identity group yields space (truncates) while the primary
     action group stays FIXED, so "Finalizar" is never pushed off the right edge —
     it clipped at ~0.94 visible before this because the left group would not shrink. */
  .toolbar { gap: 8px; padding: 8px 10px; }
  .toolbar > .toolbar__group:first-child { flex: 1 1 auto; min-width: 0; overflow: hidden; }
  .toolbar__right { flex: 0 0 auto; }
}
/* UX-002: Finalizar always keeps its label so the primary safety action is never
   an unlabeled icon, even where other toolbar buttons compact to icons. */
.tbtn--keeplabel span { display: inline; }
.tbtn--danger.tbtn--keeplabel { color: #ef9a9a; }
/* Higher-contrast readouts on the dark session chrome (UX-004 contrast). */
.chip { color: #c2cbd8; }
.select { color: #9aa6b6; }
.hud { color: #aab4c4; }
/* UX-002: keep monitor/quality compact so identity+status+Finalizar always fit. */
.toolbar .select select { max-width: 176px; }
@media (max-width: 900px) {
  .toolbar .select > span { display: none; }        /* drop the label, keep the control */
  .toolbar .select select { max-width: 132px; }
}

/* UX-012: guarantee the Finalizar (disconnect) action is 100% inside the viewport
   at tablet widths too (≤820, e.g. 768px). The identity group yields space — the
   brand text and the E2EE badge LABEL fold away (the green lock icon + its
   role=status/title remain), and the group shrinks/truncates — while the center
   and right (Finalizar) groups stay fixed, so #disconnectBtn is never pushed off
   the right edge. Verified by tests/e2e/viewport-a11y.spec.js (toBeInViewport). */
@media (max-width: 820px) {
  .toolbar { gap: 8px; padding: 8px 10px; }
  .toolbar__brand { display: none; }
  #e2eeBadge > span { display: none; }               /* keep the lock icon, drop the label */
  /* The F2 request-control button drops its label like every other secondary
     button at narrow widths (it is not the primary safety action). */
  #requestControlBtn span { display: none; }
}

@media (pointer: coarse) {
  /* WCAG 2.5.5 / UX-012: comfortable touch targets on coarse pointers. */
  .tbtn, .iconbtn, .chipf, .navitem, .btn { min-height: 44px; }
  .toolbar .tbtn { min-width: 44px; justify-content: center; }
  .row .rowact { opacity: 1; }
}

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

/* ============================================================================
   SESSION STATE MACHINE OVERLAY (UX-003)
   The waiting overlay renders a phase: label + elapsed time + message + the
   phase's recovery actions. No indefinite spinner — every phase shows progress
   and, on loss/failure, a persistent, actionable panel.
   ============================================================================ */
.phase { display: grid; justify-items: center; gap: 14px; max-width: 460px; padding: 24px; text-align: center; }
.phase__label { font-size: 15px; font-weight: 600; color: #e6ecf5; line-height: 1.4; }
.phase__meta { font-size: 12px; color: #8894a6; }
.phase__meta [data-elapsed] { color: #b9c6d8; }
.phase__msg { font-size: 13px; color: #aeb9c9; line-height: 1.5; max-width: 42ch; }
.phase__actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }
.phase__actions .btn { height: 38px; }
.phase__icon { display: grid; place-items: center; width: 46px; height: 46px; color: var(--warn); }
.phase__icon svg { width: 40px; height: 40px; stroke: currentColor; stroke-width: 1.7; fill: none; }
.phase__icon--ok { color: var(--ok); }
.phase--terminal .phase__label { color: #fff; }

/* ============================================================================
   ACCESSIBLE DIALOGS (a11y.js) — replace native prompt/alert/confirm
   ============================================================================ */
.ovl {
  position: fixed; inset: 0; z-index: 90; display: grid; place-items: center;
  padding: 20px; background: rgba(8, 11, 17, .55);
}
@media (prefers-reduced-motion: no-preference) { .ovl { animation: fadein .16s ease-out; } }
.dlg {
  width: 100%; max-width: 440px; max-height: calc(100vh - 40px); overflow: auto;
  background: var(--panel); border: 1px solid var(--line-2); border-radius: 14px;
  box-shadow: var(--shadow-2); padding: 22px 22px 18px;
  padding-bottom: max(18px, env(safe-area-inset-bottom, 0px));
}
@media (prefers-reduced-motion: no-preference) { .dlg { animation: dlgin .18s cubic-bezier(.2,.9,.3,1); } }
@keyframes dlgin { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
.dlg__title { font-size: 16px; font-weight: 650; letter-spacing: -.01em; color: var(--ink); }
.dlg__body { font-size: 13px; color: var(--muted); line-height: 1.55; margin-top: 8px; }
.dlg__pre {
  font-family: var(--mono); font-size: 13px; color: var(--ink); letter-spacing: .04em;
  background: var(--sunken); border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 14px; margin-top: 12px; white-space: pre-wrap; word-break: break-word;
}
.dlg__actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 18px; flex-wrap: wrap; }
.dlg__actions .btn { height: 38px; }
.btn--danger-solid { background: #d64545; color: #fff; box-shadow: var(--shadow-1); }
/* UX-009: glossary help dialog. */
.dlg--glossary { max-width: 460px; }
.dlg--glossary .glossary { margin: 12px 0 0; max-height: 60vh; overflow-y: auto; }
.dlg--glossary .glossary dt { font-weight: 700; font-size: 13px; color: var(--ink); margin-top: 12px; }
.dlg--glossary .glossary dt:first-child { margin-top: 0; }
.dlg--glossary .glossary dd { margin: 3px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
abbr.gloss { text-decoration: underline dotted; text-underline-offset: 2px; cursor: help; }
.btn--danger-solid:hover { background: #c23a3a; }
:root[data-theme="dark"] .btn--danger-solid { background: #e05656; }

.field { display: block; margin-top: 14px; }
.field__label { display: block; font-size: 12px; color: var(--muted); font-weight: 550; margin-bottom: 6px; }
.field__input {
  width: 100%; height: 40px; padding: 0 12px; background: var(--sunken);
  border: 1px solid var(--line-2); border-radius: 8px; font-size: 14px; color: var(--ink);
}
.field__input:focus { outline: none; border-color: var(--accent); background: var(--panel);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.field__err { font-size: 12.5px; color: #c23a3a; margin-top: 8px; line-height: 1.45; }
:root[data-theme="dark"] .field__err { color: #f19a98; }

/* ---- Pairing code dialog (FUNC-003) -------------------------------------- */
.dlg--code { max-width: 460px; }
.codegrid { display: flex; align-items: center; gap: 10px; margin-top: 16px; justify-content: center; }
.codeseg {
  width: 5.2ch; min-width: 0; flex: 1 1 5.2ch; max-width: 96px; height: 54px;
  text-align: center; font-size: 24px; letter-spacing: .18em;
  background: var(--sunken); border: 1px solid var(--line-2); border-radius: 10px; color: var(--ink);
}
.codeseg:focus { outline: none; border-color: var(--accent); background: var(--panel);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent); }
.codeseg:disabled { opacity: .6; }
.codesep { color: var(--faint); font-size: 20px; flex: none; }
.code__err { margin-top: 12px; }
.code__status { margin-top: 12px; font-size: 12.5px; color: var(--muted); display: flex; align-items: center; gap: 8px; line-height: 1.45; }
.code__status::before { content: ""; width: 14px; height: 14px; flex: none; border-radius: 50%;
  border: 2px solid var(--line-2); border-top-color: var(--accent); animation: spin 1s linear infinite; }

/* ============================================================================
   ROVING MENU (a11y.js) — ARIA menu pattern
   ============================================================================ */
.menu--roving button .m-lb { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu--roving button[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.menu__danger { color: #c23a3a; }
.menu__danger svg { color: #c23a3a; }
:root[data-theme="dark"] .menu__danger, :root[data-theme="dark"] .menu__danger svg { color: #ef9a9a; }

/* ---- Click feedback (immediate local acknowledgement of a press) ---------- */
.click-ripple {
  position: fixed;
  width: 16px; height: 16px;
  margin: -8px 0 0 -8px; /* center on the pointer */
  border-radius: 50%;
  border: 2px solid #4f8cff;
  background: rgba(79, 140, 255, .16);
  box-shadow: 0 0 0 1px rgba(79, 140, 255, .25);
  pointer-events: none;
  z-index: 9999;
  animation: click-ripple .4s cubic-bezier(.22, .61, .36, 1) forwards;
}
@keyframes click-ripple {
  from { transform: scale(.35); opacity: .95; }
  to   { transform: scale(2.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .click-ripple { animation-duration: .01s; opacity: 0; }
}

/* F3/F5 (Plan H): terminal + file-browser side panels. Mounted on demand by
   SessionView over the stage; the views own their inner markup. A dark, monospace
   surface for the terminal; a compact list for the file browser. */
.sidepanel[hidden] { display: none; }
.sidepanel {
  position: absolute; top: 0; right: 0; bottom: 0; width: min(46ch, 92%);
  background: var(--surface, #12151c); color: var(--text, #e7e9ee);
  border-left: 1px solid var(--border, #2a2f3a); box-shadow: -8px 0 24px rgba(0,0,0,.28);
  display: flex; flex-direction: column; z-index: 6; overflow: hidden;
}
/* Terminal-only session (F3): the shell IS the session — the (never-live) video
   canvas is already display:none, so let the terminal panel fill the whole stage
   instead of docking as a right-hand side panel over black. */
.stage.terminal-only #terminalPanel { left: 0; right: 0; width: auto; border-left: 0; box-shadow: none; }
[data-testid="terminal-panel"] {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  /* Fill the host (side panel OR full stage in terminal-only) as a column so the
     screen can flex to the whole height and scroll its history. */
  display: flex; flex-direction: column; position: relative;
  height: 100%; min-height: 0;
}
[data-testid="terminal-panel"] [data-term-screen] {
  flex: 1 1 auto; min-height: 0; /* min-height:0 lets the flex child shrink so overflow scrolls */
  overflow-y: auto; overflow-x: auto; padding: .5rem .6rem; white-space: pre; line-height: 1.25; font-size: 13px;
}
/* The transparent capture surface deliberately covers the rendered terminal:
   a click must focus it so a person (and keyboard-only assistive tooling) can
   actually send keystrokes to the remote PTY. */
[data-testid="terminal-panel"] [data-term-input] { position: absolute; inset: 0; opacity: 0; cursor: text; }
[data-testid="terminal-panel"]:focus-within { outline: 2px solid var(--focus, #72a7ff); outline-offset: -2px; }
/* The listing needs a flex height even while the sandbox is empty; otherwise
   the first remote list response has no visible target and the panel appears
   to contain only its toolbar. */
[data-testid="file-browser"] { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
[data-testid="file-browser"] [data-fs-list] { flex: 1; min-height: 1px; overflow: auto; }
[data-testid="file-browser"] [data-fs-row] {
  display: flex; align-items: center; gap: .5rem; padding: .3rem .6rem; cursor: pointer;
  border-bottom: 1px solid var(--border, #23272f);
}
[data-testid="file-browser"] [data-fs-row]:hover { background: rgba(255,255,255,.04); }
[data-testid="file-browser"] [data-fs-kind="dir"] { font-weight: 600; }
