/* Brand fonts vendored (variable woff2, Manual de Marca stack). NO CDN — served
   from /monitor/assets/fonts/. The type stacks below list these families FIRST,
   so they engage now that the faces are present. */
@font-face {
  font-family: 'Space Grotesk';
  src: url('/monitor/assets/fonts/SpaceGrotesk.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('/monitor/assets/fonts/Inter.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('/monitor/assets/fonts/JetBrainsMono.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
}

/* Brand splash (UX-SPLASH redesign) — a calm centered brand moment on ink, shown
   until the shell is up (atlas-splash.js fades it out with the .hide contract). The
   octopus ISOTYPE is the shipped asset (embedda-icon.svg) reused as an <img>, under a
   subtle brand-green glow; the wordmark is Space Grotesk. Dark-first, brand tokens.
   Kept EARLY (before the shell CSS) so the ink overlay paints instantly. */
#atlas-splash {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(120% 90% at 50% 40%, rgba(21, 224, 161, 0.05), transparent 62%),
    #0a0e13; /* la escena del splash (Manual de Marca --em-ink) */
  overflow: hidden;
  cursor: pointer;
  transition: opacity 0.6s ease;
}
#atlas-splash.hide {
  opacity: 0;
  pointer-events: none;
}
#atlas-splash .splash-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 30px;
  padding: 24px;
  text-align: center;
  pointer-events: none;
}
#atlas-splash .splash-halo {
  position: absolute;
  top: 62px;
  width: 340px;
  height: 340px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(21, 224, 161, 0.22), rgba(21, 224, 161, 0.05) 46%, transparent 70%);
  filter: blur(6px);
  pointer-events: none;
}
/* Hero (DC variant A · swarm orbit): a dashed ring of six swarm dots plus a
   slow counter-ring around the reused isotype. Pure CSS motion, killed under
   prefers-reduced-motion. The splash scene stays on ink in both themes. */
#atlas-splash .splash-hero {
  position: relative;
  width: 236px;
  height: 236px;
  display: grid;
  place-items: center;
}
#atlas-splash .splash-orbit {
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  border: 1px dashed rgba(233, 239, 243, 0.17);
  animation: splash-spin 24s linear infinite;
}
#atlas-splash .splash-orbit-inner {
  position: absolute;
  inset: 44px;
  border-radius: 50%;
  border: 1px solid rgba(233, 239, 243, 0.09);
  animation: splash-spin-r 30s linear infinite;
}
#atlas-splash .splash-orbit-dot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 8px;
  height: 8px;
  margin: -4px;
  border-radius: 50%;
  background: #15e0a1;
  box-shadow: 0 0 12px #15e0a1;
}
/* Six dots, DC accent family — estado green leads, ámbar/cyan/violet/blue join. */
#atlas-splash .od-0 { width: 10px; height: 10px; margin: -5px; transform: rotate(0deg) translateY(-110px); }
#atlas-splash .od-1 { background: #f2b33c; box-shadow: 0 0 12px #f2b33c; transform: rotate(60deg) translateY(-110px); }
#atlas-splash .od-2 { background: #34c7e0; box-shadow: 0 0 12px #34c7e0; transform: rotate(120deg) translateY(-110px); }
#atlas-splash .od-3 { width: 9px; height: 9px; margin: -4.5px; transform: rotate(180deg) translateY(-110px); }
#atlas-splash .od-4 { width: 7px; height: 7px; margin: -3.5px; background: #9d92ea; box-shadow: 0 0 12px #9d92ea; transform: rotate(240deg) translateY(-110px); }
#atlas-splash .od-5 { background: #5b86c9; box-shadow: 0 0 12px #5b86c9; transform: rotate(300deg) translateY(-110px); }
@keyframes splash-spin {
  to { transform: rotate(360deg); }
}
@keyframes splash-spin-r {
  to { transform: rotate(-360deg); }
}
#atlas-splash .splash-oct {
  position: relative;
  width: 148px;
  height: 148px;
  filter: drop-shadow(0 0 34px rgba(21, 224, 161, 0.30));
  animation: splash-float 5s ease-in-out infinite;
}
@keyframes splash-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}
#atlas-splash .splash-word {
  position: relative;
}
#atlas-splash .sw-mark {
  font-family: 'Space Grotesk', Inter, system-ui, sans-serif;
  font-weight: 600;
  font-size: 56px;
  letter-spacing: -0.01em;
  color: #f3f6f8;
  line-height: 1;
}
#atlas-splash .sw-sub {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.3em;
  color: #15e0a1;
  margin-top: 16px;
  text-transform: uppercase;
}
/* Story stepper (DC): incertidumbre → explicación → recomendación → acción →
   evidencia. Presentation of the product NARRATIVE — never of system state. */
#atlas-splash .splash-steps {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
}
#atlas-splash .splash-step {
  display: flex;
  align-items: center;
  gap: 7px;
}
#atlas-splash .step-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #86909c;
  opacity: 0.45;
  transition: all 0.3s ease;
}
#atlas-splash .step-label {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #86909c;
  opacity: 0.55;
  transition: all 0.3s ease;
}
#atlas-splash .splash-step.on .step-dot {
  width: 9px;
  height: 9px;
  background: #15e0a1;
  box-shadow: 0 0 12px #15e0a1;
  opacity: 1;
}
#atlas-splash .splash-step.on .step-label {
  color: #15e0a1;
  opacity: 1;
}
/* Sweep progress bar (DC) — pure brand motion, not a data claim. */
#atlas-splash .splash-progress {
  position: relative;
  width: 210px;
  height: 2px;
  border-radius: var(--radius-sm);
  background: rgba(233, 239, 243, 0.17);
  overflow: hidden;
}
#atlas-splash .splash-progress-bar {
  position: absolute;
  inset: 0;
  width: 42%;
  background: linear-gradient(90deg, transparent, #15e0a1, transparent);
  animation: splash-sweep 1.5s ease-in-out infinite;
}
@keyframes splash-sweep {
  0% { transform: translateX(-120%); }
  100% { transform: translateX(320%); }
}
/* Entry: honest fade/scale-in (.enter → .ready). Nothing here animates data. */
#atlas-splash.enter .splash-stage {
  opacity: 0;
  transform: translateY(8px) scale(0.985);
}
#atlas-splash.ready .splash-stage {
  opacity: 1;
  transform: none;
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.16, 0.84, 0.44, 1);
}
#atlas-splash.enter .splash-halo {
  opacity: 0;
}
#atlas-splash.ready .splash-halo {
  opacity: 1;
  transition: opacity 1.1s ease;
}
@media (prefers-reduced-motion: reduce) {
  #atlas-splash .splash-stage,
  #atlas-splash.enter .splash-stage,
  #atlas-splash.ready .splash-stage {
    opacity: 1;
    transform: none;
    transition: none;
  }
  #atlas-splash.ready .splash-halo {
    transition: none;
  }
  /* DC additions land settled: no spin/float/sweep, stepper lit by JS. */
  #atlas-splash .splash-orbit,
  #atlas-splash .splash-orbit-inner,
  #atlas-splash .splash-oct,
  #atlas-splash .splash-progress-bar {
    animation: none;
  }
}

:root {
  color-scheme: dark;
  /* ── BRAND PALETTE (Manual de Marca --em-*, dark-first — SUPERSEDES navy/teal) ─
     CAMPO  #0A0E13 ink   = field / canvas / console BACKGROUND (--em-ink).
     ESTADO #15E0A1 green = state/coverage/entropy/honesty-derived (invariant).
     ACCIÓN #F2B33C amber = action/objectives/missions/gated      (invariant).
     EVIDENCIA #F3F6F8 pale = light surfaces / dark-theme ink.
     The token NAMES below (--mint/--amber/--blue/…) are PRESERVED so the
     ~250 existing var(--…) refs keep resolving; only their VALUES are rebased
     onto the brand. Green (--mint) + amber (--amber) are the semantic SPINE,
     invariant across all six verticals; --blue/--cyan/--green/--violet are the
     disciplined per-vertical identity hues, redrawn from the ink/green/amber
     family (NOT the old random sprawl). All sampled AA on the ink bg. */
  --bg: #0a0e13; /* INK canvas (Manual de Marca --em-ink) */
  --ink: #e9eff3; /* text (--em-text) */
  --muted: #9aa6b2; /* secondary text (--em-text-2) */
  --quiet: #86909c; /* de-emphasis floor (manual --em-text-mute) — AA (>=4.5) on the WHOLE INK
                       elevation ramp (field-0..3). Re-tuned for the ink rebrand: the previous
                       #66727e was set against the OLD navy ramp and dropped to ~3.9 once field-0
                       became the darker ink #0a0e13, i.e. BELOW 4.5. Kept < --muted #9aa6b2 on
                       every surface, so the primary>secondary>muted hierarchy still holds. */
  --line: rgba(233, 239, 243, 0.08); /* --em-hairline */
  --line-strong: rgba(233, 239, 243, 0.16); /* --em-hairline-strong */
  --dock: rgba(10, 14, 19, 0.84); /* ink-tinted dock */
  --dock-strong: rgba(5, 8, 12, 0.94);
  /* INK ELEVATION RAMP — panels/cards/dock sit ABOVE the canvas (--em-surface*). */
  --field-0: #0a0e13; /* canvas floor (== --bg, --em-ink) */
  --field-1: #10151d; /* panel / sunken surface (--em-surface) */
  --field-2: #161d27; /* card / raised surface (--em-surface-2) */
  --field-3: #1d2530; /* hover / active raised (--em-surface-3) */
  --mint: #15e0a1; /* GREEN brand — state/coverage/derived/nominal (--em-green) */
  --green: #0aa878; /* green-deep, agro identity (--em-green-deep) */
  --blue: #5b86c9; /* blue, retail/low identity (--em-sev-low) */
  --amber: #f2b33c; /* ACCIÓN amber — action/objectives/gated (--em-warning) */
  --red: #e5484d; /* alarm (--em-danger / --em-sev-critical) */
  --violet: #9d92ea; /* indigo, "seguir" action (honesty-only, off-palette) */
  --cyan: #34c7e0; /* cyan, puerto/neighborhood identity (--em-cyan) */
  --gold: #e8b94b; /* civic gold, ciudad identity (--em-sev-medium) */
  --shadow: 0 26px 90px rgba(0, 0, 0, 0.52);

  /* ── DC STAGE TOKENS (Atlas.dc redesign — user-designed mockup) ─────────────
     The stage (map + entropy field + pins) reads from these so both themes stay
     coherent with the DC. --map is the floor under the basemap tiles (ink
     family, replaces the legacy navy #08182f); the pin tokens style the
     geo-anchored markers; --vignette frames the stage edges. */
  --map: #08131f;
  --pin-ring: rgba(8, 19, 31, 0.85);
  --pin-label: rgba(8, 13, 19, 0.82);
  --pin-label-ink: #f3f6f8;
  --vignette: rgba(6, 11, 18, 0.34);
  /* ACTION spine (DC invariant): misiones / objetivos / crear-ejecutar / gated
     render AMBER; green (--mint) stays RESERVED for estado/cobertura/entropía/
     derivado. Evaluate/derived affordances keep the green --accent. */
  --action: var(--amber);
  --action-fill: rgba(242, 179, 60, 0.16);
  --action-line: rgba(242, 179, 60, 0.55);

  /* ── DESIGN-SYSTEM v2 ───────────────────────────────────────────────────────
     One finite token set, used across the high-visibility surfaces (topbar,
     tabs, scope chips, panels, cards, badges, pills, buttons, rows, dock).
     Values chosen to equal-or-improve current pixels → the sweep is a
     find-replace, not a redesign (no visual regression). Theme overrides for
     the surface/ink-step/elevation tokens live in body[data-theme="light"]. */

  /* TYPE SCALE — Inter (sans) + ui-monospace (data), disciplined hierarchy.
     BRAND TYPE (Nexus/Embedda): Space Grotesk (display/headings) + Inter (body)
     + JetBrains Mono (mono labels/data). The three faces ARE vendored as
     variable .woff2 under /monitor/assets/fonts/ (see the @font-face block at
     the top of this file) — the stacks engage them, with system faces as the
     offline fallback. */
  --font-display: "Space Grotesk", Inter, ui-sans-serif, system-ui, sans-serif;
  --font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace; /* brand target; falls back to ui-monospace */
  --fs-micro: 10px; /* mono eyebrow / label */
  --fs-2xs: 11px; /* meta, pills, badges */
  --fs-xs: 12px; /* secondary body */
  --fs-sm: 13px; /* body, tabs */
  --fs-md: 14px; /* emphasis body */
  --fs-lg: 16px; /* card title */
  --fs-xl: 21px; /* panel heading */
  --fs-2xl: 25px; /* dock h1 */
  --fs-hero: clamp(28px, 3vw, 38px); /* glanceable big-number */
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --lh-tight: 1.1;
  --lh-snug: 1.3;
  --lh-normal: 1.45;
  --tracking-wide: 0.1em; /* mono eyebrows */
  --tracking-caps: 0.13em; /* uppercase labels */

  /* SPACING — 4px base grid. */
  --space-2xs: 2px;
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-lg: 16px;
  --space-xl: 24px;
  --space-2xl: 32px;

  /* RADIUS — collapse the 12-value zoo to 4 steps + pill. */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-pill: 999px;

  /* OPACITY steps. */
  --opacity-muted: 0.6;
  --opacity-secondary: 0.8;
  --opacity-disabled: 0.4;

  /* INK STEPS — text hierarchy at AA+ on the dark base. --ink-2 is the new
     floor for inactive controls (was --muted, which failed AA). */
  --ink-2: #cdd7e2; /* high-legibility secondary ink on navy (11.51:1) */

  /* SURFACE FILLS — ONE value per semantic (was 42 ad-hoc rgba literals). */
  --surface-1: rgba(255, 255, 255, 0.032); /* panel / card */
  --surface-2: rgba(255, 255, 255, 0.06); /* control rest / hover step */
  --surface-3: rgba(255, 255, 255, 0.018); /* sunken header */
  --surface-input: rgba(0, 0, 0, 0.26);
  --neutral-chip: rgba(168, 186, 196, 0.16); /* visible neutral control fill */
  --neutral-chip-line: rgba(168, 186, 196, 0.5);

  /* ACCENT — the per-console accent (defaults to Guardian mint; the console
     reskins this via [data-accent] so chips/active-states retint per vertical). */
  --accent: var(--mint);
  --accent-rgb: 21, 224, 161; /* GREEN brand — default (Guardian) accent, == --mint #15e0a1 */
  --accent-line: rgba(var(--accent-rgb), 0.52);
  --accent-fill: rgba(var(--accent-rgb), 0.18); /* the single secondary-active fill */
  --accent-fill-soft: rgba(var(--accent-rgb), 0.1);
  --accent-glow: rgba(var(--accent-rgb), 0.26);

  /* HONESTY tokens — the credibility grammar (derived/representative/gated/roadmap). */
  --honesty-derived: var(--mint);
  --honesty-representative: var(--blue);
  --honesty-gated: var(--amber);
  --honesty-roadmap: var(--quiet);
  /* H1 — extended honest-state grammar. interpolated = value shown BETWEEN measured
     cells (the heatmap halo), NOT an observation; conflicted = sources disagree (no live
     producer today — see honestStateChip). Theme-aware via --blue/--red. */
  --honesty-interpolated: var(--blue);
  --honesty-conflicted: var(--red);

  /* ELEVATION scale. */
  --elev-1: 0 4px 16px rgba(0, 0, 0, 0.28);
  --elev-2: 0 12px 40px rgba(0, 0, 0, 0.4);
  --elev-3: 0 26px 90px rgba(0, 0, 0, 0.52);

  /* MOTION — durations + easings (motion was essentially absent before). */
  --dur-1: 120ms;
  --dur-2: 180ms;
  --dur-3: 260ms;
  --ease-standard: cubic-bezier(0.2, 0, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
}

body[data-theme="light"] {
  color-scheme: light;
  /* EVIDENCIA #F3F6F8 pale = the light-theme field; ink/accents re-darkened to
     hold WCAG-AA on the pale surface (all sampled, see notes). */
  --bg: #f3f6f8; /* EVIDENCIA pale */
  --ink: #142533; /* navy-ink (14.42:1 on pale) */
  --muted: #4a5b6e; /* 6.42:1 */
  --quiet: #54616f; /* de-emphasis floor on the PALE ramp — AA everywhere:
                       5.47:1 base · 4.71:1 field-2 · 4.57:1 field-3
                       (was #5d6e80 = 4.83 on the pale base but 3.78 on field-3,
                        i.e. dropped below AA on the light panel/card surfaces).
                        Still lighter-contrast than --muted, hierarchy preserved. */
  --line: rgba(20, 37, 51, 0.16);
  --line-strong: rgba(20, 37, 51, 0.34);
  --dock: rgba(248, 251, 253, 0.9);
  --dock-strong: rgba(255, 255, 255, 0.97);
  /* navy elevation ramp inverts to a pale ramp on the light field. */
  --field-0: #f3f6f8;
  --field-1: #e9eef4;
  --field-2: #dfe6ee;
  --field-3: #d3dce7;
  --mint: #0e7a5a; /* GREEN brand (green-dim, --em-green-dim), AA on pale (~4.7:1) */
  --green: #2f7a5b; /* brand sage (4.77:1) */
  --blue: #1f6aab; /* brand azure (5.22:1) */
  --amber: #9c6500; /* ACCIÓN amber (4.53:1) */
  --red: #b43b35;
  --violet: #5b4fb0; /* brand indigo (6.07:1) */
  --cyan: #0d7884; /* brand cyan (4.79:1) */
  --gold: #8a6a12; /* brand civic gold (4.66:1) */
  --shadow: 0 20px 64px rgba(20, 37, 51, 0.18);

  /* DESIGN-SYSTEM v2 — theme-aware overrides (surface/ink/elevation/accent). */
  --ink-2: #243140; /* high-legibility secondary ink on the pale base (12.18:1) */
  --surface-1: rgba(20, 37, 51, 0.04);
  --surface-2: rgba(20, 37, 51, 0.07);
  --surface-3: rgba(20, 37, 51, 0.025);
  --surface-input: rgba(255, 255, 255, 0.82);
  --neutral-chip: rgba(20, 37, 51, 0.07);
  --neutral-chip-line: rgba(20, 37, 51, 0.22);
  --accent: var(--mint);
  --accent-rgb: 14, 122, 90; /* GREEN brand (light), == --mint light #0e7a5a */
  --honesty-derived: var(--mint);
  --honesty-representative: var(--blue);
  --honesty-gated: var(--amber);
  --honesty-roadmap: var(--quiet);
  --elev-1: 0 4px 16px rgba(20, 37, 51, 0.1);
  --elev-2: 0 12px 36px rgba(20, 37, 51, 0.16);
  --elev-3: 0 20px 64px rgba(20, 37, 51, 0.18);

  /* DC STAGE TOKENS — light theme. --map keeps the DC's cool map-paper tone;
     the pin label ink is the audited light --ink (adapted from the DC's
     #0b1521 so text on pins matches the rest of the light theme). */
  --map: #bcc9d8;
  --pin-ring: rgba(247, 250, 253, 0.97);
  --pin-label: rgba(247, 250, 253, 0.96);
  --pin-label-ink: #142533;
  --vignette: rgba(70, 90, 112, 0.16);
  /* ACTION spine over the pale field — fills read from the light amber. */
  --action: var(--amber);
  --action-fill: rgba(156, 101, 0, 0.14);
  --action-line: rgba(156, 101, 0, 0.5);
}

* {
  box-sizing: border-box;
}

html,
body,
.atlas-app {
  width: 100%;
  height: 100%;
  margin: 0;
}

body {
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  letter-spacing: 0;
  /* DC invariant: every figure in the console is tabular — columns of numbers
     (fps, %, H, counts, clocks) align instead of jittering as digits change. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

button,
input,
select {
  font: inherit;
}

button {
  color: inherit;
}

.atlas-app {
  display: grid;
  grid-template-rows: 56px 1fr;
  min-width: 320px;
  min-height: 620px;
  background:
    radial-gradient(circle at 16% 18%, rgba(21, 224, 161, 0.08), transparent 28%),
    radial-gradient(circle at 78% 78%, rgba(242, 163, 38, 0.07), transparent 26%),
    #0a0e13;
}

body[data-theme="light"] .atlas-app {
  background:
    radial-gradient(circle at 16% 18%, rgba(14, 122, 90, 0.08), transparent 28%),
    radial-gradient(circle at 78% 78%, rgba(156, 101, 0, 0.06), transparent 26%),
    #f3f6f8;
}

.topbar {
  position: relative;
  z-index: 20;
  display: grid;
  /* On-axis children: brand · scope/search · node · tenant · language · theme · demo · help · runtime.
     Only the scope-row column is flexible (minmax(0,1fr) → can shrink to 0 so
     its inner scope scrolls); every control to its right keeps its content
     width on a single row. grid-auto-flow:column makes the count explicit and
     keeps any stray child on the same axis (never wrapping to a 2nd row). */
  grid-auto-flow: column;
  grid-template-columns: 270px minmax(0, 1fr) repeat(7, auto);
  align-items: center;
  border-bottom: 1px solid var(--line);
  background: var(--dock);
  backdrop-filter: blur(18px);
}

.brand {
  height: 100%;
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 0 16px;
  color: var(--ink);
  text-decoration: none;
  border-right: 1px solid var(--line);
}

/* Marca Embedda = el pulpo (inteligencia distribuida). El isotipo vive en
   /monitor/assets/embedda-icon.svg; acá sólo lo montamos a tamaño + glow. */
.brand-mark {
  width: 30px;
  height: 30px;
  border-radius: var(--radius-md);
  background-image: url("/monitor/assets/embedda-icon.svg?v=20260629-octopus");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  box-shadow: 0 0 26px rgba(21, 224, 161, 0.24);
}

.brand strong {
  display: block;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.brand small,
.runtime em,
.command-palette label,
.section header span,
.dock-pane label {
  display: block;
  color: var(--quiet);
  font-family: var(--font-mono);
  font-size: 10px;
  font-style: normal;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.scope {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 0 14px;
  overflow-x: auto;
  /* Hide the scrollbar tastefully — the fade-mask below is the affordance. */
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Fade-mask on the trailing (and leading) edge so a cut chip reads as
     "this row scrolls" rather than "this chip is broken". The mask is only
     meaningful once the row actually overflows; at rest the edges are opaque
     because the content does not reach them. */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 14px,
    #000 calc(100% - 22px),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 14px,
    #000 calc(100% - 22px),
    transparent 100%
  );
}

.scope::-webkit-scrollbar {
  display: none;
}

.scope button,
.tabs button {
  height: 31px;
  /* Chips never squish — they keep their natural size and the row scrolls. */
  flex-shrink: 0;
  white-space: nowrap;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--ink-2);
  padding: 0 var(--space-md);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition:
    background var(--dur-1) var(--ease-standard),
    border-color var(--dur-1) var(--ease-standard),
    color var(--dur-1) var(--ease-standard);
}

.theme-toggle {
  height: 32px;
  min-width: 78px;
  margin: 0 var(--space-md);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--ink-2);
  padding: 0 var(--space-md);
  white-space: nowrap;
  cursor: pointer;
  transition:
    background var(--dur-1) var(--ease-standard),
    border-color var(--dur-1) var(--ease-standard),
    color var(--dur-1) var(--ease-standard);
}

/* DC topbar: the theme pill carries its glyph. CSS-only (::before keyed off
   body[data-theme]) so the i18n text sweep never erases it. Scoped to the id —
   .help-toggle shares the pill class but not the glyph. */
#theme-toggle::before {
  content: "\263E  "; /* ☾ */
}

body[data-theme="light"] #theme-toggle::before {
  content: "\2600  "; /* ☀ */
}

.theme-toggle:hover {
  border-color: var(--line-strong);
  background: var(--surface-1);
  color: var(--ink);
}

.theme-toggle[aria-pressed="true"] {
  color: var(--ink);
  border-color: rgba(14, 122, 90, 0.42);
  background: rgba(14, 122, 90, 0.1);
}

.scope button:hover,
.tabs button:hover,
.tool:hover,
.map-node:hover,
.mission-tile:hover,
.right-dock footer button:hover,
.command-palette button:hover {
  border-color: var(--line-strong);
  background: var(--surface-1);
  color: var(--ink);
}

.scope button:focus-visible,
.tabs button:focus-visible,
.theme-toggle:focus-visible,
.command-palette input:focus-visible,
.command-palette button:focus-visible,
.right-dock footer button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.scope button.active,
.tabs button.active {
  color: var(--ink);
  border-color: var(--accent-line);
  background: var(--accent-fill);
  font-weight: var(--fw-semibold);
  box-shadow: inset 2px 0 0 var(--accent);
}

.runtime {
  height: 100%;
  display: flex;
  border-left: 1px solid var(--line);
  /* Never wrap and never get clipped: the meta strip keeps a single line and
     compacts (see the breakpoints below) instead of being cut on the right. */
  white-space: nowrap;
  flex: none;
}

.runtime span {
  min-width: 0;
  display: grid;
  align-content: center;
  gap: 2px;
  padding: 0 13px;
  border-left: 1px solid var(--line);
}

.runtime span:first-child {
  border-left: 0;
}

.runtime strong {
  max-width: 130px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: 12px;
}

/* DC topbar: the runtime MODE reads amber — advisory/assisted is an
   action-gating status, not a nominal state (green stays estado-only). */
#mode-label {
  color: var(--amber);
}

#api-light {
  width: 8px;
  height: 8px;
  display: inline-block;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 15px currentColor;
  color: var(--amber);
}

#api-light.online {
  /* STATE NOMINAL = ESTADO green (brand spine), not the sage identity hue. */
  background: var(--mint);
  color: var(--mint);
}

#api-light.offline {
  background: var(--red);
  color: var(--red);
}

.stage {
  position: relative;
  min-height: 0;
  overflow: hidden;
}

#field-canvas,
.map-space,
.map-grid {
  position: absolute;
  inset: 0;
}

/* DC · stage vignette — frames the territory so the field reads as the
   protagonist (theme-aware via --vignette). Sits just over the field canvas
   (z3) and under every control (toolrail z8+, docks, palettes). */
.stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background: radial-gradient(130% 110% at 50% 45%, transparent 60%, var(--vignette));
}

#field-canvas {
  z-index: 3;
  pointer-events: none;
  background: transparent;
  /* Un <canvas> es elemento reemplazado: inset:0 NO lo estira (usa su tamaño
     intrínseco 300x150 en la esquina). width/height 100% lo hace llenar .stage. */
  width: 100%;
  height: 100%;
}

.map-space {
  z-index: 2;
  overflow: hidden;
  cursor: default;
  background:
    linear-gradient(118deg, transparent 0 38%, rgba(61, 139, 212, 0.08) 38.2% 38.8%, transparent 39% 100%),
    linear-gradient(24deg, transparent 0 58%, rgba(21, 224, 161, 0.09) 58.2% 58.8%, transparent 59% 100%),
    linear-gradient(156deg, transparent 0 66%, rgba(242, 163, 38, 0.07) 66.2% 66.7%, transparent 67% 100%),
    linear-gradient(rgba(243, 246, 248, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(243, 246, 248, 0.045) 1px, transparent 1px),
    var(--map);
  background-size: 100% 100%, 100% 100%, 100% 100%, 96px 96px, 96px 96px, 100% 100%;
}

body[data-theme="light"] .map-space {
  background:
    linear-gradient(118deg, transparent 0 38%, rgba(31, 106, 171, 0.08) 38.2% 38.8%, transparent 39% 100%),
    linear-gradient(24deg, transparent 0 58%, rgba(14, 122, 90, 0.09) 58.2% 58.8%, transparent 59% 100%),
    linear-gradient(156deg, transparent 0 66%, rgba(156, 101, 0, 0.06) 66.2% 66.7%, transparent 67% 100%),
    linear-gradient(rgba(20, 37, 51, 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(20, 37, 51, 0.07) 1px, transparent 1px),
    var(--map);
  background-size: 100% 100%, 100% 100%, 100% 100%, 96px 96px, 96px 96px, 100% 100%;
}

.atlas-app[data-draw="on"] .map-space {
  cursor: crosshair;
}

.leaflet-container {
  width: 100%;
  height: 100%;
  background:
    radial-gradient(ellipse at 20% 30%, rgba(21, 224, 161, 0.08), transparent 34%),
    radial-gradient(ellipse at 78% 66%, rgba(61, 139, 212, 0.075), transparent 32%),
    linear-gradient(118deg, transparent 0 38%, rgba(61, 139, 212, 0.08) 38.2% 38.8%, transparent 39% 100%),
    linear-gradient(24deg, transparent 0 58%, rgba(21, 224, 161, 0.09) 58.2% 58.8%, transparent 59% 100%),
    linear-gradient(156deg, transparent 0 66%, rgba(242, 163, 38, 0.07) 66.2% 66.7%, transparent 67% 100%),
    linear-gradient(rgba(243, 246, 248, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(243, 246, 248, 0.045) 1px, transparent 1px),
    var(--map);
  background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 96px 96px, 96px 96px, 100% 100%;
  color: var(--ink);
  font: inherit;
}

body[data-theme="light"] .leaflet-container {
  background:
    radial-gradient(ellipse at 20% 30%, rgba(14, 122, 90, 0.08), transparent 34%),
    radial-gradient(ellipse at 78% 66%, rgba(31, 106, 171, 0.08), transparent 32%),
    linear-gradient(118deg, transparent 0 38%, rgba(31, 106, 171, 0.08) 38.2% 38.8%, transparent 39% 100%),
    linear-gradient(24deg, transparent 0 58%, rgba(14, 122, 90, 0.09) 58.2% 58.8%, transparent 59% 100%),
    linear-gradient(156deg, transparent 0 66%, rgba(156, 101, 0, 0.06) 66.2% 66.7%, transparent 67% 100%),
    linear-gradient(rgba(20, 37, 51, 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(20, 37, 51, 0.07) 1px, transparent 1px),
    var(--map);
  background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 96px 96px, 96px 96px, 100% 100%;
}

body[data-theme="light"] .map-space::before {
  background:
    linear-gradient(90deg, transparent 0 21%, rgba(20, 37, 51, 0.065) 21.2% 21.4%, transparent 21.6% 100%),
    linear-gradient(90deg, transparent 0 52%, rgba(20, 37, 51, 0.058) 52.2% 52.45%, transparent 52.7% 100%),
    linear-gradient(90deg, transparent 0 74%, rgba(20, 37, 51, 0.056) 74.2% 74.5%, transparent 74.75% 100%),
    linear-gradient(0deg, transparent 0 28%, rgba(20, 37, 51, 0.056) 28.2% 28.45%, transparent 28.7% 100%),
    linear-gradient(0deg, transparent 0 63%, rgba(20, 37, 51, 0.058) 63.2% 63.5%, transparent 63.75% 100%);
}

.map-space::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.72;
  background:
    linear-gradient(90deg, transparent 0 21%, rgba(243, 246, 248, 0.055) 21.2% 21.4%, transparent 21.6% 100%),
    linear-gradient(90deg, transparent 0 52%, rgba(243, 246, 248, 0.052) 52.2% 52.45%, transparent 52.7% 100%),
    linear-gradient(90deg, transparent 0 74%, rgba(243, 246, 248, 0.05) 74.2% 74.5%, transparent 74.75% 100%),
    linear-gradient(0deg, transparent 0 28%, rgba(243, 246, 248, 0.05) 28.2% 28.45%, transparent 28.7% 100%),
    linear-gradient(0deg, transparent 0 63%, rgba(243, 246, 248, 0.052) 63.2% 63.5%, transparent 63.75% 100%);
}

.leaflet-tile {
  filter: saturate(0.82) brightness(0.82) contrast(1.08);
}

/* BASE LIMPIA del drill-down del enjambre (sin texturas): el contenedor Leaflet
   queda sin tiles → tinta del piso oscura, intencionalmente vacía para que la DATA
   (footprints + campo de entropía + dispositivos + detecciones) sea el contenido.
   Fiel a nexus-floor (proyecta detecciones métricas, no imágenes). */
.map-space[data-basemap="floor"] .leaflet-container {
  background: var(--map);
}
.map-space[data-basemap="floor"] {
  background: var(--map);
}

/* Footprints geo-anclados (proyección IPM representativa, a escala, de cada cámara). */
.swarm-footprint {
  transition: opacity 120ms ease;
}
/* Cono de FOV del dispositivo (hacia dónde mira). */
.swarm-fov {
  transition: opacity 120ms ease;
}

/* Marker PROMINENTE de dispositivo sobre la base limpia: glyph por tipo + etiqueta,
   legible al instante. El color lo inyecta el JS (--dev-color). */
.swarm-dev-icon {
  background: transparent;
  border: none;
}
.swarm-dev-pin {
  display: flex;
  align-items: center;
  gap: 5px;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  pointer-events: none;
  font: 600 11px/1 "Space Grotesk", system-ui, sans-serif;
}
.swarm-dev-pin .dev-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-sm);
  color: #08182f;
  background: var(--dev-color, #15e0a1);
  box-shadow: 0 0 0 2px rgba(10, 14, 19, 0.85), 0 0 10px var(--dev-color, #15e0a1);
  font-size: 12px;
}
.swarm-dev-pin .dev-label {
  color: var(--dev-color, #15e0a1);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9), 0 0 2px rgba(0, 0, 0, 0.9);
  letter-spacing: 0.01em;
}

body[data-theme="light"] .leaflet-tile {
  filter: saturate(0.8) brightness(1.05) contrast(0.94);
}

.leaflet-tile-pane {
  opacity: 0.9;
}

.leaflet-bottom.leaflet-right {
  right: 426px;
}

.leaflet-top.leaflet-left {
  top: 18px;
  left: 76px;
  z-index: 9;
}

.leaflet-top.leaflet-left .leaflet-control {
  margin: 0;
}

.leaflet-control-attribution {
  max-width: min(360px, calc(100vw - 24px));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill) 0 0 0;
  background: rgba(10, 14, 19, 0.7) !important;
  color: var(--quiet) !important;
  font-size: 10px;
}

body[data-theme="light"] .leaflet-control-attribution {
  background: rgba(250, 253, 249, 0.78) !important;
}

.leaflet-control-attribution a {
  color: var(--muted) !important;
}

.leaflet-control-zoom {
  overflow: hidden;
  border: 1px solid var(--line) !important;
  border-radius: var(--radius-md) !important;
  background: var(--dock) !important;
  box-shadow: var(--shadow) !important;
  backdrop-filter: blur(16px);
}

body[data-theme="light"] .leaflet-control-zoom {
  background: rgba(250, 253, 249, 0.88) !important;
}

.leaflet-control-zoom a {
  border-bottom: 1px solid var(--line) !important;
  background: transparent !important;
  color: var(--ink) !important;
}

.leaflet-control-zoom a:last-child {
  border-bottom: 0 !important;
}

.leaflet-div-icon.nexus-site-icon {
  border: 0;
  background: transparent;
}

.leaflet-div-icon.nexus-draft-icon {
  border: 0;
  background: transparent;
}

.map-grid {
  opacity: 0.52;
  background:
    linear-gradient(rgba(243, 246, 248, 0.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(243, 246, 248, 0.055) 1px, transparent 1px),
    linear-gradient(rgba(21, 224, 161, 0.08), transparent 28%, transparent 72%, rgba(242, 163, 38, 0.06));
  background-size: 80px 80px, 80px 80px, 100% 100%;
  mask-image: radial-gradient(circle at center, #000 0, #000 62%, transparent 100%);
}

.marker-layer {
  position: absolute;
  inset: 0;
}

.toolrail {
  position: absolute;
  z-index: 8;
  left: 16px;
  top: 18px;
  display: grid;
  gap: 8px;
  max-height: calc(100% - 36px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
}

.toolrail::-webkit-scrollbar {
  display: none;
}

.tool {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--dock);
  color: var(--ink-2);
  box-shadow: var(--elev-2);
  backdrop-filter: blur(18px);
  cursor: pointer;
  transition:
    background var(--dur-1) var(--ease-standard),
    border-color var(--dur-1) var(--ease-standard),
    color var(--dur-1) var(--ease-standard);
}

.tool.active {
  color: var(--accent);
  border-color: var(--accent-line);
  background: var(--accent-fill);
  box-shadow: var(--elev-2), inset 0 0 0 1px var(--accent-fill-soft);
}

.tool svg {
  /* Unified brand icon set: 24x24 grid (viewBox), single stroke-width, round
     caps/joins → a coherent, calm line (no military/HUD edge). */
  width: 21px;
  height: 21px;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.map-node {
  --node-color: var(--mint);
  position: absolute;
  width: 112px;
  height: 112px;
  margin-left: -56px;
  margin-top: -56px;
  border: 0;
  background: transparent;
  color: var(--node-color);
  cursor: pointer;
}

.map-node .aura,
.map-node .ring,
.map-node .core,
.map-node .spoke {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

.map-node .aura {
  inset: 0;
  background: currentColor;
  opacity: 0.12;
  filter: blur(14px);
  animation: node-breathe 4s ease-in-out infinite;
}

.map-node .ring {
  left: 34px;
  top: 34px;
  width: 44px;
  height: 44px;
  border: 1px solid currentColor;
  background: rgba(10, 14, 19, 0.82);
  box-shadow:
    0 0 0 8px color-mix(in srgb, currentColor, transparent 88%),
    0 0 34px color-mix(in srgb, currentColor, transparent 58%);
}

.map-node .core {
  left: 48px;
  top: 48px;
  width: 16px;
  height: 16px;
  background: currentColor;
  box-shadow: 0 0 20px currentColor;
}

.map-node .spoke {
  left: 56px;
  top: 16px;
  width: 1px;
  height: 80px;
  background: linear-gradient(currentColor, transparent);
  opacity: 0.38;
  transform: rotate(var(--rotation));
  transform-origin: 50% 40px;
}

.map-node .label {
  position: absolute;
  left: 50%;
  top: 82px;
  transform: translateX(-50%);
  max-width: 170px;
  padding: 4px 9px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border: 1px solid rgba(243, 246, 248, 0.16);
  border-radius: var(--radius-pill);
  background: rgba(10, 14, 19, 0.76);
  color: #f3f6f8;
  font-size: 11px;
  box-shadow: 0 16px 38px rgba(0, 0, 0, 0.34);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.48);
}

.map-node .stack {
  position: absolute;
  left: 70px;
  top: 31px;
  display: flex;
  gap: 3px;
}

.map-node .stack i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  border: 1px solid rgba(255, 255, 255, 0.32);
}

.map-node .health {
  position: absolute;
  right: 0;
  top: 18px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  color: var(--muted);
}

.map-node.selected .ring {
  border: 2px solid #fff;
  box-shadow:
    0 0 0 11px color-mix(in srgb, currentColor, transparent 82%),
    0 0 48px color-mix(in srgb, currentColor, transparent 38%);
}

.map-node.dim {
  opacity: 0.22;
}

.map-node.offline {
  filter: grayscale(0.8);
}

.site-pin {
  --node-color: var(--mint);
  position: relative;
  width: 112px;
  height: 112px;
  color: var(--node-color);
  transform: translate(-56px, -56px);
}

.site-pin .aura,
.site-pin .ring,
.site-pin .core,
.site-pin .spoke {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

.site-pin .aura {
  inset: 0;
  background: currentColor;
  opacity: 0.12;
  filter: blur(14px);
  animation: node-breathe 4s ease-in-out infinite;
}

.site-pin .ring {
  left: 34px;
  top: 34px;
  width: 44px;
  height: 44px;
  border: 1px solid currentColor;
  background: rgba(10, 14, 19, 0.82);
  box-shadow:
    0 0 0 8px color-mix(in srgb, currentColor, transparent 88%),
    0 0 34px color-mix(in srgb, currentColor, transparent 58%);
}

.site-pin .core {
  left: 48px;
  top: 48px;
  width: 16px;
  height: 16px;
  background: currentColor;
  box-shadow: 0 0 20px currentColor;
}

.site-pin .spoke {
  left: 56px;
  top: 16px;
  width: 1px;
  height: 80px;
  background: linear-gradient(currentColor, transparent);
  opacity: 0.38;
  transform: rotate(var(--rotation));
  transform-origin: 50% 40px;
}

.site-pin .label {
  position: absolute;
  left: 50%;
  top: 82px;
  transform: translateX(-50%);
  max-width: 170px;
  padding: 4px 9px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border: 1px solid rgba(243, 246, 248, 0.16);
  border-radius: var(--radius-pill);
  background: rgba(10, 14, 19, 0.78);
  color: #f3f6f8;
  font-size: 11px;
  box-shadow: 0 16px 38px rgba(0, 0, 0, 0.34);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.48);
}

.site-pin .stack {
  position: absolute;
  left: 70px;
  top: 31px;
  display: flex;
  gap: 3px;
}

.site-pin .stack i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  border: 1px solid rgba(255, 255, 255, 0.32);
}

.site-pin .health {
  position: absolute;
  right: 0;
  top: 18px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  color: var(--muted);
}

.site-pin .orders,
.site-pin .mission-state {
  position: absolute;
  left: 66px;
  min-width: 58px;
  max-width: 94px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border: 1px solid rgba(243, 246, 248, 0.16);
  border-radius: var(--radius-pill);
  background: rgba(10, 14, 19, 0.8);
  color: var(--ink);
  padding: 2px 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 9px;
  text-transform: uppercase;
}

.site-pin .orders {
  top: 49px;
  color: var(--amber);
  border-color: rgba(242, 163, 38, 0.42);
}

.site-pin .mission-state {
  top: 65px;
  color: var(--mint);
  border-color: rgba(21, 224, 161, 0.36);
}

.site-pin .mission-state.warn {
  color: var(--amber);
  border-color: rgba(242, 163, 38, 0.4);
}

.site-pin .mission-state.block {
  color: var(--red);
  border-color: rgba(255, 109, 104, 0.42);
}

.site-pin.selected .ring {
  border: 2px solid #fff;
  box-shadow:
    0 0 0 11px color-mix(in srgb, currentColor, transparent 82%),
    0 0 48px color-mix(in srgb, currentColor, transparent 38%);
}

.site-pin.dim {
  opacity: 0.24;
}

.site-pin.offline {
  filter: grayscale(0.8);
}

/* ── IA corregida · TERRITORIO = enjambres ────────────────────────────────── */
/* La chinche de un ENJAMBRE late más fuerte (es un sitio entero, no un nodo) y
   muestra barrio + dispositivos + cobertura. Click → drill-down aéreo. */
.site-pin.swarm-pin {
  cursor: zoom-in;
}

.site-pin.swarm-pin .aura {
  animation-duration: 4.6s;
}

.site-pin.swarm-pin .label {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  line-height: 1.18;
  white-space: normal;
  text-align: center;
  font-weight: 600;
}

.site-pin .swarm-barrio {
  font-size: 9px;
  font-weight: 400;
  color: var(--muted);
  letter-spacing: 0.02em;
}

.site-pin .swarm-devices {
  right: auto;
  left: 66px;
  top: 31px;
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(21, 224, 161, 0.36);
  background: rgba(10, 14, 19, 0.82);
  color: var(--mint);
  letter-spacing: 0.02em;
}

.site-pin .swarm-coverage {
  color: var(--mint);
  border-color: rgba(21, 224, 161, 0.34);
}

.site-pin.swarm-pin.status-degraded .core {
  background: var(--amber, #f2a326);
}

.site-pin.swarm-pin.status-draft {
  opacity: 0.7;
  filter: grayscale(0.4);
}

/* ── VIZ ADAPTATIVA AL ZOOM (territorio · Approach D) ──────────────────────── */
/* GATE de la .aura: a escala de red (z < AURA_MIN_ZOOM) el bloom NO respira — el
   pin queda como un punto limpio. Sólo "respira" muy cerca (fix del blob). */
.site-pin.aura-off .aura {
  display: none;
}
.site-pin.aura-off .spoke {
  display: none;
}

/* Burbuja-cluster (mid zoom): disco con count centrado, envuelto por un anillo
   donut conic-gradient de 2 arcos (blue=seguridad / mint=retail). El conic se pinta
   inline (proporción exacta de miembros). Sin overlap (una burbuja por celda px). */
.leaflet-div-icon.nexus-cluster-icon {
  background: transparent;
  border: 0;
}
.cluster-bubble {
  position: relative;
  width: var(--cl-size);
  height: var(--cl-size);
  cursor: zoom-in;
}
.cluster-bubble .cluster-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  /* enmascara el centro → queda el anillo (donut) */
  -webkit-mask: radial-gradient(circle, transparent calc(var(--cl-r) / 2), #000 calc(var(--cl-r) / 2 + 1px));
  mask: radial-gradient(circle, transparent calc(var(--cl-r) / 2), #000 calc(var(--cl-r) / 2 + 1px));
  opacity: 0.92;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.45));
}
.cluster-bubble .cluster-disc {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--cl-r);
  height: var(--cl-r);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(5, 8, 12, 0.86);
  border: 1px solid color-mix(in srgb, var(--cl-core), transparent 50%);
  box-shadow: 0 0 18px color-mix(in srgb, var(--cl-core), transparent 64%);
}
.cluster-bubble .cluster-disc b {
  color: #f3f6f8;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  font-weight: 700;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* ── Drill-down del enjambre: chrome ──────────────────────────────────────── */
/* El botón VOLVER al territorio (visible sólo en vista "swarm"). El overlay es
   el hook donde el agente siguiente monta la cámara representativa + métricas. */
.swarm-back {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 760;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px;
  border: 1px solid rgba(21, 224, 161, 0.42);
  border-radius: var(--radius-pill);
  background: rgba(10, 14, 19, 0.86);
  color: #f3f6f8;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(6px);
}

.swarm-back:hover {
  border-color: rgba(21, 224, 161, 0.7);
  background: rgba(10, 14, 19, 0.94);
}

.swarm-back[hidden] {
  display: none;
}

/* ZONA: RIGHT-SLOT-INFERIOR (vista enjambre). El Puesto inspector se ancla al borde
   inferior derecho y crece HACIA ARRIBA con tope de altura → la nueva tarjeta de 3
   secciones SCROLLEA internamente y nunca invade el onboard-dock (anclado arriba en la
   misma columna) ni se sale del viewport. Inset unificado 16px. Ladder z: portfolio
   (540) < swarm-overlay (755) < onboard-dock (756) < coverage (757) < onboard-banner
   (758) < gc-open (765) < leaflet/zoom (~800) < modales (2000). */
.swarm-overlay {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 755;
  width: 318px;
  max-width: calc(100% - 32px);
  /* tope: media columna menos el respiro → garantiza hueco con el onboard-dock que
     vive en la mitad superior de la misma columna derecha. El scroll vive en la
     tarjeta interna (.swarm-card), que SÍ recibe puntero; el contenedor deja pasar
     los clics al mapa en su zona vacía. */
  max-height: calc(50vh - 28px);
  pointer-events: none;
}

.swarm-overlay[hidden] {
  display: none;
}

/* Tarjeta del enjambre: cámara representativa (arriba) + métricas locales. La tarjeta
   de 3 secciones (más alta) SCROLLEA dentro de su slot: max-height heredado del
   contenedor → nunca se sale del viewport ni invade el onboard-dock. */
.swarm-card {
  border: 1px solid rgba(21, 224, 161, 0.32);
  border-radius: var(--radius-lg);
  background: rgba(5, 8, 12, 0.9);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(8px);
  max-height: calc(50vh - 28px);
  overflow-y: auto;
  overscroll-behavior: contain;
  pointer-events: auto;
}

/* Cámara REPRESENTATIVA: un placeholder de vista cenital (sin imagen real),
   etiquetado, con grilla de proyección + cajas de detección simuladas. */
.swarm-cam {
  position: relative;
  height: 124px;
  background:
    radial-gradient(ellipse at 50% 120%, rgba(21, 224, 161, 0.14), transparent 60%),
    linear-gradient(160deg, #0c1612 0%, #0a120e 60%, #070d0a 100%);
  border-bottom: 1px solid rgba(21, 224, 161, 0.18);
  overflow: hidden;
}

.swarm-cam-grid {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(rgba(21, 224, 161, 0.08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(21, 224, 161, 0.08) 1px, transparent 1px);
  background-size: 22px 22px;
  /* trapecio de perspectiva: la grilla se abre hacia el fondo (proyección IPM). */
  transform: perspective(220px) rotateX(46deg) scale(1.5);
  transform-origin: 50% 100%;
  opacity: 0.7;
}

.swarm-cam-box {
  position: absolute;
  border: 1.5px solid rgba(21, 224, 161, 0.85);
  border-radius: var(--radius-sm);
  box-shadow: 0 0 10px rgba(21, 224, 161, 0.4);
  background: rgba(21, 224, 161, 0.08);
}

.swarm-cam-box.is-reserved {
  border-color: rgba(157, 146, 234, 0.9);
  box-shadow: 0 0 10px rgba(157, 146, 234, 0.45);
  background: rgba(157, 146, 234, 0.1);
}

.swarm-cam-tag {
  position: absolute;
  top: 8px;
  left: 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: #8ff3d0;
  background: rgba(0, 0, 0, 0.5);
  padding: 2px 7px;
  border-radius: var(--radius-pill);
}

.swarm-cam-sub {
  position: absolute;
  bottom: 8px;
  left: 8px;
  font-size: 10px;
  color: rgba(243, 246, 248, 0.72);
  background: rgba(0, 0, 0, 0.42);
  padding: 2px 6px;
  border-radius: var(--radius-md);
}

.swarm-meta {
  padding: 11px 13px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.swarm-meta > strong {
  font-size: 14px;
  color: #f3f6f8;
}

.swarm-meta > small {
  font-size: 11px;
  color: rgba(243, 246, 248, 0.6);
}

.swarm-note {
  margin: 5px 0 7px;
  font-size: 10.5px;
  line-height: 1.35;
  color: rgba(243, 246, 248, 0.62);
}

.swarm-metrics {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 7px 10px;
}

.swarm-metrics li {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.swarm-metrics li span {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: rgba(243, 246, 248, 0.5);
}

.swarm-metrics li b {
  font-size: 15px;
  color: #8ff3d0;
  line-height: 1;
}

.swarm-metrics li i {
  font-size: 9px;
  font-style: normal;
  color: rgba(243, 246, 248, 0.45);
}

/* Frame de SEGURIDAD (barrio guardian/con-layout): el KPI de accesos como
   chokepoint se destaca con un borde-izquierdo + tono mint, leyendo como el
   "punto de control vigilado". Tasteful, no chillón; sólo en .is-chokepoint. */
.swarm-metrics li.is-chokepoint {
  border-left: 2px solid rgba(21, 224, 161, 0.7);
  padding-left: 7px;
  margin-left: -2px;
}
.swarm-metrics li.is-chokepoint b {
  color: #15e0a1;
}

/* ── KPI-CARD (Puesto Puerto / Puesto Ciudad) · top-row glanceable ────────────
   Tarjeta de número grande con grammar de honestidad por estado. Reusa la grilla
   .swarm-metrics; el modifier cambia el tratamiento visual:
   · default (derivado real): número saturado mint, sin tratamiento de sim.
   · .is-sim (representativo): borde dasheado + número desaturado + hatch sutil.
   · .is-gated (seam real GATED): borde-izq cian (port/LPR) — dato real pero detrás
     de un gate de producto.
   · .is-roadmap (sin sensor): grisado permanente, número apagado.
   El ROJO queda reservado a must-fix-now (incidente abierto/offline), NO acá. */
.swarm-metrics li.kpi-card {
  border: 1px solid rgba(243, 246, 248, 0.08);
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md);
  background: rgba(20, 37, 51, 0.34);
  transition:
    border-color var(--dur-1) var(--ease-standard),
    transform var(--dur-1) var(--ease-standard);
}
/* glanceable big-number zone: the value reads as a headline (premium hierarchy),
   the label/chip as quiet metadata — Genetec/Verkada's headline-bold contrast. */
.swarm-metrics li.kpi-card b {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
}
.swarm-metrics li.kpi-card span {
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}
.swarm-metrics li.kpi-card:hover {
  border-color: var(--line-strong);
  transform: translateY(-1px);
}
.swarm-metrics li.kpi-card.is-sim {
  border-style: dashed;
  border-color: rgba(243, 246, 248, 0.24);
  background-image: repeating-linear-gradient(
    45deg,
    rgba(243, 246, 248, 0.03) 0,
    rgba(243, 246, 248, 0.03) 4px,
    transparent 4px,
    transparent 8px
  );
}
.swarm-metrics li.kpi-card.is-sim b {
  color: rgba(143, 243, 208, 0.5);
}
.swarm-metrics li.kpi-card.is-gated {
  border-left: 2px solid rgba(19, 196, 196, 0.8);
}
.swarm-metrics li.kpi-card.is-gated b {
  color: #13c4c4;
}
.swarm-metrics li.kpi-card.is-roadmap {
  border-style: dotted;
  border-color: rgba(147, 164, 186, 0.28);
  /* WAS opacity:.6 on the whole card — it multiplied with the rgba() alphas below
     to push the roadmap number to 2.21 and its label to 1.86 (the "barely legible"
     bug). De-emphasis now lives in the text tokens alone (dotted border keeps the
     "roadmap" read), so every glyph stays AA on the card. */
}
.swarm-metrics li.kpi-card.is-roadmap b {
  color: var(--muted); /* was rgba(147,164,186,.7) × card.6 = 2.21 → 6.45 */
}
.swarm-metrics li.kpi-card.is-roadmap span,
.swarm-metrics li.kpi-card.is-roadmap i {
  color: var(--quiet); /* was rgba(147,164,186,.55) × card.6 = 1.86 → 6.09 */
}

/* ── VIZ DE FIRMA POR PUESTO (STAGE 2 · item D) ───────────────────────────────
   El diferenciador Verkada/Sentilo: cada Puesto gana una viz compacta y premium de
   su dominio (muelle/movilidad/zona/EHS), computada de los datos REALES + etiquetada
   por honestidad. Reusa los tokens del DS (radius/space/accent) + el --accent del
   vertical (inyectado en el shell). Los estados usan la paleta semántica
   (verde/ámbar/rojo) reservando el rojo a congestión/riesgo. */
.sigviz {
  margin: var(--space-md) 0 var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid rgba(var(--accent-rgb), 0.22);
  border-radius: var(--radius-md);
  background: rgba(20, 37, 51, 0.34);
}
.sigviz-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}
.sigviz-head strong {
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--accent);
}
.sigviz-chip {
  font-size: 9px;
  letter-spacing: 0.02em;
  padding: 2px var(--space-sm);
  border-radius: var(--radius-pill);
  border: 1px solid rgba(243, 246, 248, 0.18);
  color: rgba(243, 246, 248, 0.7);
  white-space: nowrap;
}
.sigviz-chip.is-sim {
  border-style: dashed;
  border-color: rgba(61, 139, 212, 0.5);
  color: rgba(143, 197, 255, 0.86);
}
.sigviz-chip.is-gated {
  border-left: 2px solid rgba(19, 196, 196, 0.8);
  color: #6fd2dd;
}
.sigviz-chip.is-roadmap {
  border-style: dotted;
  border-color: rgba(147, 164, 186, 0.42);
  color: rgba(147, 164, 186, 0.82);
}
/* honest-empty PENDIENTE (endpoint embarcado · productor no publicó): gris punteado,
   igual que roadmap pero la copia distingue "sin datos · productor no publicó". */
.sigviz-chip.is-pending {
  border-style: dotted;
  border-color: rgba(147, 164, 186, 0.42);
  color: rgba(147, 164, 186, 0.82);
}
.sigviz-note {
  margin: var(--space-sm) 0 0;
  font-size: 9px;
  line-height: 1.4;
  color: rgba(243, 246, 248, 0.5);
}
/* honest-empty (sin feed AIS/TOS): renglón sobrio, sin dibujar un estado fabricado */
.sigviz-empty {
  padding: var(--space-sm) var(--space-md);
  border: 1px dashed rgba(147, 164, 186, 0.28);
  border-radius: var(--radius-sm);
  background: rgba(243, 246, 248, 0.03);
  font-size: 10px;
  line-height: 1.4;
  color: rgba(147, 164, 186, 0.82);
}
body[data-theme="light"] .sigviz-empty {
  color: rgba(20, 37, 51, 0.6);
}

/* PUERTO · berths (Sitios 2-6) + carriles de gate */
.sigviz-berths {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-xs);
}
.sigviz-berth {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: var(--space-sm) 2px;
  border-radius: var(--radius-sm);
  border: 1px solid rgba(243, 246, 248, 0.1);
  background: rgba(243, 246, 248, 0.04);
}
.sigviz-berth-n {
  font-size: 9.5px;
  font-weight: var(--fw-bold);
  color: rgba(243, 246, 248, 0.86);
}
.sigviz-berth-t {
  font-size: 8px;
  letter-spacing: 0.04em;
  color: rgba(243, 246, 248, 0.46);
}
.sigviz-berth.is-occupied {
  border-color: rgba(19, 196, 196, 0.7);
  background: rgba(19, 196, 196, 0.16);
}
.sigviz-berth.is-maneuver {
  border-color: rgba(242, 163, 38, 0.7);
  background: rgba(242, 163, 38, 0.14);
}
.sigviz-berth.is-free {
  border-style: dashed;
  border-color: rgba(243, 246, 248, 0.18);
}
.sigviz-lanes {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  margin-top: var(--space-sm);
}
.sigviz-lane {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-2xs) var(--space-sm);
  border-radius: var(--radius-sm);
  border-left: 2px solid rgba(19, 196, 196, 0.8);
  background: rgba(243, 246, 248, 0.03);
}
.sigviz-lane-name {
  font-size: 9.5px;
  color: rgba(243, 246, 248, 0.74);
}
.sigviz-lane-q {
  font-size: 9px;
  color: rgba(243, 246, 248, 0.5);
  white-space: nowrap;
}

/* CIUDAD · segmentos de flujo (Sentilo verde/naranja/rojo) */
.sigviz-segments {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}
.sigviz-seg {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-2xs) var(--space-sm);
  border-radius: var(--radius-sm);
  font-size: 9.5px;
  color: rgba(243, 246, 248, 0.74);
  background: rgba(243, 246, 248, 0.03);
}
.sigviz-seg-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  flex: 0 0 auto;
}
.sigviz-seg.is-free .sigviz-seg-dot {
  background: #66d39a;
  box-shadow: 0 0 8px rgba(79, 181, 138, 0.5);
}
.sigviz-seg.is-moderate .sigviz-seg-dot {
  background: #f2a326;
  box-shadow: 0 0 8px rgba(242, 163, 38, 0.5);
}
.sigviz-seg.is-congested .sigviz-seg-dot {
  background: #e06a5c;
  box-shadow: 0 0 8px rgba(224, 106, 92, 0.5);
}

/* RETAIL/DEPÓSITO · grilla de zonas (ocupación/EHS) */
.sigviz-zones {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-xs);
}
.sigviz-zone {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 28px;
  padding: var(--space-2xs);
  border-radius: var(--radius-sm);
  border: 1px solid rgba(243, 246, 248, 0.1);
}
.sigviz-zone span {
  font-size: 8.5px;
  letter-spacing: 0.02em;
  color: rgba(243, 246, 248, 0.78);
}
.sigviz-zone.is-low {
  background: rgba(61, 139, 212, 0.1);
  border-color: rgba(61, 139, 212, 0.26);
}
.sigviz-zone.is-med {
  background: rgba(61, 139, 212, 0.2);
  border-color: rgba(61, 139, 212, 0.44);
}
.sigviz-zone.is-high {
  background: rgba(61, 139, 212, 0.34);
  border-color: rgba(61, 139, 212, 0.66);
}
.sigviz-zone.is-ok {
  background: rgba(79, 181, 138, 0.16);
  border-color: rgba(79, 181, 138, 0.4);
}
.sigviz-zone.is-watch {
  background: rgba(242, 163, 38, 0.16);
  border-color: rgba(242, 163, 38, 0.44);
}
.sigviz-zone.is-risk {
  background: rgba(224, 106, 92, 0.18);
  border-color: rgba(224, 106, 92, 0.5);
}
/* AGRO · estado de cultivo por lote (proxy NDVI representativo: vigor/moderado/estrés) */
.sigviz-zone.is-vigor {
  background: rgba(79, 181, 138, 0.2);
  border-color: rgba(79, 181, 138, 0.5);
}
.sigviz-zone.is-moderate {
  background: rgba(221, 200, 96, 0.18);
  border-color: rgba(221, 200, 96, 0.46);
}
.sigviz-zone.is-stress {
  background: rgba(214, 138, 74, 0.2);
  border-color: rgba(214, 138, 74, 0.5);
}
/* AGRO · marcador de cobertura del dron (presencia real, % ROADMAP) */
.sigviz-drone {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-top: var(--space-sm);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  border: 1px dashed rgba(79, 181, 138, 0.4);
  background: rgba(79, 181, 138, 0.06);
  font-size: 8.5px;
  letter-spacing: 0.02em;
  color: rgba(243, 246, 248, 0.78);
}
.sigviz-drone b {
  margin-left: auto;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: rgba(143, 197, 255, 0.7);
}
.sigviz-drone-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(79, 181, 138, 0.85);
  box-shadow: 0 0 6px rgba(79, 181, 138, 0.6);
}
.sigviz-drone.is-absent {
  border-color: rgba(243, 246, 248, 0.16);
  background: rgba(243, 246, 248, 0.03);
  color: rgba(243, 246, 248, 0.5);
}
.sigviz-drone.is-absent .sigviz-drone-dot {
  background: rgba(243, 246, 248, 0.3);
  box-shadow: none;
}
body[data-theme="light"] .sigviz-drone {
  color: rgba(20, 37, 51, 0.72);
}

/* RETAIL · embudo footfall→aforo→cola→conversión (honesty-chipped, value:null) */
.sigviz-funnel {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-xs);
  margin-top: var(--space-sm);
}
.sigviz-step {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  border: 1px solid rgba(243, 246, 248, 0.1);
  background: rgba(243, 246, 248, 0.03);
}
.sigviz-step.is-gated {
  border-left: 2px solid rgba(19, 196, 196, 0.8);
}
.sigviz-step.is-sim {
  border-style: dashed;
  border-color: rgba(61, 139, 212, 0.4);
}
.sigviz-step-l {
  font-size: 7.5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: rgba(243, 246, 248, 0.5);
}
.sigviz-step-v {
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  color: rgba(143, 197, 255, 0.7);
  line-height: var(--lh-tight);
}

body[data-theme="light"] .sigviz {
  background: rgba(20, 37, 51, 0.04);
}
body[data-theme="light"] .sigviz-berth-n,
body[data-theme="light"] .sigviz-seg,
body[data-theme="light"] .sigviz-zone span,
body[data-theme="light"] .sigviz-lane-name {
  color: rgba(20, 37, 51, 0.82);
}
body[data-theme="light"] .sigviz-note,
body[data-theme="light"] .sigviz-berth-t,
body[data-theme="light"] .sigviz-lane-q,
body[data-theme="light"] .sigviz-step-l {
  color: rgba(20, 37, 51, 0.58);
}

.swarm-advisory {
  margin: 9px 0 0;
  font-size: 9.5px;
  letter-spacing: 0.03em;
  color: rgba(242, 163, 38, 0.82);
}

body[data-theme="light"] .swarm-card {
  background: rgba(255, 255, 255, 0.94);
  border-color: rgba(14, 122, 90, 0.3);
}

body[data-theme="light"] .swarm-cam {
  background:
    radial-gradient(ellipse at 50% 120%, rgba(14, 122, 90, 0.16), transparent 60%),
    linear-gradient(160deg, #dfeae3 0%, #d4e0d8 100%);
}

body[data-theme="light"] .swarm-meta > strong { color: #0c140e; }
body[data-theme="light"] .swarm-meta > small,
body[data-theme="light"] .swarm-note { color: rgba(20, 37, 51, 0.66); }
body[data-theme="light"] .swarm-metrics li b { color: #0a7f5f; }
body[data-theme="light"] .swarm-cam-tag { color: #0a7f5f; background: rgba(255, 255, 255, 0.8); }

body[data-theme="light"] .swarm-back {
  background: rgba(255, 255, 255, 0.9);
  color: #0c140e;
}

.map-link {
  position: absolute;
  height: 2px;
  transform-origin: left center;
  background: linear-gradient(90deg, rgba(21, 224, 161, 0.0), rgba(21, 224, 161, 0.48), rgba(242, 163, 38, 0.0));
  opacity: 0.42;
  pointer-events: none;
}

.selection-zone {
  position: absolute;
  z-index: 5;
  border: 1px solid rgba(242, 163, 38, 0.82);
  background: rgba(242, 163, 38, 0.12);
  box-shadow: 0 0 34px rgba(242, 163, 38, 0.22);
  pointer-events: none;
}

.command-palette,
.right-dock,
.toast {
  position: absolute;
  z-index: 10;
  border: 1px solid var(--line);
  background: var(--dock);
  box-shadow: var(--elev-3);
  backdrop-filter: blur(18px);
}

/* P6 · DC bottom band — the mission ribbon and the contracts strip carry NO
   container chrome of their own: mission tiles float on the field as individual
   dock cards (see .mission-tile) and the api strip is a bare mono line. */
.mission-ribbon,
.api-strip {
  position: absolute;
  z-index: 10;
}

body[data-theme="light"] .command-palette,
body[data-theme="light"] .right-dock,
body[data-theme="light"] .toast,
body[data-theme="light"] .auth-panel {
  background: var(--dock);
}

.command-palette {
  left: 84px;
  bottom: 18px;
  /* DC band: fixed 340px card; the mission ribbon takes the rest of the row
     (ribbon left: 436px = 84 + 340 + 12px gap). */
  width: 340px;
  border-radius: var(--radius-lg);
  padding: var(--space-md);
}

.command-palette > div {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  margin-top: 7px;
}

.command-palette input {
  min-width: 0;
  height: 38px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-input);
  color: var(--ink);
  padding: 0 var(--space-md);
  outline: none;
  transition: border-color var(--dur-1) var(--ease-standard);
}

body[data-theme="light"] .command-palette input,
body[data-theme="light"] .onboard-form input,
body[data-theme="light"] .onboard-form select,
body[data-theme="light"] .semantic-form input,
body[data-theme="light"] .deploy-form input,
body[data-theme="light"] .deploy-form select,
body[data-theme="light"] .site-edit-form input,
body[data-theme="light"] .site-edit-form select,
body[data-theme="light"] .auth-panel input {
  background: rgba(255, 255, 255, 0.78);
}

.command-palette input:focus {
  border-color: var(--accent-line);
}

.command-palette button,
.right-dock footer button,
.deploy-form button {
  height: 38px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--ink-2);
  padding: 0 var(--space-md);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition:
    background var(--dur-1) var(--ease-standard),
    border-color var(--dur-1) var(--ease-standard),
    color var(--dur-1) var(--ease-standard);
}

.command-palette p {
  margin: 9px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.mission-ribbon {
  /* DC bottom band: one row beside the 340px command palette, ending 12px
     before the right-dock column (dock is right:16 + up to 420 wide → 448). */
  left: 436px;
  right: 448px;
  bottom: 18px;
  display: flex;
  align-items: flex-end;
  gap: 10px;
  padding: 2px 0;
  overflow-x: auto;
}

.mission-tile {
  /* DC: each tile is its own floating dock card on the field. */
  width: 216px;
  flex: none;
  text-align: left;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--dock);
  box-shadow: var(--elev-3);
  backdrop-filter: blur(14px);
  color: var(--ink);
  padding: 12px 14px;
  cursor: pointer;
  transition:
    background var(--dur-1) var(--ease-standard),
    border-color var(--dur-1) var(--ease-standard),
    transform var(--dur-1) var(--ease-standard);
}

body[data-theme="light"] .section,
body[data-theme="light"] .node-card,
body[data-theme="light"] .evidence-card,
body[data-theme="light"] .media-card,
body[data-theme="light"] .semantic-card,
body[data-theme="light"] .product-tile,
body[data-theme="light"] .field-card,
body[data-theme="light"] .measurement-card,
body[data-theme="light"] .mission-handoff-summary div,
body[data-theme="light"] .blindspot-row,
body[data-theme="light"] .ptz-approval,
body[data-theme="light"] .mission-order,
body[data-theme="light"] .product-empty,
body[data-theme="light"] .edit-note,
body[data-theme="light"] .empty-inline {
  background: rgba(255, 255, 255, 0.68);
}

.mission-tile.active {
  border-color: var(--action-line);
  background: var(--action-fill);
  box-shadow: inset 2px 0 0 var(--action);
}

.mission-tile small {
  display: block;
  color: var(--amber); /* misiones = ACCIÓN (DC invariant) */
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* DC grammar split: an UNSCORED suggestion (backend score=null / active-product
   advisory) is DERIVED territory → green accent; scored advisory/gated previews
   keep the amber ACTION grammar above. */
.mission-tile.suggest small {
  color: var(--accent);
}

.mission-tile.suggest.active {
  border-color: var(--accent-line);
  background: var(--accent-fill);
  box-shadow: inset 2px 0 0 var(--accent);
}

.mission-tile strong {
  display: block;
  margin-top: 5px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: var(--fw-semibold);
}

.mission-tile span {
  display: block;
  margin-top: 6px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}

/* DE-GREEDY · el right-dock ya NO abarca el alto completo (era top:18 → bottom:18). Se
   ancla arriba y se acota a 60vh → su mitad inferior derecha queda LIBRE: el #map-space
   full-bleed que vive debajo "crece" perceptualmente (la franja opaca se achica) y la
   leyenda del territorio gana una esquina abajo-derecha probadamente libre. El contenido
   sigue scrolleando dentro del dock (overflow:hidden + flex). */
.right-dock {
  top: 18px;
  right: 16px;
  width: min(420px, calc(100vw - 32px));
  height: min(80vh, calc(100% - 36px));
  min-height: 0;
  display: flex;
  flex-direction: column;
  max-height: min(80vh, calc(100% - 36px));
  overflow: hidden;
  border-radius: var(--radius-lg);
}

.right-dock header {
  flex: 0 0 auto;
  min-height: 0;
  padding: var(--space-lg) 17px var(--space-md);
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--surface-2), transparent);
}

.right-dock header small {
  display: block;
  color: var(--accent); /* DC: the kicker reads in the (vertical-aware) accent */
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.right-dock h1 {
  margin: var(--space-sm) 0 0;
  font-family: var(--font-display); /* DC: dock titles are Space Grotesk */
  font-size: clamp(var(--fs-xl), 2.2vw, var(--fs-2xl));
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

.right-dock p {
  margin: var(--space-sm) 0 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
  overflow-wrap: anywhere;
}

.tabs {
  flex: 0 0 auto;
  min-height: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(86px, 1fr);
  gap: 6px;
  padding: 10px 12px;
  overflow-x: auto;
  overflow-y: hidden;
  border-bottom: 1px solid var(--line);
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}

.tabs button {
  min-width: 0;
  padding: 0 8px;
  overflow: hidden;
  font-size: 13px;
  text-overflow: ellipsis;
}

.dock-pane {
  flex: 1 1 0;
  min-height: 180px;
  overflow: auto;
  padding: 14px 15px max(20px, env(safe-area-inset-bottom));
  display: grid;
  align-content: start;
  gap: 12px;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  -webkit-overflow-scrolling: touch;
}

.section {
  min-width: 0;
  border: 1px solid var(--line);
  /* DC card grammar: the accent spine on the left edge (vertical-aware via
     --accent, set per console by applyConsoleAccent). */
  border-left: 2px solid var(--accent-line);
  border-radius: var(--radius-md);
  overflow: visible;
  background: var(--surface-1);
}

.section header {
  min-height: 38px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: 0 var(--space-md);
  border-bottom: 1px solid var(--line);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  background: var(--surface-3);
}

.section header b {
  min-width: 0;
  text-align: right;
  overflow-wrap: anywhere;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--accent);
}

.metrics {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.metric {
  min-height: 78px;
  padding: 12px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.metric:nth-child(2n) {
  border-right: 0;
}

.metric:nth-last-child(-n + 2) {
  border-bottom: 0;
}

.metric span {
  color: var(--quiet);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.metric strong {
  display: block;
  margin-top: 5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 22px;
  line-height: 1;
}

.metric small {
  display: block;
  margin-top: 6px;
  color: var(--muted);
  font-size: 11px;
}

.rows {
  display: grid;
  gap: 8px;
  padding: 11px;
}

.row {
  display: grid;
  grid-template-columns: auto minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: 9px;
  align-items: start;
  min-height: 24px;
  min-width: 0;
}

.row i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--mint);
  box-shadow: 0 0 12px currentColor;
}

.row strong {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 12px;
}

.row span {
  min-width: 0;
  max-width: none;
  overflow-wrap: anywhere;
  color: var(--quiet);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  text-align: right;
}

.row.block i,
.row.absent i,
.row.faulty i,
.row.contradictory i {
  background: var(--red);
}

.row.warn i,
.row.stale i,
.row.degraded i,
.row.human i {
  background: var(--amber);
}

.row.ok i,
.row.healthy i,
.row.verified i,
.row.present i {
  background: var(--green);
}

.mission-order {
  display: grid;
  gap: 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.16);
  padding: 8px;
}

.mission-order.ok {
  border-color: rgba(21, 224, 161, 0.38);
}

.mission-order.warn {
  border-color: rgba(242, 163, 38, 0.38);
}

.mission-order.block {
  border-color: rgba(255, 109, 104, 0.4);
}

.mission-order small {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}

.mission-order-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px;
}

.mission-order-actions button {
  min-height: 30px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.045);
  cursor: pointer;
  font-size: 11px;
}

.mission-order-actions button:disabled {
  color: var(--quiet);
  cursor: not-allowed;
}

.bar-row {
  padding: 12px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 10px;
  align-items: center;
}

.bar-row strong,
.bar-row span {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
}

.bar {
  height: 7px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}

.bar i {
  display: block;
  width: var(--w);
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--mint), var(--amber));
}

.badges {
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
  padding: 0 12px 12px;
}

.badge {
  min-height: 24px;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  color: var(--ink-2);
  padding: var(--space-2xs) var(--space-sm);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
}

.badge.ok {
  color: var(--mint);
  border-color: rgba(21, 224, 161, 0.42);
  background: rgba(21, 224, 161, 0.09);
}

.badge.warn {
  color: var(--amber);
  border-color: rgba(242, 163, 38, 0.44);
  background: rgba(242, 163, 38, 0.09);
}

.badge.block {
  color: var(--red);
  border-color: rgba(255, 109, 104, 0.44);
  background: rgba(255, 109, 104, 0.09);
}

.product-target {
  display: grid;
  gap: 5px;
  padding: 12px;
  border-top: 1px solid var(--line);
}

.product-target strong {
  font-size: 14px;
}

.product-target span {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}

.product-focus {
  overflow: hidden;
}

.focus-hero {
  display: grid;
  gap: 5px;
  padding: 12px;
  border-top: 1px solid var(--line);
  background: linear-gradient(90deg, rgba(21, 224, 161, 0.08), rgba(242, 163, 38, 0.04));
}

.focus-hero strong {
  color: var(--ink);
  font-size: 14px;
}

.focus-hero span {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}

.focus-actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: 8px;
  padding: 10px;
  border-top: 1px solid var(--line);
}

.focus-actions button {
  min-height: 34px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.045);
  cursor: pointer;
}

.focus-actions button:disabled {
  color: var(--quiet);
  cursor: not-allowed;
}

.focus-actions .focus-open {
  border-color: rgba(21, 224, 161, 0.45);
  background: rgba(21, 224, 161, 0.12);
}

.site-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  padding: 10px;
  border-top: 1px solid var(--line);
}

.site-actions button {
  min-height: 34px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.045);
  cursor: pointer;
}

.site-actions button:disabled {
  color: var(--quiet);
  cursor: not-allowed;
}

.site-actions .danger {
  color: var(--red);
  border-color: rgba(255, 109, 104, 0.42);
  background: rgba(255, 109, 104, 0.08);
}

.products-section {
  overflow: hidden;
}

.product-grid {
  display: grid;
  gap: 10px;
  padding: 10px;
}

.product-tile {
  display: grid;
  gap: 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.035);
  padding: 11px;
}

.product-tile.active {
  border-color: rgba(21, 224, 161, 0.5);
  background: rgba(21, 224, 161, 0.08);
}

.product-tile.block {
  border-color: rgba(255, 109, 104, 0.46);
}

.product-tile.warn {
  border-color: rgba(242, 163, 38, 0.42);
}

.product-tile.disabled {
  opacity: 0.62;
}

.product-tile header {
  display: grid;
  gap: 3px;
}

.product-tile header small,
.product-tile em,
.product-smoke {
  color: var(--quiet);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  font-style: normal;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.product-tile header strong {
  color: var(--ink);
  font-size: 14px;
}

.product-tile p {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.38;
}

.product-meta,
.product-routes {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.product-meta span,
.product-routes code {
  max-width: 100%;
  min-height: 23px;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  color: var(--muted);
  background: rgba(0, 0, 0, 0.18);
  padding: 3px 7px;
  font-size: 11px;
  white-space: normal;
  overflow-wrap: anywhere;
}

.product-routes code {
  border-radius: var(--radius-md);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.product-lifecycle {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 5px;
}

.product-lifecycle span {
  min-width: 0;
  min-height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--quiet);
  background: rgba(0, 0, 0, 0.16);
  padding: 4px 5px;
  font-size: 10px;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

.product-lifecycle span i {
  width: 6px;
  height: 6px;
  flex: 0 0 auto;
  border-radius: var(--radius-pill);
  background: currentColor;
}

.product-lifecycle span.ok {
  color: var(--green);
  border-color: rgba(21, 224, 161, 0.34);
  background: rgba(21, 224, 161, 0.08);
}

.product-lifecycle span.wait {
  color: var(--amber);
  border-color: rgba(242, 163, 38, 0.22);
}

.product-runtime {
  display: grid;
  gap: 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.16);
  padding: 8px;
}

.product-runtime b {
  color: var(--ink);
  font-size: 12px;
  text-transform: uppercase;
}

.product-runtime span,
.product-runtime small {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.3;
}

.product-runtime small {
  color: var(--quiet);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.product-op-result {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.18);
  overflow: hidden;
}

.product-op-result.ok {
  border-color: rgba(21, 224, 161, 0.42);
}

.product-op-result.warn {
  border-color: rgba(242, 163, 38, 0.4);
}

.product-op-result.block {
  border-color: rgba(255, 109, 104, 0.44);
}

.product-op-result summary {
  min-height: 32px;
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: 8px;
  align-items: center;
  cursor: pointer;
  list-style: none;
  padding: 7px 8px;
}

.product-op-result summary::-webkit-details-marker {
  display: none;
}

.product-op-result summary b,
.product-op-result summary span {
  overflow-wrap: anywhere;
  font-size: 11px;
}

.product-op-result summary b {
  color: var(--ink);
  text-transform: uppercase;
}

.product-op-result summary span {
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.product-op-result pre {
  max-height: 150px;
  overflow: auto;
  margin: 0;
  border-top: 1px solid var(--line);
  color: var(--muted);
  background: rgba(0, 0, 0, 0.18);
  padding: 8px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: 10px;
  line-height: 1.35;
}

.product-ops {
  min-width: 0;
  display: grid;
  gap: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 8px;
  background: rgba(0, 0, 0, 0.18);
}

.product-ops.ok {
  border-color: rgba(21, 224, 161, 0.35);
}

.product-ops.warn {
  border-color: rgba(242, 163, 38, 0.35);
}

.product-ops.block {
  border-color: rgba(255, 109, 104, 0.4);
}

.product-ops header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}

.product-ops header span,
.product-ops header b {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 11px;
}

.product-ops header span {
  color: var(--muted);
  text-transform: uppercase;
}

.product-ops header b {
  color: var(--ink);
}

.product-ops-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}

.product-ops-grid div {
  min-width: 0;
  display: grid;
  gap: 2px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: var(--radius-md);
  padding: 6px;
}

.product-ops-grid span,
.product-ops-grid small,
.product-ops-status span,
.product-deadletter span,
.product-deadletter small {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 10px;
}

.product-ops-grid span,
.product-ops-grid small,
.product-ops-status span,
.product-deadletter small {
  color: var(--muted);
}

.product-ops-grid strong {
  color: var(--ink);
  font-size: 14px;
}

.product-ops-status {
  display: grid;
  gap: 3px;
}

.product-ops-actions,
.product-deadletter div {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.product-deadletters {
  display: grid;
  gap: 6px;
}

.product-deadletter {
  min-width: 0;
  display: grid;
  gap: 5px;
  border-top: 1px solid var(--line);
  padding-top: 6px;
}

.product-deadletter span {
  color: var(--ink);
}

.product-deadletter button.danger {
  border-color: rgba(255, 109, 104, 0.42);
}

.gateway-ops {
  min-width: 0;
  display: grid;
  gap: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 8px;
  background: rgba(0, 0, 0, 0.18);
}

.gateway-ops.ok {
  border-color: rgba(21, 224, 161, 0.35);
}

.gateway-ops.warn {
  border-color: rgba(242, 163, 38, 0.35);
}

.gateway-ops.block,
.gateway-result.block {
  border-color: rgba(255, 109, 104, 0.42);
}

.gateway-ops header,
.gateway-actions {
  min-width: 0;
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
}

.gateway-actions {
  flex-wrap: wrap;
}

.gateway-actions button {
  min-width: 0;
  flex: 1 1 112px;
}

.gateway-ops header span,
.gateway-ops header b,
.gateway-field span,
.gateway-result b,
.gateway-result span,
.gateway-result small,
.gateway-mappings-editor summary b,
.gateway-mappings-editor summary span {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 11px;
}

.gateway-ops header span,
.gateway-field span,
.gateway-result span,
.gateway-result small,
.gateway-mappings-editor summary span {
  color: var(--muted);
}

.gateway-ops header span,
.gateway-field span {
  text-transform: uppercase;
}

.gateway-ops header b,
.gateway-result b,
.gateway-mappings-editor summary b {
  color: var(--ink);
}

.gateway-ops-grid {
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}

.gateway-ops-grid div {
  min-width: 0;
  display: grid;
  gap: 2px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: var(--radius-md);
  padding: 6px;
}

.gateway-ops-grid span,
.gateway-ops-grid strong {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 10px;
}

.gateway-ops-grid span {
  color: var(--muted);
}

.gateway-ops-grid strong {
  color: var(--ink);
}

.gateway-field {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.gateway-field select,
.gateway-field textarea,
.gateway-mappings-editor textarea {
  min-width: 0;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.22);
  color: var(--ink);
  padding: 7px;
  font: 10px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;
}

.gateway-field textarea {
  min-height: 150px;
  max-height: 230px;
  resize: vertical;
}

.gateway-mappings-editor textarea {
  min-height: 180px;
  max-height: 280px;
  resize: vertical;
}

.gateway-result {
  min-width: 0;
  display: grid;
  gap: 3px;
  border: 1px solid rgba(21, 224, 161, 0.35);
  border-radius: var(--radius-md);
  padding: 7px;
}

.gateway-mappings-editor {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 7px;
}

.gateway-mappings-editor summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 8px;
  cursor: pointer;
}

.gateway-mappings-editor button {
  margin-top: 7px;
  width: 100%;
}

.product-smoke {
  border-left: 2px solid rgba(242, 163, 38, 0.55);
  padding-left: 8px;
  line-height: 1.35;
}

.product-tile footer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(92px, auto);
  gap: 7px;
}

.product-tile button {
  min-height: 33px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
  cursor: pointer;
}

.product-tile button:disabled {
  cursor: not-allowed;
  color: var(--quiet);
}

.product-tile .product-action {
  border-color: rgba(21, 224, 161, 0.52);
  background: rgba(21, 224, 161, 0.13);
}

.product-tile .product-op {
  border-color: rgba(242, 163, 38, 0.38);
}

.product-empty {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--muted);
  padding: 12px;
}

.node-grid,
.evidence-list,
.media-grid,
.semantic-list {
  min-width: 0;
  display: grid;
  gap: 10px;
  padding: 10px;
}

.node-card,
.evidence-card,
.media-card,
.semantic-card {
  min-width: 0;
  display: grid;
  gap: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.035);
  padding: 10px;
}

.node-card.ok,
.evidence-card.ok,
.evidence-card.verified,
.media-card.ok,
.semantic-card.ok {
  border-color: rgba(21, 224, 161, 0.42);
}

.node-card.warn,
.evidence-card.warn,
.media-card.warn,
.semantic-card.warn {
  border-color: rgba(242, 163, 38, 0.38);
}

.node-card.block,
.evidence-card.block {
  border-color: rgba(255, 109, 104, 0.44);
}

.node-card header,
.evidence-card header,
.media-card header,
.semantic-card header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  color: var(--quiet);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.node-card strong,
.evidence-card strong,
.media-card strong,
.semantic-card strong {
  min-width: 0;
  overflow-wrap: anywhere;
  color: var(--ink);
  font-size: 13px;
}

.node-card small,
.evidence-card small,
.media-card small,
.semantic-card small {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.node-card button,
.media-card button,
.media-actions button,
.semantic-card button,
.onboard-form button,
.semantic-form button,
.compute-form > button {
  min-height: 34px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.045);
  line-height: 1.2;
  padding: 0 10px;
  cursor: pointer;
}

.node-card button:disabled,
.media-card button:disabled,
.media-actions button:disabled {
  color: var(--quiet);
  cursor: not-allowed;
}

/* ── KF1 · Cartera multi-sitio (client-side aggregation of saved nodes) ─────────
   Differentiated per-node states (vivo / sin conexión / requiere login / consultando);
   the roll-up sums ONLY reporting nodes. Theme-aware via the shared --em-* tokens. */
.section.cartera header b {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--ink-2);
}
.cartera-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 10px 0;
}
.cartera-updated {
  color: var(--quiet);
  font-size: 11px;
}
.cartera-refresh {
  min-height: 30px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
  padding: 0 12px;
  cursor: pointer;
}
.cartera-refresh:disabled {
  color: var(--quiet);
  cursor: progress;
}
.cartera-grid {
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
  padding: 10px;
}
.cartera-card {
  min-width: 0;
  display: grid;
  gap: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.035);
  padding: 10px;
  align-content: start;
}
.cartera-card.c-ok {
  border-color: rgba(21, 224, 161, 0.42);
}
.cartera-card.c-auth {
  border-color: rgba(242, 179, 60, 0.42);
}
.cartera-card.c-offline {
  border-color: rgba(229, 72, 77, 0.44);
}
.cartera-card.c-pending {
  border-color: var(--line-strong);
}
.cartera-card.is-connected {
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
.cartera-card header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.cartera-card header strong {
  min-width: 0;
  overflow-wrap: anywhere;
  color: var(--ink);
  font-size: 13px;
}
.cartera-host {
  color: var(--muted);
  font-size: 11px;
  overflow-wrap: anywhere;
}
.cartera-badge {
  color: var(--mint);
  font-weight: 600;
}
.cartera-chip {
  flex: none;
  border-radius: var(--radius-pill);
  padding: 2px 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
  border: 1px solid var(--line);
  color: var(--ink-2);
  white-space: nowrap;
}
.cartera-chip-ok {
  color: var(--mint);
  border-color: rgba(21, 224, 161, 0.5);
  background: rgba(21, 224, 161, 0.1);
}
.cartera-chip-warn {
  color: var(--amber);
  border-color: rgba(242, 179, 60, 0.5);
  background: rgba(242, 179, 60, 0.1);
}
.cartera-chip-block {
  color: var(--red);
  border-color: rgba(229, 72, 77, 0.5);
  background: rgba(229, 72, 77, 0.1);
}
.cartera-chip-pending {
  color: var(--quiet);
}
.cartera-rows {
  display: grid;
  gap: 4px;
}
.cartera-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
}
.cartera-row span {
  color: var(--muted);
}
.cartera-row strong {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
  overflow-wrap: anywhere;
}
.cartera-row.warn strong {
  color: var(--amber);
}
.cartera-reason {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.cartera-skeleton {
  height: 40px;
  border-radius: var(--radius-sm);
  background: linear-gradient(100deg, rgba(255, 255, 255, 0.04) 30%, rgba(255, 255, 255, 0.09) 50%, rgba(255, 255, 255, 0.04) 70%);
  background-size: 200% 100%;
  animation: cartera-shimmer 1.4s ease-in-out infinite;
}
@keyframes cartera-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}
.cartera-actions {
  display: flex;
  gap: 8px;
}
.cartera-connect {
  flex: 1;
  min-height: 32px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
  padding: 0 10px;
  cursor: pointer;
}
.cartera-connect:disabled {
  color: var(--quiet);
  cursor: default;
}
.cartera-retry {
  flex: none;
  min-height: 32px;
  min-width: 34px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
  cursor: pointer;
}
.cartera-note {
  margin: 0;
  padding: 4px 10px 2px;
  color: var(--quiet);
  font-size: 11px;
  line-height: 1.4;
}
.cartera-refresh:focus-visible,
.cartera-connect:focus-visible,
.cartera-retry:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
@media (prefers-reduced-motion: reduce) {
  .cartera-skeleton { animation: none; }
}

.media-console {
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(220px, 0.75fr);
  gap: 10px;
  padding: 10px;
}

.media-viewer {
  min-width: 0;
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: #07110f;
  aspect-ratio: 16 / 9;
}

.media-viewer.live {
  border-color: rgba(21, 224, 161, 0.48);
}

.media-viewer.block {
  border-color: rgba(255, 109, 104, 0.5);
}

.media-viewer canvas {
  width: 100%;
  height: 100%;
  display: block;
}

.media-viewer-overlay {
  position: absolute;
  left: 10px;
  right: 10px;
  top: 10px;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  pointer-events: none;
  color: var(--ink);
  font-size: 11px;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.7);
}

.media-viewer-overlay strong,
.media-viewer-overlay span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.media-inspector {
  min-width: 0;
  display: grid;
  align-content: start;
  gap: 10px;
}

.media-stats {
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.media-stats div {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 8px;
  background: rgba(255, 255, 255, 0.035);
}

.media-stats span {
  display: block;
  color: var(--muted);
  font-size: 10px;
  text-transform: uppercase;
}

.media-stats strong {
  display: block;
  margin-top: 4px;
  color: var(--ink);
  font-size: 13px;
  overflow-wrap: anywhere;
}

.media-actions {
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.media-actions button {
  flex: 1 1 96px;
  min-width: 0;
  padding: 0 10px;
}

.media-grid-compact {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.media-card.selected {
  outline: 1px solid rgba(61, 139, 212, 0.55);
  outline-offset: -1px;
}

.evidence-card pre {
  max-height: 135px;
  overflow: auto;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--muted);
  background: rgba(0, 0, 0, 0.18);
  padding: 8px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: 10px;
  line-height: 1.35;
}

.incident-queue {
  min-width: 0;
}

.incident-metrics .metric {
  min-height: 68px;
}

.incident-toolbar {
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(105px, 0.8fr) minmax(0, 1.2fr) auto;
  gap: 8px;
  align-items: end;
  border-top: 1px solid var(--line);
  padding: 10px;
}

.incident-toolbar label {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.incident-toolbar label span {
  color: var(--muted);
  font-size: 10px;
  text-transform: uppercase;
}

.incident-toolbar select,
.incident-toolbar input,
.incident-toolbar button,
.incident-card button,
.incident-actions button {
  min-width: 0;
  min-height: 32px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
}

.incident-toolbar input,
.incident-toolbar select {
  width: 100%;
  padding: 0 8px;
}

.incident-layout {
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(210px, 0.9fr) minmax(0, 1.1fr);
  gap: 10px;
  padding: 10px;
}

.incident-list {
  min-width: 0;
  display: grid;
  align-content: start;
  gap: 8px;
  max-height: 560px;
  overflow: auto;
}

.incident-card {
  padding: 9px;
}

.incident-card.selected {
  outline: 1px solid rgba(21, 224, 161, 0.72);
  background: rgba(21, 224, 161, 0.07);
}

.incident-detail {
  min-width: 0;
  display: grid;
  align-content: start;
  gap: 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.16);
  padding: 10px;
}

.incident-detail.open {
  border-color: rgba(242, 163, 38, 0.42);
}

.incident-detail.acknowledged,
.incident-detail.resolved {
  border-color: rgba(21, 224, 161, 0.38);
}

.incident-detail.empty {
  color: var(--muted);
}

.incident-detail header,
.incident-actions {
  min-width: 0;
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
}

.incident-detail header span,
.incident-detail header b {
  min-width: 0;
  overflow-wrap: anywhere;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
}

.incident-detail header span {
  color: var(--muted);
  text-transform: uppercase;
}

.incident-detail-grid {
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
}

.incident-detail-grid div {
  min-width: 0;
  display: grid;
  gap: 2px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: var(--radius-md);
  padding: 6px;
}

.incident-detail-grid span,
.incident-detail-grid strong {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 10px;
}

.incident-detail-grid span {
  color: var(--muted);
  text-transform: uppercase;
}

.incident-actions {
  justify-content: start;
  flex-wrap: wrap;
}

.incident-actions button {
  padding: 0 10px;
  cursor: pointer;
}

.incident-actions button:disabled {
  color: var(--quiet);
  cursor: not-allowed;
}

.incident-actions .danger {
  border-color: rgba(255, 109, 104, 0.44);
}

.incident-detail pre {
  max-height: 320px;
  overflow: auto;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.22);
  color: var(--muted);
  padding: 8px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font: 10px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;
}

.onboard-form,
.semantic-form,
.compute-form {
  display: grid;
  gap: 10px;
  padding: 11px;
}

.onboard-form label,
.semantic-form label,
.compute-form label {
  display: grid;
  gap: 6px;
}

.onboard-form label span,
.semantic-form label span,
.compute-form label span {
  color: var(--quiet);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.onboard-form input,
.onboard-form select,
.semantic-form input,
.compute-form input,
.compute-form select {
  width: 100%;
  height: 36px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.24);
  color: var(--ink);
  padding: 0 10px;
  outline: none;
}

/* keyboard focus ring (a11y): the base rule kills the UA outline, so restore a
   visible accent ring on :focus-visible (matches the command-palette house style). */
.onboard-form input:focus-visible,
.onboard-form select:focus-visible,
.semantic-form input:focus-visible,
.compute-form input:focus-visible,
.compute-form select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent-line);
}

/* COMPUTE ONBOARDING (tab Nodos) — paneles de 3 pasos. Reusa .section/.rows/
   .metrics; sólo añade: una pista honesta, una nota, un subtítulo de sección y
   filas con botones de acción inline (4ª columna sin romper el grid de 3). */
.compute-hint {
  margin: 0;
  padding: 0 11px;
  color: var(--quiet);
  font-size: 11px;
  line-height: 1.5;
}

.compute-note {
  margin: 0;
  padding: 8px 11px 11px;
  color: var(--quiet);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  line-height: 1.5;
}

.section header.sub {
  margin-top: 6px;
  opacity: 0.92;
}

/* Filas accionables: id · estado · botón(es). El grid base es de 3 columnas; en
   estos paneles la fila puede llevar uno/dos botones de acción al final. */
.compute-step .rows .row,
.cameras-step .rows .row {
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
}

.compute-step .row button,
.cameras-step .row button {
  height: 26px;
  padding: 0 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.24);
  color: var(--ink);
  font-size: 11px;
  cursor: pointer;
  white-space: nowrap;
}

.compute-step .row button:hover,
.cameras-step .row button:hover {
  border-color: var(--mint);
}

.distribution-step button#compute-distribution-refresh {
  margin: 0 11px 11px;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.24);
  color: var(--ink);
  font-size: 12px;
  cursor: pointer;
}

.distribution-step button#compute-distribution-refresh:hover {
  border-color: var(--mint);
}

.deploy-form {
  display: grid;
  gap: 10px;
  padding: 11px;
}

.site-edit-form {
  display: grid;
  gap: 10px;
  padding: 11px;
}

.form-grid {
  display: grid;
  gap: 9px;
}

.form-grid.two {
  grid-template-columns: repeat(auto-fit, minmax(136px, 1fr));
}

.form-grid label {
  display: grid;
  gap: 6px;
}

.form-grid label span {
  color: var(--quiet);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.deploy-form select,
.deploy-form input,
.site-edit-form select,
.site-edit-form input {
  width: 100%;
  height: 36px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.24);
  color: var(--ink);
  padding: 0 10px;
  outline: none;
}

/* keyboard focus ring (a11y): restore a visible accent ring on :focus-visible. */
.deploy-form select:focus-visible,
.deploy-form input:focus-visible,
.site-edit-form select:focus-visible,
.site-edit-form input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent-line);
}

.site-edit-form input[type="checkbox"] {
  width: 14px;
  height: 14px;
  accent-color: var(--mint);
}

.check-line {
  min-height: 32px;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 12px;
}

.edit-note,
.empty-inline {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--muted);
  background: rgba(0, 0, 0, 0.16);
  padding: 8px;
  font-size: 12px;
  line-height: 1.35;
}

.edit-note.ok {
  color: var(--mint);
  border-color: rgba(21, 224, 161, 0.36);
  background: rgba(21, 224, 161, 0.08);
}

.edit-note.warn {
  color: var(--amber);
  border-color: rgba(242, 163, 38, 0.34);
}

.product-checkboxes,
.node-checkboxes {
  display: grid;
  gap: 7px;
}

.check-pill {
  min-height: 32px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 8px;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.035);
  color: var(--muted);
  padding: 7px 8px;
  font-size: 12px;
}

.check-pill span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.site-edit-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.site-edit-actions button {
  min-height: 36px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.045);
  cursor: pointer;
}

.site-edit-actions button.primary {
  border-color: rgba(21, 224, 161, 0.52);
  background: rgba(21, 224, 161, 0.14);
}

.space-panel,
.space-readiness,
.space-intent-builder,
.space-intent-result,
.field-panel,
.blindspot-panel,
.ptz-panel,
.measurement-panel,
.mission-handoff-panel {
  scroll-margin-top: 10px;
}

.space-actions {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  align-items: center;
  margin-top: 10px;
}

.space-actions button {
  min-height: 36px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.045);
  line-height: 1.2;
  padding: 0 10px;
  cursor: pointer;
}

.space-actions button.primary {
  border-color: rgba(21, 224, 161, 0.52);
  background: rgba(21, 224, 161, 0.14);
}

.space-actions button:disabled,
.ptz-approval input:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

.space-actions span,
.space-error,
.ptz-execute-status {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}

.space-error {
  margin: 10px 0 0;
  color: #ffb5a8;
}

.evidence-pack-panel .space-actions {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.evidence-pack-panel .space-actions span {
  grid-column: 1 / -1;
}

.space-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0;
}

.space-chip-list span {
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 4px 8px;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.035);
  font-size: 12px;
}

.field-grid,
.measurement-grid,
.mission-handoff-summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 10px;
}

.field-card,
.measurement-card,
.mission-handoff-summary div {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.035);
  padding: 9px;
  min-width: 0;
}

.field-card span,
.measurement-row span,
.mission-handoff-summary span {
  display: block;
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.field-card strong,
.mission-handoff-summary strong {
  display: block;
  margin-top: 4px;
  overflow-wrap: anywhere;
  font-size: 13px;
}

.field-card strong,
.measurement-row strong,
.mission-handoff-summary strong,
.blindspot-main strong,
.blindspot-main small,
.blindspot-metrics,
.blindspot-action {
  word-break: break-word;
}

.blindspot-list {
  display: grid;
  gap: 8px;
}

.blindspot-row {
  display: grid;
  grid-template-columns: 40px minmax(0, 1.4fr) minmax(0, 1.7fr);
  gap: 8px;
  align-items: center;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.035);
  color: var(--ink);
  padding: 8px;
  text-align: left;
}

.blindspot-row.selected {
  border-color: rgba(21, 224, 161, 0.6);
  background: rgba(21, 224, 161, 0.1);
}

.blindspot-rank {
  color: var(--muted);
  font-size: 12px;
}

.blindspot-main,
.blindspot-metrics,
.blindspot-action {
  min-width: 0;
  overflow-wrap: anywhere;
}

.blindspot-main strong,
.blindspot-main small {
  display: block;
}

.blindspot-main small,
.blindspot-metrics,
.blindspot-action {
  color: var(--muted);
  font-size: 12px;
}

.blindspot-metrics.ok {
  color: #9ce7b8;
}

.blindspot-metrics.warn {
  color: #ffd48c;
}

.blindspot-metrics.block {
  color: #ffb5a8;
}

.ptz-approval {
  display: grid;
  gap: 6px;
  margin-top: 10px;
  padding: 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.035);
}

.ptz-approval label {
  display: flex;
  gap: 8px;
  align-items: center;
}

.ptz-approval p {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
}

.measurement-card h3 {
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--ink);
}

.measurement-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.measurement-row strong {
  overflow-wrap: anywhere;
}

.measurement-row.delta-positive strong {
  color: #9ce7b8;
}

.measurement-row.delta-negative strong {
  color: #ffb5a8;
}

.measurement-row.not-measured strong {
  color: var(--muted);
}

@media (max-width: 720px) {
  .field-grid,
  .measurement-grid,
  .mission-handoff-summary,
  .blindspot-row {
    grid-template-columns: minmax(0, 1fr);
  }
}

.right-dock footer {
  flex: 0 0 auto;
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 9px;
  padding: 12px 13px;
  border-top: 1px solid var(--line);
  background: var(--dock-strong);
}

/* ACTION spine (DC): the CREATE/EXECUTE primaries render AMBER — misiones,
   órdenes y despliegues son acción, no estado. "Evaluar" (command palette) is an
   evaluate/derived affordance and stays on the green --accent. */
.right-dock footer button.primary,
.deploy-form button.primary,
.onboard-form button.primary,
.semantic-form button.primary,
.compute-form > button.primary {
  color: var(--ink);
  border-color: var(--action-line);
  background: var(--action-fill);
  font-weight: var(--fw-semibold);
}

.command-palette button {
  color: var(--ink);
  border-color: var(--accent-line);
  background: var(--accent-fill);
  font-weight: var(--fw-semibold);
}

.right-dock footer button.primary:hover {
  background: var(--action-fill);
  border-color: var(--action);
}

.command-palette button:hover {
  background: var(--accent-fill);
  border-color: var(--accent);
}

.api-strip {
  /* DC "contratos del nodo" strip: a bare mono line floating above the bottom
     band (no card chrome) — chrome removal lives in the shared rule with
     .mission-ribbon. Lifted to bottom:126 so the ribbon owns the baseline. */
  right: 448px;
  bottom: 126px;
  width: 310px;
  padding: 0;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.02em;
  line-height: 1.5;
}

.api-strip b {
  color: var(--ink);
}

.toast {
  display: none;
  top: 74px;
  left: 84px;
  max-width: min(520px, calc(100vw - 520px));
  border-radius: var(--radius-md);
  padding: 11px 12px;
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1.42;
}

.toast b {
  color: var(--ink);
}

.auth-panel {
  position: fixed;
  top: 82px;
  right: 24px;
  width: min(360px, calc(100vw - 32px));
  z-index: 45;
  border: 1px solid rgba(243, 246, 248, 0.18);
  border-radius: var(--radius-md);
  background: rgba(10, 14, 19, 0.94);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38);
  backdrop-filter: blur(18px);
  padding: 14px;
}

.auth-panel form,
.auth-panel header,
.auth-panel label {
  display: grid;
}

.auth-panel form {
  gap: 10px;
}

.auth-panel header {
  gap: 2px;
}

.auth-panel header strong {
  color: var(--ink);
  font-size: 0.9rem;
}

.auth-panel header span,
.auth-panel p {
  margin: 0;
  color: var(--muted);
  font-size: 0.76rem;
}

.auth-panel label {
  gap: 5px;
  color: var(--muted);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.auth-panel input {
  min-width: 0;
  border: 1px solid rgba(243, 246, 248, 0.16);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.06);
  color: var(--ink);
  padding: 9px 10px;
  font: inherit;
  letter-spacing: 0;
}

.auth-panel .auth-remember {
  grid-template-columns: auto 1fr;
  align-items: center;
  letter-spacing: 0;
  text-transform: none;
}

.auth-panel .auth-remember input {
  width: 16px;
  height: 16px;
  padding: 0;
}

.auth-panel div {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.auth-panel button {
  border: 1px solid rgba(243, 246, 248, 0.18);
  border-radius: var(--radius-md);
  background: rgba(21, 224, 161, 0.12);
  color: var(--ink);
  padding: 9px 12px;
  cursor: pointer;
}

@keyframes node-breathe {
  0%,
  100% {
    opacity: 0.09;
    transform: scale(0.82);
  }
  50% {
    opacity: 0.2;
    transform: scale(1.18);
  }
}

/* MEDIUM TIER · 1320 → 1080 — keep all four columns but COMPACT the runtime so
   it never shows-but-cut. Drop the label words + the (least critical) profile
   span; keep "N/M ONLINE" and the mode value. The scope row scrolls. */
@media (max-width: 1320px) {
  .topbar {
    grid-template-columns: 248px minmax(0, 1fr) repeat(7, auto);
  }

  .runtime em:not(#api-label) {
    /* hide the "modo"/"perfil" mono labels — values stay legible on their own.
       #api-label is the live "N/M ONLINE" count, NOT a label: it stays. */
    display: none;
  }

  .runtime span {
    padding: 0 11px;
  }

  .language-switch span {
    display: none;
  }

  .language-switch select {
    width: 94px;
    max-width: 94px;
  }

  .runtime span:last-child {
    /* the profile is the most droppable signal; the ONLINE count + mode dot
       are what the founder reads at a glance */
    display: none;
  }
}

/* NARROW-MEDIUM TIER · ≤1080 — now the runtime would start competing with the
   scope/search for room, so retire it to the right-dock chrome and reclaim its
   column. Three columns: brand · scope-row · tenant. Scope still scrolls. */
@media (max-width: 1080px) {
  .topbar {
    /* runtime hidden below; the remaining shell controls stay on one axis. */
    grid-template-columns: 240px minmax(0, 1fr) repeat(6, auto);
  }

  .runtime {
    display: none;
  }

  .tenant-switch select {
    max-width: 132px;
  }

  .language-switch select {
    width: 86px;
    max-width: 86px;
  }

  .right-dock {
    width: min(420px, calc(100vw - 100px));
  }

  /* Below the band break-point the palette goes full-width again, so the
     ribbon re-stacks ABOVE it (pre-band layout). */
  .mission-ribbon {
    left: 84px;
    right: 16px;
    bottom: 116px;
  }

  .command-palette {
    right: 16px;
    width: auto;
  }

  .api-strip {
    display: none;
  }
}

@media (max-width: 760px) {
  body {
    overflow: auto;
  }

  .atlas-app {
    min-height: 980px;
    grid-template-rows: auto 1fr;
  }

  .topbar {
    /* stack to rows again: brand on top, scope-row below; the two toggles are
       absolutely parked top-right while the other controls keep keyboard flow */
    grid-auto-flow: row;
    grid-template-columns: 1fr;
  }

  .brand {
    height: 56px;
    border-right: 0;
    /* clear the abs-positioned theme toggle parked top-right */
    padding-right: 96px;
  }

  .theme-toggle {
    position: absolute;
    top: 12px;
    z-index: 2;
    margin: 0;
    min-width: 72px;
  }

  #theme-toggle.theme-toggle {
    right: 10px;
  }

  .tenant-switch,
  .language-switch,
  .node-connect-toggle,
  .help-toggle {
    margin: 7px 10px 0;
    justify-self: start;
  }

  .language-switch span {
    display: inline;
  }

  .language-switch select {
    width: min(138px, 42vw);
    max-width: 42vw;
  }

  .scope-row {
    flex-wrap: wrap;
    gap: 9px;
    padding: 9px 10px 11px;
    border-top: 1px solid var(--line);
  }

  /* Wrapped layout: the scope takes its own full-width line and SCROLLS
     horizontally (chips stay full-size, fade-mask is the affordance); the
     search drops below it at full width. */
  .scope-row .scope {
    flex: 1 1 100%;
    min-width: 0;
    padding: 0;
  }

  .site-search {
    flex: 1 1 100%;
    max-width: none;
  }

  .toolrail {
    left: 10px;
    top: 14px;
    max-height: calc(100% - 28px);
  }

  .tool {
    width: 44px;
    height: 44px;
  }

  .leaflet-top.leaflet-left {
    top: 14px;
    left: 64px;
  }

  .right-dock {
    left: 10px;
    right: 10px;
    top: 10px;
    bottom: 10px;
    width: auto;
    height: auto;
    max-height: calc(100dvh - 20px);
  }

  .mission-ribbon {
    left: 68px;
    right: 10px;
    bottom: calc(48% + 118px);
  }

  .command-palette {
    left: 68px;
    right: 10px;
    bottom: calc(48% + 20px);
  }

  .toast {
    left: 68px;
    right: 10px;
    max-width: none;
  }

  .leaflet-control-attribution {
    display: none;
  }

  .tabs {
    padding: 9px 10px;
    grid-auto-columns: minmax(82px, 1fr);
  }

  .tabs button {
    min-width: 0;
    font-size: 12px;
  }

  .dock-pane {
    padding: 12px 10px max(18px, env(safe-area-inset-bottom));
  }

  .incident-toolbar,
  .incident-layout,
  .incident-detail-grid,
  .site-edit-actions {
    grid-template-columns: 1fr;
  }

  .incident-list {
    max-height: 260px;
  }

  .media-console,
  .media-grid-compact {
    grid-template-columns: minmax(0, 1fr);
  }

  .media-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .row {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .row span {
    grid-column: 2;
    text-align: left;
  }

  .right-dock footer {
    grid-template-columns: 1fr;
  }

  .node-card header,
  .evidence-card header,
  .media-card header,
  .semantic-card header,
  .section header {
    min-width: 0;
  }

  .node-card header b,
  .evidence-card header b,
  .media-card header b,
  .semantic-card header b,
  .section header b {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* REFLOW ANGOSTO · los docks flotantes (enjambre + territorio) pasan a ancho-completo
     anclados al borde correspondiente, con tope de altura → nada se sale ni se pisa
     hasta ~360px. El Puesto inspector (abajo) y el onboard-dock (arriba) siguen en
     mitades opuestas de la columna; la cobertura/leyenda quedan en la izquierda. */
  .onboard-dock,
  .swarm-overlay,
  .coverage-dock,
  .portfolio-panel {
    left: 10px;
    right: 10px;
    width: auto;
    max-width: none;
  }

  .onboard-dock {
    top: 64px;
  }

  .swarm-overlay {
    bottom: 64px; /* deja sitio al pill del Puesto Guardian (gc-open) abajo */
    max-height: 42vh;
  }

  .swarm-card {
    max-height: 42vh;
  }

  .onboard-panel {
    max-height: 42vh;
  }

  .coverage-dock {
    bottom: 64px;
    max-height: 42vh;
  }

  .portfolio-panel {
    top: 64px;
    bottom: 10px;
    max-height: calc(100dvh - 74px);
  }

  .onboard-banner {
    left: 64px;
    max-width: calc(100% - 74px);
  }
}

.pilot-wizard-ladder {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.pilot-wizard-step {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.035);
  color: var(--ink);
  padding: 7px 8px;
}

.pilot-wizard-step:focus {
  outline: 2px solid rgba(21, 224, 161, 0.6);
  outline-offset: 1px;
}

.pilot-wizard-step.current {
  border-color: rgba(21, 224, 161, 0.6);
  background: rgba(21, 224, 161, 0.1);
}

.pilot-wizard-step.block {
  border-color: rgba(255, 122, 122, 0.5);
}

.pilot-wizard-step-index {
  color: var(--muted);
  font-size: 12px;
  text-align: center;
}

.pilot-wizard-step-main {
  min-width: 0;
  overflow-wrap: anywhere;
}

.pilot-wizard-step-main strong,
.pilot-wizard-step-main small {
  display: block;
}

.pilot-wizard-step-main small {
  color: var(--muted);
}

.pilot-wizard-step-state {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.pilot-wizard-step-state.ok {
  color: rgba(21, 224, 161, 0.9);
}

.pilot-wizard-step-state.block {
  color: rgba(255, 122, 122, 0.9);
}

/* ── PR 7: coordinación Physarum + capa cognitiva (memoria · agente) ───────── */

.space-coord {
  position: relative;
  overflow: hidden;
}
.space-coord.coord-live {
  border-color: rgba(157, 146, 234, 0.34);
  box-shadow: inset 0 0 0 1px rgba(157, 146, 234, 0.1), 0 0 28px rgba(157, 146, 234, 0.07);
}
.space-coord.coord-live::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(120% 80% at 12% -10%, rgba(157, 146, 234, 0.12), transparent 60%);
  animation: coord-breathe 6s ease-in-out infinite;
}
.space-coord.coord-local {
  border-color: var(--line);
}

.coord-rank {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 8px 0 6px;
}
.coord-row {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) 84px 40px auto;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.025);
  font-size: 12px;
  transition: border-color 0.3s ease, background 0.3s ease;
}
.coord-row.is-owned {
  border-color: rgba(21, 224, 161, 0.5);
  background: rgba(21, 224, 161, 0.08);
  box-shadow: 0 0 16px rgba(21, 224, 161, 0.08);
}
.coord-row.is-reserved {
  border-color: rgba(157, 146, 234, 0.4);
  background: rgba(157, 146, 234, 0.06);
}
.coord-rank-n {
  color: var(--quiet);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.coord-cell {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink);
  font-weight: 600;
}
.coord-bar {
  position: relative;
  height: 7px;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.06);
  overflow: hidden;
}
.coord-bar i {
  position: absolute;
  inset: 0 auto 0 0;
  display: block;
  height: 100%;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--cyan), var(--blue));
  background-size: 200% 100%;
  animation: coord-flow 2.4s linear infinite;
}
.coord-row.is-owned .coord-bar i {
  background: linear-gradient(90deg, var(--mint), var(--green));
}
.coord-row.is-reserved .coord-bar i {
  background: linear-gradient(90deg, var(--violet), var(--blue));
}
.coord-score {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
  font-size: 11px;
}
.coord-owner {
  color: var(--quiet);
  font-size: 10px;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.coord-row.is-owned .coord-owner {
  color: var(--mint);
}
.coord-row.is-reserved .coord-owner {
  color: var(--violet);
}
.coord-note {
  margin: 6px 0 2px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.45;
  border-left: 2px solid rgba(157, 146, 234, 0.4);
  padding-left: 8px;
}
.coord-note.muted {
  color: var(--quiet);
  border-left-color: var(--line-strong);
}
.coord-fleet {
  margin-top: 8px;
}

.space-memory[data-mem="on"] header b {
  color: var(--mint);
}
.space-memory[data-mem="off"] header b {
  color: var(--quiet);
}
.mem-recall {
  display: flex;
  gap: 8px;
  margin: 8px 0 6px;
}
.mem-recall input {
  flex: 1;
  min-width: 0;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 8px 10px;
  color: var(--ink);
  font-size: 12px;
}
.mem-recall input:focus {
  outline: none;
  border-color: var(--mint);
  box-shadow: 0 0 0 1px rgba(21, 224, 161, 0.3);
}
.mem-recall button {
  border: 1px solid rgba(21, 224, 161, 0.4);
  background: rgba(21, 224, 161, 0.1);
  color: var(--mint);
  border-radius: var(--radius-md);
  padding: 8px 14px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s ease;
}
.mem-recall button:hover {
  background: rgba(21, 224, 161, 0.18);
}
.mem-recall button:disabled {
  opacity: 0.5;
  cursor: default;
}

.space-agent header b {
  color: var(--blue);
}

@keyframes coord-flow {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: 0 0;
  }
}
@keyframes coord-breathe {
  0%,
  100% {
    opacity: 0.5;
  }
  50% {
    opacity: 1;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
   PASO 2 · PUESTO GUARDIAN — consola operativa sensor→atención.
   Shell oscuro full-screen: topbar + rail + stage(tab) + COP dock + statusbar.
   Reusa los tokens --bg/--ink/--line/--mint/--amber + la rampa de entropía.
   Mono para todos los instrumentos numéricos (cue Bloomberg/Mission-Control).
   ════════════════════════════════════════════════════════════════════════════ */
/* GAP 3 · el botón del Puesto (fallback al flujo click-pin→consola). Reposicionado al
   borde INFERIOR-IZQUIERDO del stage para NO pisar la marca/«‹ Territorio» (top-left).
   Pill mint clara y visible (era gris lavado): chip de acento, alto contraste. */
.gc-open {
  position: absolute;
  left: 16px;
  bottom: 16px;
  z-index: 765;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(21, 224, 161, 0.16);
  color: var(--mint);
  border: 1px solid rgba(21, 224, 161, 0.6);
  border-radius: var(--radius-pill);
  padding: 0.46rem 0.85rem;
  font: 700 0.78rem/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.04em;
  cursor: pointer;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(6px);
}
.gc-open:hover {
  border-color: var(--mint);
  background: rgba(21, 224, 161, 0.26);
  color: #eafff8;
}
.gc-open[hidden] {
  display: none;
}

/* Stage 1 · el toggle "Modo demo" — EXPLÍCITO, badgeado, distinto del viejo
   `physarumDemo` disfrazado (retirado): acento ACCIÓN ámbar (nunca se confunde con
   el pill mint de "abrir"), apilado justo arriba de #gc-open. .is-on = encendido. */
.guardian-demo-toggle {
  position: absolute;
  left: 16px;
  bottom: 64px;
  z-index: 765;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--neutral-chip);
  color: var(--ink-2);
  border: 1px solid var(--neutral-chip-line);
  border-radius: var(--radius-pill);
  padding: 0.4rem 0.8rem;
  font: 700 0.72rem/1 var(--font-mono);
  letter-spacing: 0.04em;
  cursor: pointer;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(6px);
  transition:
    background var(--dur-1) var(--ease-standard),
    border-color var(--dur-1) var(--ease-standard),
    color var(--dur-1) var(--ease-standard);
}
.guardian-demo-toggle:hover {
  border-color: var(--amber);
  color: var(--amber);
}
.guardian-demo-toggle.is-on {
  background: rgba(242, 163, 38, 0.18);
  color: var(--amber);
  border-color: rgba(242, 163, 38, 0.65);
}

/* HONESTIDAD · sello "DEMO · datos representativos", reusado en TODA superficie
   sintética del Puesto (header chip, muro, detalle por-cámara, COP). Acento
   ACCIÓN ámbar (nunca el mint de "cobertura real") + alto contraste, imposible de
   confundir con un chip de estado real. */
.gc-demo-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  background: rgba(242, 163, 38, 0.22);
  color: var(--amber);
  border: 1px solid rgba(242, 163, 38, 0.6);
  border-radius: var(--radius-pill);
  padding: 0.2rem 0.6rem;
  font: 700 0.68rem/1 var(--font-mono);
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.gc-demo-badge-wall {
  margin-bottom: var(--space-sm);
}

/* Banner persistente bajo el topbar, visible en TODAS las tabs mientras el Modo
   demo esté activo (toggled por renderGuardianConsole en cada render — no sólo al
   abrir). Ningún screenshot recortado de esta consola puede leerse como real. */
.gc-demo-banner {
  background: rgba(242, 163, 38, 0.14);
  color: var(--amber);
  border-bottom: 1px solid rgba(242, 163, 38, 0.4);
  padding: var(--space-xs) var(--space-md);
  font: 700 0.72rem/1.3 var(--font-mono);
  letter-spacing: 0.02em;
  text-align: center;
}
.gc-demo-banner[hidden] {
  display: none;
}

.gc-copdock-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
}

.guardian-console {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: var(--bg);
  color: var(--ink);
  font: 400 13px/1.45 Inter, system-ui, sans-serif;
}
.guardian-console[hidden] {
  display: none;
}
.guardian-console code,
.guardian-console .gc-rank-h,
.guardian-console .gc-tb-mean,
.guardian-console time,
.guardian-console .gc-tile-stat,
.guardian-console .gc-sensor-table td,
.guardian-console .gc-m-need {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}

/* ── TOPBAR ─────────────────────────────────────────────────────────────────*/
/* ONE PRODUCT, FIVE IDENTITIES · una franja de acento (3px) en el borde superior del
   topbar reskinea el Puesto al toque (mint/azul/cyan/verde/ámbar) desde el --accent
   que renderGcTopbar inyecta por vertical. El mismo chassis, identidad inconfundible. */
.gc-topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem 0.9rem;
  border-bottom: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  background: rgba(5, 8, 12, 0.96);
  transition: border-top-color var(--dur-2) var(--ease-standard);
}
.gc-close,
.gc-tb-title b {
  transition: color var(--dur-1) var(--ease-standard);
}
.gc-close {
  background: var(--neutral-chip);
  border: 1px solid var(--neutral-chip-line);
  color: #eef3f4;
  border-radius: var(--radius-md);
  padding: 0.35rem 0.6rem;
  font: 700 0.74rem/1 var(--font-mono);
  letter-spacing: 0.06em;
  cursor: pointer;
  transition:
    background var(--dur-1) var(--ease-standard),
    border-color var(--dur-1) var(--ease-standard),
    color var(--dur-1) var(--ease-standard);
}
.gc-close:hover {
  border-color: var(--accent-line);
  background: var(--accent-fill-soft);
  color: #f3fffb;
}
.gc-topbar-meta {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 1.2rem;
  min-width: 0;
}
.gc-tb-title b {
  font-size: 0.92rem;
}
.gc-tb-title small {
  display: block;
  color: var(--muted); /* subtítulo del topbar: AA (era opacity .6) */
  font-size: 0.72rem;
}
.gc-tb-engine {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  font-size: 0.74rem;
}
.gc-live {
  color: var(--mint);
}
.gc-synth {
  color: var(--amber);
}
.gc-sim {
  color: var(--amber);
  opacity: 0.85;
}
.gc-topbar-tabs {
  display: flex;
  gap: 0.3rem;
}
/* (B) SCOPE-STRIP · superficie de capacidad del Puesto (== stackForKind), en el accent
   del vertical. Chips neutros del DS con borde de acento — el operador ve de un vistazo
   QUÉ hace este Puesto. Se contrae en pantallas chicas (no compite con las tabs). */
.gc-scope-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
  min-width: 0;
}
.gc-scope-chip {
  font: 600 0.64rem/1 var(--font-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-fill-soft);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-pill);
  padding: var(--space-2xs) var(--space-sm);
  white-space: nowrap;
}
@media (max-width: 1280px) {
  .gc-scope-strip {
    display: none;
  }
}
/* GAP 3 · CONTRASTE. Las tabs/botones NO seleccionados eran var(--ink)+opacity sobre
   un chip casi invisible → lavados. Ahora: chip NEUTRO visible (gris claro legible),
   texto a contraste pleno, SIN opacity. El acento mint queda RESERVADO al SELECCIONADO
   (.active) — el ojo distingue al toque cuál está activo. */
.gc-tab,
.gc-freeze {
  background: var(--neutral-chip);
  border: 1px solid var(--neutral-chip-line);
  color: #e8eef0;
  border-radius: var(--radius-md);
  padding: 0.36rem 0.7rem;
  font: 600 0.72rem/1 var(--font-mono);
  letter-spacing: 0.05em;
  cursor: pointer;
  transition:
    background var(--dur-1) var(--ease-standard),
    border-color var(--dur-1) var(--ease-standard),
    color var(--dur-1) var(--ease-standard);
}
.gc-tab:hover,
.gc-freeze:hover {
  border-color: var(--accent-line);
  background: var(--accent-fill-soft);
  color: #f3fffb;
}
.gc-tab:focus-visible,
.gc-freeze:focus-visible,
.gc-close:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.gc-tab.active {
  background: var(--accent-fill);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: var(--fw-bold);
}
.gc-freeze[aria-pressed="true"] {
  opacity: 1;
  border-color: var(--amber);
  color: var(--amber);
}

/* ── BODY: rail | stage | copdock ───────────────────────────────────────────*/
.gc-body {
  display: grid;
  grid-template-columns: 220px 1fr 460px;
  min-height: 0;
  overflow: hidden;
}
@media (max-width: 1280px) {
  .gc-body {
    grid-template-columns: 180px 1fr 400px;
  }
}
/* GAP 3 · paneles grisáceos lavados → fondo de panel sutil + divisores más marcados.
   Da separación legible entre rail/stage/COP sin gritar. */
.gc-rail,
.gc-copdock {
  border-right: 1px solid var(--line-strong);
  padding: 0.7rem;
  overflow: auto;
  background: rgba(168, 186, 196, 0.05);
}
.gc-copdock {
  border-right: none;
  border-left: 1px solid var(--line-strong);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.gc-rail h3,
.gc-copdock-head {
  font: 700 0.68rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.1em;
  /* was color:#cdd6d8 @opacity .85 (hardcoded + opacity-stacked); the de-emphasis
     is now carried by the token alone so it can't stack below AA. */
  color: var(--ink-2);
  margin: 0.6rem 0 0.4rem;
}
.gc-rail-rank,
.gc-rail-events {
  list-style: none;
  margin: 0;
  padding: 0;
}
.gc-rank-row {
  display: grid;
  grid-template-columns: 1.6rem 1rem 1fr 3rem auto;
  align-items: center;
  gap: 0.35rem;
  padding: 0.28rem 0.2rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 0.76rem;
  transition: background var(--dur-1) var(--ease-standard);
}
.gc-rank-row:hover,
.gc-rank-row.is-focus {
  background: var(--accent-fill-soft);
}
.gc-rank-n {
  font: 700 0.7rem/1 ui-monospace, Menlo, monospace;
  /* mono chico de ranking: token AA en toda la rampa (era opacity .7 → 4.09 en rail claro) */
  color: var(--muted);
}
.gc-rank-bar {
  display: block;
  height: 5px;
  border-radius: var(--radius-sm);
  background: rgba(243, 246, 248, 0.1);
  overflow: hidden;
}
.gc-rank-bar i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--amber));
}
.gc-rank-h {
  font-size: 0.72rem;
  color: var(--ink-2); /* dato H (mono): legible pleno, era opacity .8 */
  text-align: right;
}
.gc-rail-events li {
  font-size: 0.72rem;
  /* de-emphasis via token (was opacity .78) so the nested <time> can't stack below AA */
  color: var(--ink-2);
  padding: 0.16rem 0;
}
.gc-rail-events time {
  /* was opacity .55 ON TOP of the li's .78 (= .43 effective → 3.77, FAIL).
     Direct token = AA on its own, no stacking. */
  color: var(--muted);
  margin-right: 0.3rem;
}
.gc-empty {
  /* was opacity .4 → 3.47 (FAIL). --muted is AA on every panel surface. */
  color: var(--muted);
  font-size: 0.74rem;
  font-style: italic;
}
/* STAGE 2 · nota honesta sobre la grilla real cuando hay cámaras pero sin campo vivo
   (space-fabric no publicó celdas todavía) — distinta del honest-empty de arriba
   (ahí NO hay ni cámaras); acá el muro sigue mostrando tiles debajo. */
.gc-empty-note {
  color: var(--muted);
  font-size: 0.72rem;
  font-style: italic;
  margin: 0 0 0.5rem;
}

/* ── COP DOCK: re-parenta #map-space + #field-canvas (GAP 4: PROMINENTE) ──────*/
/* El minimapa del enjambre (campo + conos + flota) es PROMINENTE y SIEMPRE visible
   en todas las tabs. El #map-space llena el VIEWPORT posicionado; el #field-canvas se
   superpone EXACTO encima (inset:0), no como un bloque aparte. */
.gc-copdock-viewport {
  position: relative;
  flex: 1 1 auto;
  min-height: 360px;
  border-radius: var(--radius-md);
  border: 1px solid var(--line);
  overflow: hidden;
}
.gc-copdock-viewport #map-space {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
  border-radius: var(--radius-md);
}
.gc-copdock-viewport #field-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  border-radius: var(--radius-md);
  z-index: 2;
}
.gc-copdock-head {
  flex: 0 0 auto;
}
.gc-copdock-legend {
  flex: 0 0 auto;
  font-size: 0.68rem;
  color: var(--muted); /* leyenda del COP: AA en claro (era opacity .6 → 4.09 FAIL) */
  line-height: 1.4;
}

/* ── STAGE / WALL ───────────────────────────────────────────────────────────*/
.gc-stage {
  position: relative;
  overflow: auto;
  padding: 0.8rem;
}
.gc-wall-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.7rem;
  align-items: start;
}
.gc-tile {
  position: relative;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: rgba(5, 8, 12, 0.9);
  padding: 0.4rem;
  overflow: hidden;
  transition:
    border-color var(--dur-2) var(--ease-standard),
    box-shadow var(--dur-2) var(--ease-standard);
}
.gc-tile.gc-hero {
  grid-column: span 2;
  grid-row: span 2;
}
.gc-tile.is-focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
/* HUD corner brackets — el frame táctico que distingue "instrumento" de "video" */
.gc-tile::before,
.gc-tile::after {
  content: "";
  position: absolute;
  width: 12px;
  height: 12px;
  border: 1px solid var(--accent);
  opacity: var(--opacity-muted);
  pointer-events: none;
}
.gc-tile::before {
  top: 4px;
  left: 4px;
  border-right: none;
  border-bottom: none;
}
.gc-tile::after {
  bottom: 4px;
  right: 4px;
  border-left: none;
  border-top: none;
}
.gc-tile-canvas {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
  background: #0a0e13;
}
.gc-tile-badge {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 2;
  font: 700 0.66rem/1 ui-monospace, Menlo, monospace;
  background: rgba(10, 14, 19, 0.82);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.2rem 0.35rem;
  letter-spacing: 0.03em;
}
.gc-tile-label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.74rem;
  margin-bottom: 0.3rem;
}
.gc-tile-kind {
  color: var(--muted); /* was opacity .5 → 4.06 on field-3 (FAIL) */
  font-size: 0.68rem;
}
.gc-tile-stat {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.68rem;
  margin-top: 0.3rem;
  color: var(--ink-2); /* stats del tile: legible pleno (era opacity .86) */
}
.gc-tile-alloc {
  color: var(--muted); /* meta de asignación: AA en la rampa (era opacity .7) */
}
.gc-spark {
  width: 48px;
  height: 14px;
  color: var(--mint);
}
.gc-tile-sim {
  margin-top: 0.25rem;
  font: 600 0.64rem/1 ui-monospace, Menlo, monospace;
  color: var(--amber);
  opacity: 0.85;
}
/* STAGE 2 · cámara real sin posición medida (o sin geo-referencia del sitio para
   proyectarla) — honesto, nunca un pin inventado. Ver renderGcWall/__hasPosition. */
.gc-tile-posnote {
  margin-top: 0.2rem;
  font-size: 0.66rem;
  font-style: italic;
  color: var(--muted);
}
.gc-hero-why {
  font: 600 0.7rem/1.3 ui-monospace, Menlo, monospace;
  color: var(--mint);
  background: rgba(21, 224, 161, 0.08);
  border-radius: var(--radius-sm);
  padding: 0.3rem 0.4rem;
  margin-bottom: 0.35rem;
}
.gc-rondin {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.6rem;
  padding: 0.4rem 0.6rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
  font-size: 0.74rem;
  color: var(--ink-2); /* rondín: legible (era opacity .85, que multiplicaba al label/h) */
}
.gc-rondin-label {
  font: 700 0.66rem/1 ui-monospace, Menlo, monospace;
  color: var(--muted); /* mono label: AA en rail claro (era opacity .6 → 4.09 FAIL) */
  letter-spacing: 0.06em;
}
.gc-rondin-h {
  margin-left: auto;
  font-family: ui-monospace, Menlo, monospace;
  color: var(--muted); /* dato H mono (era opacity .7) */
}
.gc-wall-foot,
.gc-sensor-foot {
  margin-top: 0.7rem;
  font-size: 0.68rem;
  color: var(--muted); /* pie de nota chico: AA (era opacity .55 → 3.53 FAIL en claro) */
  line-height: 1.4;
}

/* ── SENSORES ───────────────────────────────────────────────────────────────*/
.gc-sensor-group h4 {
  font: 700 0.7rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.08em;
  margin: 0.8rem 0 0.3rem;
  color: var(--ink-2); /* encabezado de grupo: legible (era opacity .7) */
}
.gc-att-event h4 {
  color: var(--amber);
}
.gc-sensor-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.74rem;
}
.gc-sensor-table th {
  text-align: left;
  font: 600 0.66rem/1 ui-monospace, Menlo, monospace;
  color: var(--muted); /* was opacity .5 → 4.06 on field-3 (FAIL for ~10.5px) */
  padding: 0.3rem 0.5rem;
  border-bottom: 1px solid var(--line);
}
.gc-sensor-table td {
  padding: 0.32rem 0.5rem;
  border-bottom: 1px solid rgba(243, 246, 248, 0.06);
}
.gc-sensor-row {
  cursor: pointer;
}
.gc-sensor-row:hover,
.gc-sensor-row.is-focus {
  background: rgba(21, 224, 161, 0.08);
}
.gc-null {
  color: var(--muted); /* was opacity .45 → 3.99 (FAIL); honest "no data" text, must read */
  font-style: italic;
}
.gc-glyph,
.gc-rank-glyph,
.gc-tile-glyph,
.gc-rondin-glyph {
  display: inline-block;
}

/* ── MISIONES ───────────────────────────────────────────────────────────────*/
.gc-missions {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 1rem;
  align-items: start;
}
.gc-missions h3 {
  font: 700 0.7rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.08em;
  color: var(--muted); /* título de sección: AA en claro (era opacity .6 → 4.09 FAIL) */
  margin: 0 0 0.5rem;
}
.gc-mission {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 0.5rem 0.6rem;
  margin-bottom: 0.5rem;
  background: rgba(5, 8, 12, 0.6);
}
.gc-mission.is-focus {
  border-color: var(--mint);
}
.gc-mission header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.78rem;
}
.gc-m-verb {
  font-weight: 700;
}
.gc-m-need {
  margin-left: auto;
  color: var(--muted); /* dato need (era opacity .7) */
  font-size: 0.72rem;
}
.gc-m-agent {
  font-size: 0.72rem;
  color: var(--muted); /* meta agente (era opacity .7) */
  margin: 0.2rem 0;
}
.gc-m-why {
  margin: 0.3rem 0;
  padding-left: 1rem;
  font-size: 0.72rem;
  color: var(--ink-2); /* explicación: legible pleno (era opacity .82) */
}
.gc-m-state {
  font-size: 0.72rem;
  color: var(--ink-2); /* estado de misión (era opacity .75) */
}
.gc-m-sim {
  color: var(--amber);
}
.gc-m-actions {
  display: flex;
  gap: 0.35rem;
  margin: 0.4rem 0 0.3rem;
}
.gc-m-act {
  background: none;
  border: 1px solid var(--line-strong);
  color: var(--ink);
  border-radius: var(--radius-sm);
  padding: 0.28rem 0.55rem;
  font: 600 0.7rem/1 ui-monospace, Menlo, monospace;
  cursor: pointer;
}
.gc-m-act:hover {
  border-color: var(--mint);
  color: var(--mint);
}
.gc-m-sim-btn {
  border-color: var(--amber);
  color: var(--amber);
}
.gc-m-gate {
  font: 600 0.64rem/1.3 ui-monospace, Menlo, monospace;
  color: var(--amber); /* marca GATED (honestidad) — debe leerse: sin opacity (era .8 → 3.34 en claro) */
  margin-top: 0.3rem;
}
.gc-m-closed {
  font-size: 0.7rem;
  color: var(--muted); /* was opacity .5 → 4.06 on field-3 (FAIL) */
}
.gc-missions-audit ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.gc-missions-audit li {
  font-size: 0.7rem;
  color: var(--ink-2); /* was opacity .78 — token so the nested time can't stack */
  padding: 0.16rem 0;
  border-bottom: 1px solid rgba(243, 246, 248, 0.05);
}
.gc-missions-audit time {
  color: var(--muted); /* was opacity .55 × li .78 = .43 → FAIL; direct token = AA */
  margin-right: 0.3rem;
}

/* ── OBJETIVOS · subasta Contract-Net (de observar a ACTUAR) ─────────────────*/
.gc-objectives {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 1rem;
  align-items: start;
}
.gc-objectives h3 {
  font: 700 0.7rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.08em;
  color: var(--muted); /* título ZONAS/TÁCTICO: AA en claro (era opacity .6 → 4.09 FAIL) */
  margin: 0 0 0.5rem;
}
.gc-obj {
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: var(--radius-md);
  padding: 0.5rem 0.6rem;
  margin-bottom: 0.5rem;
  background: rgba(5, 8, 12, 0.6);
}
/* acento por tipo de acción (verificar=ámbar, seguir=violeta, inspeccionar=mint) */
.gc-obj-t-verificar-evento {
  border-left-color: var(--amber);
}
.gc-obj-t-seguir-objetivo {
  border-left-color: #9d92ea;
}
.gc-obj-t-inspeccionar-zona {
  border-left-color: var(--mint);
}
.gc-obj-sin-cobertura,
.gc-obj-resuelto {
  /* de-emphasis SIN apilar opacidad: 0.6 multiplicaba a cada hijo (why-line .72 → .43 →
     3.98, status .65 → 3.47, obj-why .6 → 3.14: FALLAN AA de cuerpo). A 0.85 el peor hijo
     queda en 5.0:1 (AA) y la tarjeta sigue leyéndose "apagada" vs las activas. */
  opacity: 0.85;
}
.gc-obj.is-focus {
  border-color: var(--mint);
}
.gc-obj header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.78rem;
}
.gc-obj-verb {
  font-weight: 700;
}
.gc-obj-pri {
  margin-left: auto;
  color: var(--muted); /* prioridad (era opacity .7; bajo card .85 sigue AA) */
  font-size: 0.72rem;
}
.gc-obj-status {
  font: 700 0.6rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted); /* status mono chico: AA (era opacity .65; stack .6×.65=.39 → 3.47 FAIL) */
}
.gc-obj-assign {
  font-size: 0.74rem;
  margin: 0.25rem 0;
}
.gc-obj-act {
  color: var(--mint);
}
.gc-obj-handoff {
  color: #9d92ea;
}
.gc-obj-noassign {
  color: var(--amber);
  font-weight: 600;
}
.gc-obj-why-line {
  font-size: 0.7rem;
  color: var(--ink-2); /* línea de porqué (era opacity .72; stack .6×.72=.43 → 3.98 FAIL) */
  margin: 0.2rem 0;
}
.gc-obj-bids {
  list-style: none;
  margin: 0.3rem 0;
  padding: 0;
}
.gc-obj-bid {
  font-size: 0.7rem;
  color: var(--ink-2); /* puja (era opacity .82) */
  padding: 0.12rem 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}
.gc-obj-win {
  color: var(--mint);
  font-weight: 600;
  opacity: 1;
}
.gc-obj-noreach {
  color: var(--muted); /* was opacity .45 → 3.99 (FAIL) */
}
.gc-obj-fit {
  color: var(--muted); /* fit de la puja (era opacity .7) */
}
.gc-obj-why {
  color: var(--muted); /* porqué de la puja: AA en claro (era opacity .6 → 4.09 FAIL) */
}
.gc-obj-gate {
  font: 600 0.62rem/1.3 ui-monospace, Menlo, monospace;
  color: var(--amber); /* marca GATED (honestidad) — debe leerse: sin opacity (era .8 → 3.34 en claro) */
  margin-top: 0.3rem;
}
.gc-obj-audit ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.gc-obj-audit li {
  font-size: 0.7rem;
  color: var(--ink-2); /* was opacity .78 — token so the nested time can't stack */
  padding: 0.16rem 0;
  border-bottom: 1px solid rgba(243, 246, 248, 0.05);
}
.gc-obj-audit time {
  color: var(--muted); /* was opacity .55 × li .78 = .43 → FAIL; direct token = AA */
  margin-right: 0.3rem;
}

/* ── PATRULLA flag (móviles/dron en el muro y la analítica) ──────────────────*/
.gc-tile-patrol {
  font: 700 0.58rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--amber);
  border: 1px solid var(--amber);
  border-radius: var(--radius-sm);
  padding: 0.08rem 0.24rem;
  opacity: 0.85;
}
.gc-tile-mobile .gc-tile-canvas {
  outline: 1px dashed rgba(242, 163, 38, 0.4);
  outline-offset: -2px;
}

/* ── ANALÍTICA (GAP 3) ──────────────────────────────────────────────────────*/
.gc-analytics {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.gc-an-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 0.5rem;
}
.gc-an-metric {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 0.45rem 0.55rem;
  background: rgba(5, 8, 12, 0.6);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.gc-an-k {
  font: 600 0.62rem/1.2 ui-monospace, Menlo, monospace;
  letter-spacing: 0.04em;
  opacity: 0.55;
  text-transform: uppercase;
}
.gc-an-metric b {
  font: 700 1.1rem/1 ui-monospace, Menlo, monospace;
  color: var(--ink);
}
.gc-an-metric b small {
  font-size: 0.7rem;
  opacity: 0.6;
  margin-left: 0.1rem;
}
.gc-an-metric b.gc-null {
  font-size: 0.86rem;
}
.gc-an-metric i {
  font-size: 0.62rem;
  opacity: 0.5;
  font-style: normal;
  line-height: 1.3;
}
.gc-an-null {
  opacity: 0.7;
}
.gc-an-sales {
  border: 1px dashed var(--amber);
  border-radius: var(--radius-md);
  padding: 0.4rem 0.6rem;
  font: 600 0.74rem/1.3 ui-monospace, Menlo, monospace;
  color: var(--amber);
}
.gc-an-sales i {
  font-style: normal;
  opacity: 0.7;
  font-size: 0.66rem;
  margin-left: 0.3rem;
}
.gc-an-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.7rem;
  align-items: start;
}
@media (max-width: 1100px) {
  .gc-an-grid {
    grid-template-columns: 1fr;
  }
}
.gc-an-panel {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 0.55rem 0.6rem;
  background: rgba(5, 8, 12, 0.5);
}
.gc-an-panel h4 {
  font: 700 0.66rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.07em;
  opacity: 0.6;
  margin: 0 0 0.45rem;
}
.gc-an-tl {
  list-style: none;
  margin: 0;
  padding: 0;
}
.gc-an-tl li {
  font-size: 0.7rem;
  color: var(--ink-2); /* was opacity .82 — token so the nested time can't stack */
  padding: 0.16rem 0;
  border-bottom: 1px solid rgba(243, 246, 248, 0.05);
}
.gc-an-tl time {
  color: var(--muted); /* was opacity .55 × li .82 = .45 → FAIL; direct token = AA */
  margin-right: 0.35rem;
}
.gc-an-tl-verify {
  color: var(--amber);
}
.gc-an-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.72rem;
}
.gc-an-table td {
  padding: 0.26rem 0.3rem;
  border-bottom: 1px solid rgba(243, 246, 248, 0.06);
}
.gc-an-row {
  cursor: pointer;
}
.gc-an-row:hover {
  background: rgba(21, 224, 161, 0.08);
}
.gc-an-barcell {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  white-space: nowrap;
}
.gc-an-bar {
  display: block;
  flex: 1 1 auto;
  height: 5px;
  min-width: 40px;
  border-radius: var(--radius-sm);
  background: rgba(243, 246, 248, 0.1);
  overflow: hidden;
}
.gc-an-bar i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--mint), var(--amber));
}
.gc-an-tag {
  font: 700 0.58rem/1 ui-monospace, Menlo, monospace;
  color: var(--amber);
  border: 1px solid var(--amber);
  border-radius: var(--radius-sm);
  padding: 0.06rem 0.22rem;
}
.gc-an-nozone {
  font-size: 0.72rem;
  opacity: 0.65;
}

/* ── STATUS BAR ─────────────────────────────────────────────────────────────*/
.gc-statusbar {
  display: flex;
  gap: 1.4rem;
  flex-wrap: wrap;
  padding: 0.45rem 0.9rem;
  border-top: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.96);
  font: 500 0.7rem/1 ui-monospace, Menlo, monospace;
  opacity: 0.82;
}
.gc-statusbar span:first-child {
  color: var(--mint);
}

/* calm baseline: sin motion decorativa; respeta reduced-motion */
@media (prefers-reduced-motion: reduce) {
  .gc-rank-bar i {
    transition: none;
  }
}

/* light theme: hereda los tokens light ya definidos */
body[data-theme="light"] .guardian-console {
  background: var(--bg);
}
body[data-theme="light"] .gc-tile,
body[data-theme="light"] .gc-mission,
body[data-theme="light"] .gc-obj {
  /* en tema claro la tarjeta de objetivos NO puede quedar con el fondo ink oscuro
     (rgba(5,8,12,.6)) heredando la tinta oscura de --ink → texto-oscuro-sobre-oscuro
     = 2.95:1 (FALLA). Se invierte a superficie clara como .gc-mission → --ink lee AA. */
  background: rgba(255, 255, 255, 0.7);
}

/* ═══ QUINTA SUPERFICIE · DRILL-IN POR CÁMARA (detalle completo de UNA cámara) ═══
   Overlay full-bleed dentro de la .gc-stage (que es position:relative). Cubre los 4
   paneles del tab (que quedan montados debajo, hidden). El COP sigue en su dock. */
.gc-detail {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 0.8rem;
  overflow: auto;
  background: linear-gradient(180deg, rgba(5, 8, 12, 0.98), rgba(5, 8, 12, 0.99));
}
.gc-detail[hidden] {
  display: none;
}
.gc-detail-head {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: rgba(10, 14, 19, 0.9);
  padding: 0.55rem 0.8rem;
}
.gc-detail-close {
  position: absolute;
  top: 0.4rem;
  right: 0.5rem;
  background: rgba(120, 160, 180, 0.1);
  border: 1px solid rgba(120, 160, 180, 0.4);
  color: var(--ink);
  border-radius: var(--radius-md);
  width: 1.7rem;
  height: 1.7rem;
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
}
.gc-d-glyph {
  font-size: 1.4rem;
}
.gc-d-id b {
  font-size: 0.98rem;
  display: block;
}
.gc-d-id small {
  opacity: 0.65;
  font-size: 0.72rem;
}
.gc-d-rank {
  text-align: center;
  margin-left: 0.4rem;
}
.gc-d-rankn {
  font: 700 1.1rem/1 ui-monospace, Menlo, monospace;
  color: var(--mint);
}
.gc-d-rank small {
  display: block;
  opacity: 0.6;
  font-size: 0.66rem;
}
.gc-d-live {
  color: var(--mint);
  font-size: 0.72rem;
}
.gc-d-repr {
  color: var(--amber);
  font-size: 0.72rem;
}
.gc-detail-head .gc-sim {
  margin-left: auto;
  margin-right: 2rem;
}
.gc-detail-body {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 0.7rem;
  align-items: start;
}
.gc-detail-pov {
  position: relative;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: rgba(5, 8, 12, 0.95);
  overflow: hidden;
  min-height: 280px;
}
.gc-detail-pov-canvas {
  display: block;
  width: 100%;
  height: auto;
}
.gc-detail-pov-sim {
  position: absolute;
  top: 0.5rem;
  left: 0.6rem;
  color: var(--amber);
  font: 600 0.7rem/1 ui-monospace, Menlo, monospace;
  background: rgba(5, 8, 12, 0.7);
  padding: 0.2rem 0.4rem;
  border-radius: var(--radius-sm);
}
.gc-detail-pov-why {
  position: absolute;
  bottom: 0.5rem;
  left: 0.6rem;
  opacity: 0.7;
  font: 0.68rem/1 ui-monospace, Menlo, monospace;
  background: rgba(5, 8, 12, 0.7);
  padding: 0.2rem 0.4rem;
  border-radius: var(--radius-sm);
}
.gc-detail-metrics,
.gc-detail-access,
.gc-detail-ingress,
.gc-detail-lpr {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: rgba(10, 14, 19, 0.88);
  padding: 0.6rem 0.7rem;
}
.gc-detail-metrics h4,
.gc-detail-access h4,
.gc-detail-ingress h4,
.gc-detail-lpr h4 {
  margin: 0 0 0.5rem;
  font: 700 0.74rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.05em;
}
.gc-detail-metrics h4 i,
.gc-detail-ingress h4 i {
  font-style: normal;
  opacity: 0.55;
  font-weight: 400;
}
.gc-d-metric-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.3rem 0.7rem;
}
.gc-d-metric-grid li {
  display: flex;
  justify-content: space-between;
  border-bottom: 1px dotted rgba(120, 160, 180, 0.18);
  padding: 0.15rem 0;
  font-size: 0.74rem;
}
.gc-d-metric-grid span {
  opacity: 0.7;
}
.gc-detail-secops {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.7rem;
  align-items: start;
}
.gc-detail-access.is-access {
  border-color: rgba(240, 170, 90, 0.5);
}
.gc-d-access-row {
  display: flex;
  justify-content: space-between;
  padding: 0.2rem 0;
  font-size: 0.78rem;
}
.gc-d-acc-ocupado {
  color: var(--amber);
}
.gc-d-acc-libre {
  color: var(--mint);
}
.gc-d-adv-verificar {
  color: var(--amber);
}
.gc-d-adv-permitir {
  color: var(--mint);
}
.gc-d-adv-despejado {
  opacity: 0.7;
}
.gc-d-access-actions {
  display: flex;
  gap: 0.4rem;
  margin: 0.5rem 0 0.3rem;
}
.gc-d-allow,
.gc-d-deny {
  flex: 1;
  border-radius: var(--radius-md);
  padding: 0.4rem;
  font: 600 0.7rem/1 ui-monospace, Menlo, monospace;
  cursor: not-allowed;
  opacity: 0.65;
}
.gc-d-allow {
  border: 1px solid rgba(21, 224, 161, 0.45);
  background: rgba(21, 224, 161, 0.1);
  color: var(--mint);
}
.gc-d-deny {
  border: 1px solid rgba(240, 120, 110, 0.45);
  background: rgba(240, 120, 110, 0.1);
  color: #f0786e;
}
.gc-d-advisory-note,
.gc-d-lpr-foot {
  margin: 0.4rem 0 0;
  font-size: 0.66rem;
  opacity: 0.6;
  line-height: 1.3;
}
.gc-d-ingress-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.72rem;
}
.gc-d-ingress-table th {
  text-align: left;
  opacity: 0.6;
  font-weight: 600;
  border-bottom: 1px solid rgba(120, 160, 180, 0.25);
  padding: 0.2rem 0.3rem;
}
.gc-d-ingress-table td {
  padding: 0.2rem 0.3rem;
  border-bottom: 1px dotted rgba(120, 160, 180, 0.15);
}
.gc-d-plate-slot {
  opacity: 0.55;
  font-size: 0.66rem;
}
.gc-detail-lpr.is-gated {
  border-color: rgba(200, 140, 240, 0.4);
}
.gc-d-lpr-gate {
  margin: 0 0 0.5rem;
  color: #c89af0;
  font: 600 0.7rem/1.3 ui-monospace, Menlo, monospace;
}
.gc-d-lpr-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.gc-d-lpr-list li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.gc-d-plate-synth {
  font: 700 0.92rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.1em;
  border: 1px dashed rgba(200, 140, 240, 0.6);
  border-radius: var(--radius-sm);
  padding: 0.15rem 0.4rem;
  color: #d8b8f5;
}
.gc-d-lpr-list small {
  opacity: 0.55;
  font-size: 0.66rem;
}
@media (max-width: 1100px) {
  .gc-detail-body {
    grid-template-columns: 1fr;
  }
  .gc-detail-secops {
    grid-template-columns: 1fr;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ONBOARD · "DESPLEGAR DISPOSITIVO" — config mode en la vista de enjambre.
   Re-creación REPRESENTATIVA del onboarding real (probe → register → footprint →
   georef). HONESTO: discovery representativa, dispositivos DEMO-LOCAL.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Botón "＋ Desplegar dispositivo" (paso 0) + banner de cobertura.
   ZONA: RIGHT-SLOT-SUPERIOR (vista enjambre). Anclado ARRIBA de la columna derecha
   (top:72, bajo el topbar de 56px + respiro). El Puesto inspector (.swarm-overlay)
   vive ABAJO de la misma columna y crece hacia arriba con tope → los dos comparten la
   columna derecha SIN solaparse: cada uno acotado a ≈media columna. Inset 16px. */
.onboard-dock {
  position: absolute;
  right: 16px;
  top: 72px;
  z-index: 756;
  width: 318px;
  max-width: calc(100% - 32px);
}
.onboard-dock[hidden] {
  display: none;
}

.onboard-open {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 15px;
  border: 1px solid rgba(61, 139, 212, 0.5);
  border-radius: var(--radius-pill);
  background: rgba(6, 12, 18, 0.9);
  color: #eaf4ff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(6px);
}
.onboard-open:hover {
  border-color: rgba(61, 139, 212, 0.85);
  background: rgba(9, 16, 24, 0.96);
}
.onboard-badge {
  margin-left: 4px;
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  background: rgba(61, 139, 212, 0.2);
  border: 1px solid rgba(61, 139, 212, 0.4);
  font-size: 10px;
  font-weight: 600;
}

/* Banner "N objetivos sin alcance · desplegá un dispositivo" (clickeable). */
/* Banner pill: arranca a la DERECHA del rail de herramientas (left:16, 48px de ancho)
   para no taparlo; bajo el topbar (56px). Zona top, libre. */
.onboard-banner {
  position: absolute;
  top: 64px;
  left: 80px;
  z-index: 758;
  max-width: calc(100% - 96px);
  padding: 7px 13px;
  border: 1px solid rgba(242, 163, 38, 0.55);
  border-radius: var(--radius-pill);
  background: rgba(28, 18, 6, 0.9);
  color: #ffe6c2;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(6px);
  animation: onboard-banner-pulse 2.4s ease-in-out infinite;
}
.onboard-banner[hidden] {
  display: none;
}
.onboard-banner b {
  color: #ffd28a;
}
@keyframes onboard-banner-pulse {
  0%, 100% { border-color: rgba(242, 163, 38, 0.45); }
  50% { border-color: rgba(242, 163, 38, 0.9); }
}

/* El panel de 5 pasos. */
.onboard-panel {
  position: relative;
  border: 1px solid rgba(61, 139, 212, 0.34);
  border-radius: var(--radius-lg);
  background: rgba(5, 9, 14, 0.94);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(9px);
  padding: 14px 14px 12px;
  color: #dce8f4;
  font-size: 12px;
  /* acotado a ≈media columna: el dock vive arriba (top:72) y el Puesto inspector
     abajo (bottom:16, tope 50vh-28) → con este tope los dos no pueden encontrarse. */
  max-height: calc(50vh - 44px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.onboard-close {
  position: absolute;
  top: 8px;
  right: 9px;
  width: 22px;
  height: 22px;
  border: 1px solid rgba(160, 180, 200, 0.3);
  border-radius: var(--radius-md);
  background: rgba(12, 18, 24, 0.8);
  color: #c8d6e4;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.onboard-close:hover {
  border-color: rgba(160, 180, 200, 0.6);
}

.onboard-head {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-bottom: 10px;
  padding-right: 24px;
}
.onboard-head b {
  font-size: 12.5px;
  letter-spacing: 0.04em;
  color: #f0f6fc;
}
.onboard-rep {
  font-size: 10.5px;
  color: #f2a326;
  letter-spacing: 0.01em;
}

.onboard-probes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.onboard-probe-pick {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  border: 1px solid rgba(61, 139, 212, 0.22);
  border-radius: var(--radius-md);
  background: rgba(10, 16, 22, 0.7);
  color: #dce8f4;
  cursor: pointer;
}
.onboard-probe-pick:hover {
  border-color: rgba(61, 139, 212, 0.6);
  background: rgba(14, 22, 30, 0.9);
}
.onboard-probe-pick b {
  font-size: 12px;
  color: #f0f6fc;
}
.onboard-probe-meta {
  font-size: 10.5px;
  color: #93a6ba;
  font-family: ui-monospace, monospace;
}
.onboard-empty {
  font-size: 11px;
  color: var(--quiet); /* was #7a8a9a = 3.50 on the ramp (FAIL); token is AA-on-ramp */
  padding: 6px 2px;
}

.onboard-field {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 7px 0;
}
.onboard-field label {
  flex: 0 0 78px;
  font-size: 11px;
  color: #9fb2c4;
}
.onboard-field code {
  font-family: ui-monospace, monospace;
  font-size: 11px;
  color: #8fd6ff;
}
.onboard-field input[type="text"],
.onboard-field select {
  flex: 1;
  padding: 4px 7px;
  border: 1px solid rgba(120, 150, 175, 0.3);
  border-radius: var(--radius-md);
  background: rgba(10, 16, 22, 0.8);
  color: #eaf2fa;
  font-size: 11.5px;
}
.onboard-field input[type="range"] {
  flex: 1;
  accent-color: #3d8bd4;
}
.onboard-val {
  flex: 0 0 30px;
  text-align: right;
  font-family: ui-monospace, monospace;
  font-size: 11px;
  color: #cfe0f0;
}

.onboard-actions {
  display: flex;
  gap: 8px;
  margin-top: 11px;
}
.onboard-save {
  flex: 1;
  padding: 8px;
  border: 1px solid rgba(21, 224, 161, 0.5);
  border-radius: var(--radius-md);
  background: rgba(21, 224, 161, 0.16);
  color: #bfeef0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  cursor: pointer;
}
.onboard-save:hover {
  background: rgba(21, 224, 161, 0.26);
  border-color: rgba(21, 224, 161, 0.8);
}
.onboard-cancel {
  padding: 8px 12px;
  border: 1px solid rgba(160, 180, 200, 0.3);
  border-radius: var(--radius-md);
  background: rgba(12, 18, 24, 0.7);
  color: #c8d6e4;
  font-size: 11.5px;
  cursor: pointer;
}
.onboard-foot,
.onboard-saved {
  margin: 9px 0 0;
  font-size: 10px;
  line-height: 1.4;
  color: var(--muted); /* was #8295a6 = 4.01 on the ramp (FAIL); --muted is AA on the ramp */
}
.onboard-saved {
  color: #15e0a1;
  margin: 0 0 8px;
}

/* Pin DRAGGABLE de colocación (divIcon) + anillo de "config". */
.onboard-pin-wrap {
  background: transparent;
  border: 0;
}
.onboard-pin {
  display: block;
  width: 26px;
  height: 26px;
  line-height: 26px;
  text-align: center;
  font-size: 20px;
  color: #3d8bd4;
  text-shadow: 0 0 8px rgba(61, 139, 212, 0.9), 0 1px 2px rgba(0, 0, 0, 0.8);
  cursor: grab;
}
.onboard-pin:active {
  cursor: grabbing;
}

body[data-theme="light"] .onboard-panel {
  background: rgba(248, 251, 255, 0.96);
  color: #1d2a36;
  border-color: rgba(60, 120, 180, 0.3);
}
body[data-theme="light"] .onboard-probe-pick {
  background: rgba(240, 246, 252, 0.8);
  color: #1d2a36;
}
body[data-theme="light"] .onboard-probe-pick b {
  color: #0c1822;
}

/* ═══════════════════════════════════════════════════════════════════════════
   PLANIFICADOR DE COBERTURA · SET-COVER (advisory, heurístico)
   BOM + costo representativo/editable + ambas estrategias + modos + no-cubrible.
   Anclado abajo-IZQUIERDA (el onboard-dock vive a la derecha → no se pisan).
   ═══════════════════════════════════════════════════════════════════════════ */
/* ZONA: BOTTOM-LEFT-SUPERIOR (vista enjambre). Apilado SOBRE el pill del Puesto
   Guardian (.gc-open, ~40px de alto en bottom:16) → no comparten el mismo punto. La
   leyenda del campo (canvas) vive en la columna izquierda PERO arriba (bajo el zoom),
   muy por encima de esta franja inferior → no colisiona. Inset 16px. */
.coverage-dock {
  position: absolute;
  left: 16px;
  bottom: 64px;
  z-index: 757;
  width: 320px;
  max-width: calc(100% - 32px);
  max-height: calc(100vh - 140px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.coverage-dock[hidden] {
  display: none;
}
.coverage-open {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 15px;
  border: 1px solid rgba(157, 146, 234, 0.5);
  border-radius: var(--radius-pill);
  background: rgba(10, 8, 18, 0.9);
  color: #ece6ff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(6px);
}
.coverage-open:hover {
  border-color: rgba(157, 146, 234, 0.85);
  background: rgba(14, 11, 24, 0.96);
}
.coverage-card {
  border: 1px solid rgba(157, 146, 234, 0.4);
  border-radius: var(--radius-lg);
  background: rgba(8, 9, 14, 0.95);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(8px);
  padding: 12px 13px 13px;
  color: #e7e9f4;
  font-size: 12px;
  max-height: 70vh;
  overflow-y: auto;
}
.coverage-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.coverage-head strong {
  font-size: 13px;
  letter-spacing: 0.01em;
}
.coverage-close {
  border: none;
  background: transparent;
  color: #9aa0bd;
  font-size: 14px;
  cursor: pointer;
  padding: 2px 4px;
}
.coverage-close:hover {
  color: #ece6ff;
}
.coverage-advisory {
  margin: 6px 0 4px;
  font-size: 10px;
  color: #b6a8e6;
  letter-spacing: 0.02em;
}
.coverage-bom {
  margin: 4px 0 6px;
  font-size: 12px;
  line-height: 1.4;
  color: #eef0fb;
}
.coverage-bom b {
  color: #c9b9ff;
}
.coverage-bomlist ul {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.coverage-bomlist li {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  background: rgba(157, 146, 234, 0.12);
  border: 1px solid rgba(157, 146, 234, 0.3);
  font-size: 11px;
}
.coverage-bomlist b {
  color: #d6c8ff;
}
.coverage-modes {
  display: flex;
  gap: 6px;
  margin: 4px 0 8px;
}
.coverage-mode {
  flex: 1;
  padding: 6px 8px;
  border: 1px solid rgba(120, 130, 170, 0.35);
  border-radius: var(--radius-md);
  background: rgba(14, 16, 26, 0.7);
  color: #c7cbe0;
  font-size: 11px;
  cursor: pointer;
}
.coverage-mode.is-active {
  border-color: rgba(157, 146, 234, 0.8);
  background: rgba(157, 146, 234, 0.18);
  color: #ece6ff;
}
.coverage-strats {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
}
.coverage-strat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  padding: 7px 10px;
  border: 1px solid rgba(120, 130, 170, 0.3);
  border-radius: var(--radius-lg);
  background: rgba(13, 15, 24, 0.7);
  color: #d6d9ec;
  cursor: pointer;
}
.coverage-strat.is-active {
  border-color: rgba(21, 224, 161, 0.7);
  background: rgba(21, 224, 161, 0.12);
}
.coverage-strat-head {
  font-size: 12px;
  font-weight: 700;
  text-transform: capitalize;
}
.coverage-strat-head i {
  font-style: normal;
  font-weight: 500;
  font-size: 10px;
  color: #98a0c0;
  margin-left: 4px;
}
.coverage-strat-total {
  font-size: 11px;
  color: #b9bed8;
}
.coverage-strat-total b {
  color: #eef0fb;
}
.coverage-prices {
  border-top: 1px solid rgba(120, 130, 170, 0.18);
  padding-top: 8px;
  margin-bottom: 8px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px 8px;
}
.coverage-prices-note {
  grid-column: 1 / -1;
  margin: 0 0 2px;
  font-size: 10px;
  color: #8b91ad;
}
.coverage-price {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  font-size: 10.5px;
  color: #b9bed8;
}
.coverage-price input {
  width: 72px;
  padding: 3px 6px;
  border: 1px solid rgba(120, 130, 170, 0.35);
  border-radius: var(--radius-md);
  background: rgba(8, 10, 18, 0.8);
  color: #e7e9f4;
  font-size: 11px;
}
.coverage-uncov {
  margin: 0 0 8px;
  font-size: 11px;
  color: #8e96b2;
}
.coverage-uncov.is-warn {
  color: #ffb3a8;
}
.coverage-accept {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid rgba(21, 224, 161, 0.6);
  border-radius: var(--radius-lg);
  background: rgba(21, 224, 161, 0.14);
  color: #d2f1f3;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}
.coverage-accept:hover:not(:disabled) {
  background: rgba(21, 224, 161, 0.24);
}
.coverage-accept:disabled {
  opacity: 0.45;
  cursor: default;
}
.coverage-foot {
  margin: 8px 0 0;
  font-size: 9.5px;
  line-height: 1.4;
  color: #7e85a0;
}

/* ════════════════════════════════════════════════════════════════════════════
   CAPA DE PORTFOLIO POR TENANT — selector de identidad + dashboard read-only.
   Aditiva: sin tenant nada de esto se muestra (el territorio queda igual).
   ════════════════════════════════════════════════════════════════════════════ */

.tenant-switch,
.language-switch {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 4px;
  color: var(--muted);
  font-size: 12px;
}
.tenant-switch select,
.language-switch select {
  background: var(--dock);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 4px 8px;
  font: inherit;
}

.language-switch {
  margin-right: 2px;
}

.language-switch span {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.language-switch select {
  width: 116px;
  max-width: 14vw;
}

.language-switch select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Badges de relación de propiedad — el color codifica el alcance de datos. */
.pf-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  border: 1px solid var(--line);
  white-space: nowrap;
}
.pf-own {
  color: var(--mint);
  border-color: color-mix(in srgb, var(--mint) 50%, transparent);
  background: color-mix(in srgb, var(--mint) 12%, transparent);
}
.pf-subscribed {
  color: var(--blue);
  border-color: color-mix(in srgb, var(--blue) 50%, transparent);
  background: color-mix(in srgb, var(--blue) 12%, transparent);
}
.pf-shared {
  color: var(--violet);
  border-color: color-mix(in srgb, var(--violet) 50%, transparent);
  background: color-mix(in srgb, var(--violet) 12%, transparent);
}

/* Dock del dashboard — flota a la izquierda del mapa, sobre el territorio. */
/* DE-GREEDY · el portfolio (sólo territorio) ya NO abarca el alto completo (era top:84 →
   bottom:16). Se ancla arriba y se acota a 64vh → su mitad inferior izquierda queda LIBRE,
   abriendo el campo central full-bleed (#map-space) hacia abajo-izquierda. El roster
   scrollea internamente (overflow-y:auto), nada se pierde. */
.portfolio-panel {
  position: absolute;
  top: 84px;
  left: 16px;
  width: 360px;
  max-width: calc(100vw - 32px);
  max-height: min(64vh, calc(100% - 100px));
  z-index: 540;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  overflow-y: auto;
  background: var(--dock-strong);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow);
  backdrop-filter: blur(14px);
}
.portfolio-panel[hidden] {
  display: none;
}

.pf-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}
.pf-id small {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 10px;
  color: var(--quiet);
}
.pf-id h2 {
  margin: 2px 0 0;
  font-size: 18px;
  color: var(--ink);
}
.pf-close {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--muted);
  border-radius: var(--radius-md);
  width: 28px;
  height: 28px;
  cursor: pointer;
}
.pf-close:hover {
  color: var(--ink);
  border-color: var(--line-strong);
}

.pf-aggregate {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
}
.pf-aggregate > div {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 7px 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--dock);
}
.pf-aggregate b {
  font-size: 16px;
  color: var(--ink);
}
.pf-aggregate em {
  font-style: normal;
  font-size: 9px;
  color: var(--quiet);
  text-align: center;
  line-height: 1.2;
}
.pf-aggregate-relations {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.pf-section h3 {
  margin: 6px 0 6px;
  font-size: 12px;
  color: var(--ink);
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.pf-section h3 small {
  font-size: 10px;
  color: var(--quiet);
  font-weight: 400;
}

.pf-rank {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.pf-rank-row {
  display: grid;
  grid-template-columns: 20px 1fr auto auto auto;
  align-items: center;
  gap: 6px;
  padding: 5px 7px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--dock);
  cursor: pointer;
  font-size: 12px;
}
.pf-rank-row:hover,
.pf-rank-row:focus-visible {
  border-color: var(--line-strong);
  outline: none;
}
.pf-rank-n {
  color: var(--quiet);
  font-weight: 700;
}
.pf-rank-name {
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pf-rank-driver {
  font-size: 9px;
  color: var(--amber);
  letter-spacing: 0.04em;
}
.pf-rank-score {
  font-weight: 700;
  color: var(--ink);
}

.pf-feed {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-height: 160px;
  overflow-y: auto;
}
.pf-feed-row {
  font-size: 11px;
  color: var(--muted);
  padding: 3px 0;
  border-bottom: 1px dashed var(--line);
}
.pf-feed-row code,
.pf-events-abstract code {
  font-size: 10px;
  color: var(--violet);
}

.pf-empty {
  color: var(--quiet);
  font-size: 11px;
  list-style: none;
}

.pf-groups {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.pf-group h3 {
  margin: 4px 0 6px;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  text-transform: uppercase;
}
.pf-count {
  color: var(--quiet);
}
.pf-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pf-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 9px 11px;
  background: var(--dock);
  cursor: pointer;
}
.pf-card:hover,
.pf-card:focus-visible {
  border-color: var(--line-strong);
  outline: none;
}
.pf-card-own {
  border-left: 3px solid var(--mint);
}
.pf-card-subscribed {
  border-left: 3px solid var(--blue);
}
.pf-card-shared {
  border-left: 3px solid var(--violet);
}
.pf-card header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.pf-card header strong {
  font-size: 13px;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pf-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin: 6px 0 4px;
  font-size: 11px;
  color: var(--muted);
}
.pf-caps {
  font-size: 10px;
  color: var(--quiet);
  margin-bottom: 4px;
}
.pf-events-abstract {
  list-style: none;
  margin: 6px 0 4px;
  padding: 0;
  font-size: 11px;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pf-surface {
  font-size: 10px;
  padding: 4px 6px;
  border-radius: var(--radius-md);
  margin-top: 4px;
}
.pf-surface-full {
  color: var(--mint);
  background: color-mix(in srgb, var(--mint) 8%, transparent);
}
.pf-surface-summary {
  color: var(--blue);
  background: color-mix(in srgb, var(--blue) 8%, transparent);
}
.pf-surface-shared {
  color: var(--violet);
  background: color-mix(in srgb, var(--violet) 8%, transparent);
}
.pf-note {
  display: block;
  margin-top: 4px;
  font-size: 9.5px;
  color: var(--quiet);
}

/* En el drill-down de un enjambre el portfolio se oculta (no compite con la consola). */
.atlas-app[data-view="swarm"] .portfolio-panel {
  display: none;
}
/* En enjambre el detalle lo da el swarm-overlay (Puesto inspector); el right-dock
   ("detalle operativo" del TERRITORIO) es redundante + se apilaba con onboard-dock +
   swarm-overlay en la columna derecha. Ocultarlo destraba el apilamiento Y ensancha el
   campo COP (campo + conos + flota) — el right-dock era el bloqueador derecho más ancho. */
.atlas-app[data-view="swarm"] .right-dock {
  display: none;
}
/* ── "MAXIMIZAR CAMPO" (focus campo) ── el botón ⤢ del toolrail (.tool[data-tool=focus])
   colapsa los paneles laterales del enjambre para revelar el mapa completo (campo + conos +
   flota). Reversible: el mismo botón reabre. Solo en enjambre. Deslizan fuera con transición;
   el toolrail, la leyenda, el gc-open y el back quedan. */
.swarm-overlay,
.onboard-dock,
.coverage-dock,
.command-palette,
.mission-ribbon {
  transition:
    transform 0.28s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.2s ease;
}
.atlas-app[data-view="swarm"][data-focus="field"] .swarm-overlay,
.atlas-app[data-view="swarm"][data-focus="field"] .onboard-dock {
  transform: translateX(calc(100% + 24px));
  opacity: 0;
  pointer-events: none;
}
.atlas-app[data-view="swarm"][data-focus="field"] .coverage-dock {
  transform: translateX(calc(-100% - 24px));
  opacity: 0;
  pointer-events: none;
}
.atlas-app[data-view="swarm"][data-focus="field"] .command-palette,
.atlas-app[data-view="swarm"][data-focus="field"] .mission-ribbon {
  transform: translateY(calc(100% + 24px));
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .swarm-overlay,
  .onboard-dock,
  .coverage-dock,
  .command-palette,
  .mission-ribbon {
    transition: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   STAGE 3 — DISCOVERABILITY + PREMIUM MICRO-INTERACTIONS
   "Saltar a sitio…" (búsqueda del roster) + el pulido que separa "prototipo" de
   "producto": hover/focus/active con las motion tokens, active-state inconfundible,
   jerarquía glanceable de los big-numbers, estados vacío/carga y la leyenda de
   honestidad hecha tasteful. Todo sobre los tokens de DS-v2, sin literales nuevos.
   ═══════════════════════════════════════════════════════════════════════════ */

/* La columna 2 del topbar ahora envuelve scope + búsqueda en una fila. */
.scope-row {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: 0 var(--space-md);
}
.scope-row .scope {
  padding: 0;
  /* The scope is the element that gives way: it can shrink to near-zero (its
     own overflow-x scroll + fade-mask keeps the chips reachable) so the search
     and the runtime meta on its right never get pushed off-screen. */
  flex: 1 1 auto;
  min-width: 0;
}

/* ── "SALTAR A SITIO…" · campo de búsqueda + dropdown de resultados ─────────── */
.site-search {
  position: relative;
  /* Keep a stable, bounded width — the scope row (left of it) absorbs the
     slack so the search does not balloon on wide screens nor get crushed. */
  flex: 0 1 260px;
  max-width: 360px;
  min-width: 0;
  display: flex;
  align-items: center;
}
.site-search-icon {
  position: absolute;
  left: var(--space-md);
  width: 15px;
  height: 15px;
  color: var(--quiet);
  pointer-events: none;
  transition: color var(--dur-1) var(--ease-standard);
}
.site-search-icon svg {
  /* same unified brand icon set as the toolrail (24x24 grid, round caps). */
  width: 100%;
  height: 100%;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.site-search input {
  width: 100%;
  height: 32px;
  padding: 0 var(--space-md) 0 32px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface-input);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  transition:
    border-color var(--dur-1) var(--ease-standard),
    background var(--dur-1) var(--ease-standard),
    box-shadow var(--dur-2) var(--ease-standard);
}
.site-search input::placeholder {
  color: var(--quiet);
}
.site-search input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}
.site-search input:hover {
  border-color: var(--line-strong);
}
.site-search input:focus-visible {
  outline: none;
  border-color: var(--accent-line);
  background: var(--surface-1);
  box-shadow: 0 0 0 3px var(--accent-fill-soft);
}
.site-search input:focus-visible ~ .site-search-icon,
.site-search:focus-within .site-search-icon {
  color: var(--accent);
}
.site-search-results {
  position: absolute;
  top: calc(100% + var(--space-sm));
  left: 0;
  right: 0;
  margin: 0;
  padding: var(--space-xs);
  list-style: none;
  max-height: 56vh;
  overflow-y: auto;
  background: var(--dock-strong);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-2);
  backdrop-filter: blur(20px);
  z-index: 40;
  display: none;
  animation: site-search-pop var(--dur-2) var(--ease-out);
}
.site-search[data-open="true"] .site-search-results {
  display: block;
}
@keyframes site-search-pop {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.site-search-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--dur-1) var(--ease-standard);
}
.site-search-row .ss-dot {
  align-self: center;
  width: 7px;
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--mint);
  box-shadow: 0 0 8px var(--mint);
}
.site-search-row[data-vertical="blue"] .ss-dot {
  background: var(--blue);
  box-shadow: 0 0 8px var(--blue);
}
.site-search-row[data-vertical="cyan"] .ss-dot {
  background: var(--cyan);
  box-shadow: 0 0 8px var(--cyan);
}
.site-search-row[data-vertical="green"] .ss-dot {
  background: var(--green);
  box-shadow: 0 0 8px var(--green);
}
.site-search-row[data-vertical="amber"] .ss-dot {
  background: var(--amber);
  box-shadow: 0 0 8px var(--amber);
}
.site-search-row[data-vertical="gold"] .ss-dot {
  background: var(--gold);
  box-shadow: 0 0 8px var(--gold);
}
.site-search-row .ss-name {
  color: var(--ink);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.site-search-row .ss-sub {
  color: var(--ink-2);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: var(--opacity-secondary);
}
.site-search-row:hover,
.site-search-row.is-active {
  background: var(--accent-fill);
}
.site-search-empty {
  padding: var(--space-md);
  color: var(--ink-2);
  font-size: var(--fs-xs);
  text-align: center;
  opacity: var(--opacity-secondary);
}

/* ── PIN RESALTADO tras "Saltar a sitio…" — pulso temporal inconfundible ────── */
.site-pin.search-hit {
  z-index: 9000;
}
.site-pin.search-hit .ring {
  border-color: var(--node-color);
  box-shadow:
    0 0 0 2px var(--node-color),
    0 0 22px var(--node-color);
  animation: search-hit-pulse 0.9s var(--ease-out) 3;
}
.site-pin.search-hit .label {
  color: var(--ink);
  font-weight: var(--fw-semibold);
}
@keyframes search-hit-pulse {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.28);
    opacity: 0.65;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

/* ── MICRO-INTERACTIONS · hover/active feedback en los controles del topbar ─── */
.scope button,
.tabs button,
.theme-toggle,
.site-search input,
.gc-tab {
  will-change: transform;
}
.scope button:active,
.tabs button:active,
.theme-toggle:active,
.tool:active {
  transform: translateY(0.5px);
}
.scope button:hover,
.tabs button:hover {
  border-color: var(--accent-line);
}

/* ── LEYENDA DE HONESTIDAD persistente y tasteful (no clutter) ──────────────── */
.honesty-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm) var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-2);
}
.honesty-legend .hl-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  white-space: nowrap;
}
.honesty-legend .hl-swatch {
  width: 9px;
  height: 9px;
  border-radius: var(--radius-sm);
  flex: 0 0 auto;
}
.honesty-legend .hl-swatch.is-derived {
  background: var(--honesty-derived);
}
.honesty-legend .hl-swatch.is-representative {
  background: var(--honesty-representative);
}
.honesty-legend .hl-swatch.is-gated {
  background: var(--honesty-gated);
}
.honesty-legend .hl-swatch.is-roadmap {
  border: 1px dashed var(--honesty-roadmap);
  background: transparent;
}

/* H1 — reusable honest-state chip (interpolated / conflicted). Transparent fill +
   token-colored hairline + token text, so it reads as a state tag, not a solid badge.
   interpolated is used by the heatmap legend; conflicted ships styled for a future real
   producer (documented, no producer faked). */
.hstate {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-2xs);
  font-family: var(--font-mono);
  padding: 0 6px;
  border-radius: var(--radius-pill);
  border: 1px solid currentColor;
  line-height: 1.55;
  letter-spacing: 0.02em;
  opacity: 0.92;
}
.hstate--interpolated {
  color: var(--honesty-interpolated);
  border-style: dashed; /* dashed = "shown between measurements", distinct from observed */
}
.hstate--conflicted {
  color: var(--honesty-conflicted);
}

/* ── Premium honest empty-state — the ONE reusable component (KA2b·1) ─────────
   Teaches WHAT is missing, WHY (a real cause), and what UNBLOCKS it. Tokenized
   throughout (no ad-hoc literals); `grid-column:1/-1` lets it span the grid hosts
   (.node-grid/.evidence-list/.media-grid) and is a harmless no-op in flex/block. */
.empty-state {
  grid-column: 1 / -1;
  display: flex;
  gap: var(--space-sm);
  align-items: flex-start;
  padding: var(--space-md) var(--space-lg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  color: var(--muted);
  line-height: var(--lh-normal);
}
.empty-state.es-compact {
  padding: var(--space-sm) var(--space-md);
  gap: var(--space-xs);
}
.empty-state .es-mark {
  flex: none;
  width: 9px;
  height: 9px;
  margin-top: 5px;
  border-radius: 50%; /* structural circle — exempt from the radius-token sweep */
  border: 1.5px solid var(--quiet);
}
/* tone-coded marker (color only — the meaning always lives in the text). */
.empty-state .es-mark-gated {
  border-color: var(--honesty-gated);
  border-style: dashed;
}
.empty-state .es-mark-offline {
  border-color: var(--red);
}
.empty-state .es-body {
  min-width: 0;
}
.empty-state .es-what {
  display: block;
  color: var(--ink-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}
.empty-state .es-why {
  margin: var(--space-xs) 0 0;
  font-size: var(--fs-xs);
  color: var(--muted);
}
.empty-state .es-gate {
  margin-top: var(--space-xs);
  font-size: var(--fs-2xs);
  font-family: var(--font-mono);
  color: var(--honesty-gated);
}
.empty-state .es-gate code {
  color: var(--honesty-gated);
  font-family: var(--font-mono);
}
.empty-state .es-cta {
  margin-top: var(--space-xs);
  font-size: var(--fs-xs);
  color: var(--quiet);
}

/* ── Trust/Freshness badge — COMPONENTS, never a single score (KA2b·2) ─────────
   Each chip is one honest component (frescura · verificación · origen). Colors map
   onto the honesty spine: fresh/verified=ESTADO green, stale/neutral=quiet, warn=amber. */
.trust-badge {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  margin: var(--space-xs) 0 0;
}
.trust-badge .tb-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  background: var(--surface-1);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.02em;
  color: var(--ink-2);
  white-space: nowrap;
}
.trust-badge .tb-fresh,
.trust-badge .tb-verified {
  color: var(--honesty-derived);
  border-color: rgba(var(--accent-rgb), 0.4);
}
.trust-badge .tb-stale {
  color: var(--quiet);
  border-style: dashed;
}
.trust-badge .tb-warn {
  color: var(--honesty-gated);
  border-color: var(--honesty-gated);
}
.trust-badge .tb-neutral {
  color: var(--muted);
}
/* the corrupt-sidecar ledger warns loudly (KA2b·4): amber frame, never a calm $0. */
.fab-ledger.is-invalid {
  border-color: var(--honesty-gated);
  background: rgba(var(--accent-rgb), 0.04);
}
.fab-ledger.is-invalid .fab-ledger-spent {
  color: var(--honesty-gated);
}

/* ── Gate Explanation Layer — the "?" affordance (KA2b·3) ──────────────────────
   A focusable "?" whose full explanation (flag + what-it-doesn't-do + source) rides
   in the button's aria-label; sighted users get the visual note on hover/focus-within.
   No JS, no id collisions. Colors on the ACCIÓN-amber gated spine. */
.gate-explain {
  position: relative;
  display: inline-flex;
  vertical-align: baseline;
}
.gate-q {
  width: 15px;
  height: 15px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: var(--radius-pill);
  border: 1px solid var(--honesty-gated);
  background: transparent;
  color: var(--honesty-gated);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  line-height: 1;
  cursor: help;
}
.gate-q:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.gate-explain-detail {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  z-index: 40;
  display: none;
  flex-direction: column;
  gap: 3px;
  min-width: 220px;
  max-width: 320px;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  border: 1px solid var(--line-strong);
  background: var(--dock-strong);
  box-shadow: var(--elev-2);
  font-size: var(--fs-2xs);
  line-height: var(--lh-snug);
  color: var(--muted);
  text-align: left;
  white-space: normal;
}
.gate-explain:hover .gate-explain-detail,
.gate-explain:focus-within .gate-explain-detail {
  display: flex;
}
.gate-explain-detail strong {
  color: var(--ink-2);
  font-size: var(--fs-xs);
}
.gate-explain-detail .ge-reason {
  color: var(--honesty-gated);
}
.gate-explain-detail .ge-flag {
  color: var(--honesty-gated);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
}
.gate-explain-detail .ge-source {
  color: var(--quiet);
}

/* ── ESTADO DE CARGA · skeleton shimmer calmo (refina el "esperando contratos") */
.is-loading-skeleton {
  position: relative;
  overflow: hidden;
  color: transparent !important;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.is-loading-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.06),
    transparent
  );
  transform: translateX(-100%);
  animation: skeleton-shimmer 1.4s var(--ease-standard) infinite;
}
@keyframes skeleton-shimmer {
  to {
    transform: translateX(100%);
  }
}

/* ── W7 · Panel de carga · esqueleto reusable del dock mientras el primer fetch
   está en vuelo. Honestidad: sólo aparece con el endpoint en "pending" y sin dato
   aún; en cuanto el nodo responde (dato real o vacío honesto) se reemplaza — nunca
   tapa un "sin datos" resuelto (ver dockTabLoading en atlas.js). */
.panel-skeleton {
  display: grid;
  gap: 12px;
  align-content: start;
}
.panel-skeleton .pk-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  padding: 14px 15px;
  display: grid;
  gap: 10px;
}
.panel-skeleton .pk-bar {
  height: 12px;
  border-radius: var(--radius-sm);
}
.panel-skeleton .pk-title {
  height: 16px;
  width: 46%;
}
.panel-skeleton .pk-w90 {
  width: 90%;
}
.panel-skeleton .pk-w80 {
  width: 80%;
}
.panel-skeleton .pk-w70 {
  width: 70%;
}
.panel-skeleton .pk-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.panel-skeleton .pk-tile {
  height: 52px;
  border-radius: var(--radius-sm);
}
/* Visually-hidden honest label for assistive tech (announces "loading"). */
.panel-skeleton .pk-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* Respeta prefers-reduced-motion: sin shimmer, sólo el bloque calmo. */
@media (prefers-reduced-motion: reduce) {
  .is-loading-skeleton::after {
    animation: none;
  }
}

/* En el drill-down la búsqueda no compite con la consola (foco en el sitio activo). */
.atlas-app[data-view="swarm"] .site-search {
  opacity: var(--opacity-muted);
}
.atlas-app[data-view="swarm"] .site-search:focus-within {
  opacity: 1;
}

/* Responsive · la búsqueda se contrae pero sigue accesible; <760 se reacomoda
   a una fila propia (el topbar ya colapsa ahí). */
@media (max-width: 1320px) {
  .site-search {
    flex-basis: 200px;
  }
}
@media (max-width: 1080px) {
  .site-search {
    flex-basis: 160px;
  }
}
@media (max-width: 760px) {
  /* full-width on its own wrapped line — see the topbar collapse block above */
  .site-search input::placeholder {
    content: "";
  }
}

/* DESIGN-SYSTEM v2 · MOTION — respeta la preferencia de reducir movimiento.
   Las micro-interacciones (hover/focus/active) son polish, nunca esenciales. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
   P0 MOAT-KPIs · el moat info-teórico promovido a KPI de primera clase.
   green (--mint) = cobertura/derivado · amber (--amber) = acción/sim. La grammar
   de honestidad va embebida en cada elemento (chip derivado/representativo).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── KPI 1 · LEADERBOARD DE BLINDSPOTS + EIG ("qué se nos escapa, rankeado") ── */
.bs-board {
  margin: var(--space-md) 0 var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid rgba(var(--accent-rgb), 0.22);
  border-radius: var(--radius-md);
  background: rgba(20, 37, 51, 0.34);
}
.bs-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}
.bs-head strong {
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--accent);
}
.bs-chip {
  font-size: 9px;
  letter-spacing: 0.02em;
  padding: 2px var(--space-sm);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.bs-chip.is-derived {
  border: 1px solid rgba(21, 224, 161, 0.55);
  color: var(--mint);
}
.bs-sub,
.bs-empty {
  margin: 0 0 var(--space-sm);
  font-size: 9px;
  line-height: 1.4;
  color: rgba(243, 246, 248, 0.58);
}
.bs-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.bs-row {
  display: grid;
  grid-template-columns: 16px 44px 1fr auto auto;
  align-items: center;
  gap: var(--space-sm);
  font-size: 10px;
  font-family: var(--font-mono);
}
.bs-n {
  color: rgba(243, 246, 248, 0.45);
  text-align: right;
}
.bs-cell {
  color: var(--ink-2);
  white-space: nowrap;
}
.bs-row.is-uncertain .bs-cell {
  color: rgba(243, 246, 248, 0.55);
}
.bs-bar {
  height: 6px;
  border-radius: var(--radius-pill);
  background: rgba(243, 246, 248, 0.08);
  overflow: hidden;
}
.bs-bar-fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, rgba(21, 224, 161, 0.85), var(--amber));
}
.bs-score {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.bs-eig {
  color: var(--amber);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ── P2 · BLINDSPOT → COSTO DE CIERRE (BOM) · join rankedBlindspots × planCoverage ── */
.bs-bom {
  margin: var(--space-xs) 0 var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid rgba(242, 163, 38, 0.28); /* ACCIÓN amber — esto es una COTIZACIÓN (acción) */
  border-radius: var(--radius-md);
  background: rgba(242, 163, 38, 0.06);
}
.bs-bom-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}
.bs-bom-head strong {
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--amber);
}
.bs-bom-chip {
  font-size: 9px;
  letter-spacing: 0.02em;
  padding: 2px var(--space-sm);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.bs-bom-chip.is-derived {
  border: 1px solid rgba(21, 224, 161, 0.55);
  color: var(--mint);
}
.bs-bom-line {
  margin: 0 0 2px;
  font-size: 12px;
  color: var(--ink);
}
.bs-bom-bom {
  color: var(--ink);
}
.bs-bom-usd {
  color: var(--amber);
  font-variant-numeric: tabular-nums;
}
.bs-bom-arrow {
  margin: 0 0 2px;
  font-size: 10px;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.bs-bom-after {
  color: var(--mint);
}
.bs-bom-uncov {
  color: rgba(243, 246, 248, 0.55);
  font-size: 9px;
}
.bs-bom-sub,
.bs-bom-empty {
  margin: 0;
  font-size: 9px;
  line-height: 1.4;
  color: rgba(243, 246, 248, 0.55);
}

/* ── P2 · FLOTA · MAPA GEO + MATRIZ DE SUB-COBERTURA + EFICIENCIA DE COORDINACIÓN ── */
.pf-map-svg {
  display: block;
  width: 100%;
  height: 180px;
  margin: var(--space-xs) 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}
.pf-map-bg {
  fill: rgba(10, 14, 19, 0.55);
}
.pf-map-marker {
  cursor: pointer;
}
.pf-map-marker circle {
  stroke: rgba(10, 14, 19, 0.85);
  stroke-width: 0.6;
  transition: r 0.15s ease;
}
.pf-map-marker:hover circle,
.pf-map-marker:focus-visible circle {
  stroke: var(--ink);
  stroke-width: 1;
}
.pf-tint-teal,
.pf-map-marker.pf-tint-teal circle {
  fill: var(--mint);
  color: var(--mint);
}
.pf-tint-amber,
.pf-map-marker.pf-tint-amber circle {
  fill: var(--amber);
  color: var(--amber);
}
.pf-tint-neutral,
.pf-map-marker.pf-tint-neutral circle {
  fill: rgba(147, 164, 186, 0.7);
  color: rgba(147, 164, 186, 0.82);
}
.pf-map-legend {
  margin: 0;
  font-size: 9px;
  color: rgba(243, 246, 248, 0.58);
}
/* matriz de sub-cobertura */
.pf-uc-headrow,
.pf-uc-row {
  display: grid;
  grid-template-columns: 16px 1fr auto 1fr auto auto auto;
  align-items: center;
  gap: var(--space-sm);
  font-size: 10px;
}
.pf-uc-headrow {
  margin-bottom: 3px;
  font-size: 8px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(243, 246, 248, 0.45);
}
.pf-uc-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.pf-uc-row {
  cursor: pointer;
  font-family: var(--font-mono);
}
.pf-uc-row:hover,
.pf-uc-row:focus-visible {
  background: rgba(var(--accent-rgb), 0.08);
  border-radius: var(--radius-sm);
}
.pf-uc-n {
  color: rgba(243, 246, 248, 0.45);
  text-align: right;
}
.pf-uc-name {
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pf-uc-bar {
  height: 6px;
  border-radius: var(--radius-pill);
  background: rgba(243, 246, 248, 0.08);
  overflow: hidden;
}
.pf-uc-bar-fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: currentColor;
}
.pf-uc-blind,
.pf-uc-cov,
.pf-uc-stale {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
/* eficiencia de coordinación */
.pf-coord-kpi {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: var(--space-xs) 0;
}
.pf-coord-bar {
  flex: 1;
  height: 8px;
  border-radius: var(--radius-pill);
  background: rgba(243, 246, 248, 0.08);
  overflow: hidden;
}
.pf-coord-bar-fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, rgba(21, 224, 161, 0.85), var(--mint));
}
.pf-coord-eff {
  color: var(--mint);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
}
.pf-coord-kpi em {
  font-style: normal;
  font-size: 9px;
  color: rgba(243, 246, 248, 0.55);
}
.pf-coord-line {
  margin: 0 0 2px;
  font-size: 10px;
  color: var(--ink-2);
}
.pf-coord-deploy {
  color: var(--amber);
}
.pf-coord-sub,
.pf-coord-empty {
  margin: 0;
  font-size: 9px;
  line-height: 1.4;
  color: rgba(243, 246, 248, 0.55);
}

/* ── KPI 2 · TILE COBERTURA-CONFIANZA (CI + proveniencia) ── */
.kpi-card.cov-conf .cov-ci {
  font-style: normal;
  font-size: 0.78em;
  color: var(--mint);
  margin-left: 2px;
}
.cov-prov {
  display: inline-block;
  font-size: 8px;
  letter-spacing: 0.04em;
  padding: 1px 5px;
  border-radius: var(--radius-pill);
  margin-right: 4px;
  vertical-align: middle;
}
.cov-prov.is-direct {
  border: 1px solid rgba(21, 224, 161, 0.6);
  color: var(--mint);
}
.cov-prov.is-inferred {
  border: 1px dashed rgba(61, 139, 212, 0.5);
  color: rgba(143, 197, 255, 0.86);
}
.cov-prov.is-unknown {
  border: 1px dotted rgba(147, 164, 186, 0.42);
  color: rgba(147, 164, 186, 0.82);
}

/* ── KPI 3 · STRIP DE ROI DE REDUCCIÓN DE INCERTIDUMBRE ── */
.roi-strip {
  margin: var(--space-md) 0 var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid rgba(242, 163, 38, 0.26);
  border-radius: var(--radius-md);
  background: rgba(20, 37, 51, 0.34);
}
.roi-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}
.roi-head strong {
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--amber);
}
.roi-chip {
  font-size: 9px;
  letter-spacing: 0.02em;
  padding: 2px var(--space-sm);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  border: 1px dashed rgba(242, 163, 38, 0.5);
  color: var(--amber);
}
/* ROI medido en vivo (no sim): green/derivado, borde sólido — no mentir "sim"
   sobre una medición real del nodo. */
.roi-chip.is-derived {
  border: 1px solid rgba(21, 224, 161, 0.6);
  color: var(--mint);
}
/* ── Secciones del Puesto (IA) ── agrupan el muro de ~9 paneles en 3 bloques con
   header de color-honestidad: ESTADO REAL (green) → PLAN DE CIERRE (green) →
   LECTURA DE VERTICAL (ámbar/sim, <details> colapsable). El header ámbar separa
   real-vs-sim a nivel sección, no sólo por chip. */
.puesto-sec {
  margin-top: var(--space-md);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--line);
}
.puesto-sec:first-of-type {
  margin-top: var(--space-sm);
  border-top: 0;
}
.puesto-sec-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  margin: 0 0 var(--space-sm);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.puesto-sec-head span {
  margin-left: auto;
  font-weight: 600;
  font-size: 8.5px;
  letter-spacing: 0.02em;
  text-transform: none;
}
.puesto-sec-head.is-derived span {
  color: var(--mint);
}
.puesto-sec-head.is-sim span {
  color: var(--amber);
}
details.puesto-sec--vertical > summary {
  cursor: pointer;
  list-style: none;
}
details.puesto-sec--vertical > summary::-webkit-details-marker {
  display: none;
}
details.puesto-sec--vertical > summary::before {
  content: "▾";
  margin-right: 6px;
  font-size: 9px;
  color: var(--amber);
}
details.puesto-sec--vertical:not([open]) > summary::before {
  content: "▸";
}
.roi-empty {
  margin: 0;
  font-size: 9px;
  line-height: 1.4;
  color: rgba(243, 246, 248, 0.5);
}
.roi-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-sm);
}
.roi-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  background: rgba(243, 246, 248, 0.04);
}
.roi-cell span {
  font-size: 8px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: rgba(243, 246, 248, 0.5);
}
.roi-cell b {
  font-family: var(--font-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.roi-cell b.is-pos {
  color: var(--mint);
}
.roi-cell b.is-neg {
  color: var(--amber);
}
.roi-cell b.is-null {
  color: rgba(243, 246, 248, 0.4);
}

/* ── KPI 1 · ROLL-UP DE PORTFOLIO (top blindspots de la flota) ── */
.pf-bs-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.pf-bs-row {
  display: grid;
  grid-template-columns: 16px 1fr 44px auto auto;
  align-items: center;
  gap: var(--space-sm);
  font-size: 11px;
  font-family: var(--font-mono);
  padding: 4px var(--space-sm);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.pf-bs-row:hover,
.pf-bs-row:focus-visible {
  background: rgba(var(--accent-rgb), 0.12);
  outline: none;
}
.pf-bs-n {
  color: rgba(243, 246, 248, 0.45);
  text-align: right;
}
.pf-bs-name {
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pf-bs-cell {
  color: var(--ink-2);
}
.pf-bs-score {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.pf-bs-eig {
  color: var(--amber);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Light-theme: las superficies de los KPIs del moat sobre la base pálida. */
body[data-theme="light"] .bs-board,
body[data-theme="light"] .roi-strip {
  background: rgba(20, 37, 51, 0.04);
}
body[data-theme="light"] .bs-bar {
  background: rgba(20, 37, 51, 0.1);
}

/* ════════════════════════════════════════════════════════════════════════
   P1 / WAVE-2 · completitud de verticales (retail funnel+horaria / warehouse
   trends / staleness SLA). Reusa la grammar de marca: --mint green = derivado/
   estado, --amber = representativo/gated. Mismas superficies que .bs-board.
   ════════════════════════════════════════════════════════════════════════ */

/* superficie común de los paneles P1 (sembrada/representativa = borde amber) */
.rfun,
.rh,
.wt {
  margin: var(--space-md) 0 var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid rgba(242, 163, 38, 0.24);
  border-radius: var(--radius-md);
  background: rgba(20, 37, 51, 0.34);
}
.zs {
  margin: var(--space-md) 0 var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid rgba(21, 224, 161, 0.24);
  border-radius: var(--radius-md);
  background: rgba(20, 37, 51, 0.34);
}
.rfun-head,
.rh-head,
.wt-head,
.zs-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}
.rfun-head strong,
.rh-head strong,
.wt-head strong {
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--amber);
}
.zs-head strong {
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--mint);
}
.rfun-chip,
.rh-chip,
.wt-chip,
.zs-chip {
  font-size: 9px;
  letter-spacing: 0.02em;
  padding: 2px var(--space-sm);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.rfun-chip.is-sim,
.rh-chip.is-sim,
.wt-chip.is-sim {
  border: 1px dashed rgba(242, 163, 38, 0.5);
  color: var(--amber);
}
/* honest-empty PENDIENTE (endpoint embarcado · productor no publicó): gris punteado */
.rfun-chip.is-pending,
.rh-chip.is-pending,
.wt-chip.is-pending {
  border: 1px dotted rgba(147, 164, 186, 0.45);
  color: rgba(147, 164, 186, 0.82);
}
.zs-chip.is-derived {
  border: 1px solid rgba(21, 224, 161, 0.55);
  color: var(--mint);
}
.rfun-note,
.rh-note,
.wt-note,
.zs-note,
.zs-empty,
.rfun-empty,
.rh-empty,
.wt-empty,
.rfun-cap + .rfun-v ~ .rfun-note {
  margin: var(--space-xs) 0 0;
  font-size: 9px;
  line-height: 1.4;
  color: rgba(243, 246, 248, 0.55);
}
body[data-theme="light"] .rfun-empty,
body[data-theme="light"] .rh-empty,
body[data-theme="light"] .wt-empty {
  color: rgba(20, 37, 51, 0.6);
}
/* honest-empty: neutraliza el marco/encabezado amber (amber = acción/representativo) */
.rfun[data-empty],
.rh[data-empty],
.wt[data-empty] {
  border-color: rgba(147, 164, 186, 0.24);
}
.rfun[data-empty] .rfun-head strong,
.rh[data-empty] .rh-head strong,
.wt[data-empty] .wt-head strong {
  color: rgba(147, 164, 186, 0.9);
}

/* ── RETAIL · embudo con anchos proporcionales + drop-off ── */
.rfun-row {
  display: grid;
  grid-template-columns: 96px 1fr auto;
  align-items: center;
  gap: var(--space-sm);
  font-size: 10px;
  font-family: var(--font-mono);
  padding: 2px 0;
}
.rfun-l {
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rfun-bar {
  height: 12px;
  border-radius: var(--radius-sm);
  background: rgba(243, 246, 248, 0.07);
  overflow: hidden;
}
.rfun-bar-fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, rgba(21, 224, 161, 0.85), var(--amber));
}
.rfun-v {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.rfun-row.is-gated .rfun-cap {
  font-size: 9px;
  letter-spacing: 0.03em;
  color: var(--amber);
  border: 1px dashed rgba(242, 163, 38, 0.5);
  border-radius: var(--radius-pill);
  padding: 1px 6px;
  text-align: center;
}
.rfun-row.is-gated .rfun-v {
  color: rgba(243, 246, 248, 0.4);
}
.rfun-drop {
  display: flex;
  align-items: center;
  gap: 5px;
  margin: 1px 0 1px 100px;
}
.rfun-drop-chip {
  font-family: var(--font-mono);
  font-size: 9px;
  font-variant-numeric: tabular-nums;
  color: var(--amber);
  border: 1px solid rgba(242, 163, 38, 0.45);
  border-radius: var(--radius-pill);
  padding: 0 5px;
}
.rfun-drop-lbl {
  font-size: 8px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(243, 246, 248, 0.42);
}

/* ── RETAIL · serie horaria (sparkline-bar) + delta badge ── */
.rh-row {
  margin: 2px 0;
}
.rh-bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 42px;
}
.rh-bar {
  flex: 1;
  display: flex;
  align-items: flex-end;
  height: 100%;
  background: rgba(243, 246, 248, 0.05);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.rh-bar-fill {
  display: block;
  width: 100%;
  border-radius: var(--radius-sm);
  background: rgba(21, 224, 161, 0.7);
}
.rh-bar.is-peak .rh-bar-fill {
  background: var(--amber);
}
.rh-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-top: var(--space-xs);
}
.rh-total {
  font-size: 10px;
  font-family: var(--font-mono);
  color: var(--ink-2);
}
.rh-delta {
  font-size: 10px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.rh-delta.is-up {
  color: var(--mint);
  border: 1px solid rgba(21, 224, 161, 0.5);
}
.rh-delta.is-down {
  color: var(--amber);
  border: 1px solid rgba(242, 163, 38, 0.5);
}

/* ── WAREHOUSE · tendencia de incidentes + productividad por zona + near-miss ── */
.wt-sub {
  font-size: 9px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: rgba(243, 246, 248, 0.5);
  margin: var(--space-xs) 0 3px;
}
.wt-bars {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 36px;
}
.wt-bar {
  flex: 1;
  display: flex;
  align-items: flex-end;
  height: 100%;
  background: rgba(243, 246, 248, 0.05);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.wt-bar-fill {
  display: block;
  width: 100%;
  border-radius: var(--radius-sm);
  background: rgba(21, 224, 161, 0.6);
}
.wt-bar.is-hot .wt-bar-fill {
  background: var(--amber);
}
.wt-bar.is-zero .wt-bar-fill {
  background: rgba(243, 246, 248, 0.14);
}
.wt-prod {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.wt-prod-row {
  display: grid;
  grid-template-columns: 96px 1fr auto;
  align-items: center;
  gap: var(--space-sm);
  font-size: 10px;
  font-family: var(--font-mono);
}
.wt-prod-l {
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wt-prod-bar {
  height: 6px;
  border-radius: var(--radius-pill);
  background: rgba(243, 246, 248, 0.07);
  overflow: hidden;
}
.wt-prod-fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, rgba(21, 224, 161, 0.8), var(--amber));
}
.wt-prod-v {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.wt-ctx {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: var(--space-sm) 0 0;
  font-size: 10px;
  color: var(--ink-2);
}
.wt-ctx b {
  color: var(--ink);
  font-family: var(--font-mono);
}
.wt-ctx-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 6px rgba(242, 163, 38, 0.6);
}

/* ── STALENESS / FRESHNESS SLA BADGE por zona (derivado · green) ── */
.zs-list {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.zs-row {
  display: grid;
  grid-template-columns: 12px 1fr auto;
  align-items: center;
  gap: var(--space-sm);
  font-size: 10px;
  font-family: var(--font-mono);
  padding: 3px var(--space-sm);
  border-radius: var(--radius-sm);
}
.zs-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.zs-row.is-ok .zs-dot {
  background: var(--mint);
  box-shadow: 0 0 6px rgba(21, 224, 161, 0.55);
}
.zs-row.is-watch .zs-dot {
  background: var(--amber);
  box-shadow: 0 0 6px rgba(242, 163, 38, 0.55);
}
.zs-row.is-stale .zs-dot {
  background: #e5484d;
  box-shadow: 0 0 6px rgba(229, 72, 77, 0.6);
}
.zs-name {
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.zs-age {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.zs-row.is-ok .zs-age {
  color: var(--mint);
}
.zs-row.is-watch .zs-age {
  color: var(--amber);
}
.zs-row.is-stale {
  background: rgba(229, 72, 77, 0.08);
}
.zs-row.is-stale .zs-age {
  color: #f08a8d;
}

/* Light-theme: superficies P1 sobre la base pálida. */
body[data-theme="light"] .rfun,
body[data-theme="light"] .rh,
body[data-theme="light"] .wt,
body[data-theme="light"] .zs {
  background: rgba(20, 37, 51, 0.04);
}
body[data-theme="light"] .rfun-bar,
body[data-theme="light"] .rh-bar,
body[data-theme="light"] .wt-bar,
body[data-theme="light"] .wt-prod-bar {
  background: rgba(20, 37, 51, 0.1);
}

/* ── P3 / WAVE-4 · root-cause charts (delay-attribution · Pareto · scatter) ──────────
   Marca: barras green→amber por rank (el peor = amber), línea de acumulado ink. Chip
   amber representativo. Reusa la geometría de los bloques .wt/.zs (border amber-sim). */
.rcc {
  margin: var(--space-md) 0 var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid rgba(242, 163, 38, 0.24);
  border-radius: var(--radius-md);
  background: rgba(20, 37, 51, 0.34);
}
.rcc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}
.rcc-head strong {
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--amber);
}
.rcc-chip.is-sim {
  font-size: 9px;
  letter-spacing: 0.02em;
  padding: 2px var(--space-sm);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  border: 1px dashed rgba(242, 163, 38, 0.5);
  color: var(--amber);
}
/* honest-empty (sin feed AIS/TOS · roadmap): chip gris punteado, sin acento amber */
.rcc-chip.is-roadmap {
  font-size: 9px;
  letter-spacing: 0.02em;
  padding: 2px var(--space-sm);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  border: 1px dotted rgba(147, 164, 186, 0.45);
  color: rgba(147, 164, 186, 0.82);
}
/* honest-empty PENDIENTE (endpoint embarcado · productor no publicó): gris punteado,
   como roadmap pero la copia distingue "sin datos · productor no publicó". */
.rcc-chip.is-pending {
  font-size: 9px;
  letter-spacing: 0.02em;
  padding: 2px var(--space-sm);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  border: 1px dotted rgba(147, 164, 186, 0.45);
  color: rgba(147, 164, 186, 0.82);
}
.rcc-empty {
  margin: var(--space-sm) 0 0;
  font-size: 9px;
  line-height: 1.4;
  color: rgba(243, 246, 248, 0.55);
}
body[data-theme="light"] .rcc-empty {
  color: rgba(20, 37, 51, 0.6);
}
/* honest-empty: neutraliza el marco/encabezado amber (amber = acción/representativo) */
.rcc[data-empty] {
  border-color: rgba(147, 164, 186, 0.24);
}
.rcc[data-empty] .rcc-head strong {
  color: rgba(147, 164, 186, 0.9);
}
.rcc-sub {
  margin: var(--space-sm) 0 4px;
  font-size: 9px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.rcc-note {
  margin: var(--space-xs) 0 0;
  font-size: 9px;
  line-height: 1.4;
  color: rgba(243, 246, 248, 0.55);
}

/* atribución de demora · barra apilada horizontal */
.pda-bar {
  display: flex;
  height: 22px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: rgba(243, 246, 248, 0.05);
}
.pda-seg {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  font-size: 9px;
  font-family: var(--font-mono);
  color: var(--field-0); /* near-black ink label on the bright green/amber segment */
  overflow: hidden;
}
.pda-seg.is-a {
  background: var(--mint);
}
.pda-seg.is-b {
  background: rgba(21, 224, 161, 0.55);
}
.pda-seg.is-c {
  background: var(--amber);
}
.pda-seg-pct {
  white-space: nowrap;
  font-weight: 700;
}
.pda-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: 4px;
}
.pda-leg {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 9px;
  color: var(--ink-2);
}
.pda-sw {
  width: 9px;
  height: 9px;
  border-radius: var(--radius-sm);
  display: inline-block;
}
.pda-sw.is-a {
  background: var(--mint);
}
.pda-sw.is-b {
  background: rgba(21, 224, 161, 0.55);
}
.pda-sw.is-c {
  background: var(--amber);
}

/* Pareto · barras DESC + marca de acumulado (línea ink) */
.pareto {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.pareto-row {
  display: grid;
  grid-template-columns: 116px 1fr auto;
  align-items: center;
  gap: var(--space-sm);
  font-size: 10px;
  font-family: var(--font-mono);
}
.pareto-l {
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pareto-bar {
  position: relative;
  height: 8px;
  border-radius: var(--radius-pill);
  background: rgba(243, 246, 248, 0.07);
  overflow: visible;
}
.pareto-bar-fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: rgba(21, 224, 161, 0.75);
}
.pareto-row.is-worst .pareto-bar-fill {
  background: var(--amber);
}
.pareto-cum {
  position: absolute;
  top: -3px;
  width: 2px;
  height: 14px;
  background: var(--ink);
  transform: translateX(-1px);
  border-radius: var(--radius-pill);
}
.pareto-v {
  color: var(--ink);
  font-weight: 700;
}
.pareto-row.is-worst .pareto-v {
  color: var(--amber);
}

/* scatter · ocupación (x) vs near-miss (y) + coeficiente r */
.scatter {
  margin-top: 4px;
}
.scatter-plot {
  position: relative;
  height: 86px;
  border-left: 1px solid rgba(243, 246, 248, 0.2);
  border-bottom: 1px solid rgba(243, 246, 248, 0.2);
  margin: 0 0 14px 8px;
}
.scatter-dot {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--mint);
  transform: translate(-50%, 50%);
  box-shadow: 0 0 6px rgba(21, 224, 161, 0.5);
}
.scatter-dot.is-worst {
  background: var(--amber);
  box-shadow: 0 0 7px rgba(242, 163, 38, 0.6);
}
.scatter-y-lbl {
  position: absolute;
  left: -6px;
  top: -12px;
  font-size: 8px;
  color: var(--ink-2);
}
.scatter-x-lbl {
  position: absolute;
  right: 0;
  bottom: -13px;
  font-size: 8px;
  color: var(--ink-2);
}
.scatter-read {
  margin: 2px 0 0;
  font-size: 10px;
  color: var(--ink-2);
}
.scatter-r {
  font-family: var(--font-mono);
  font-weight: 700;
  padding: 1px 6px;
  border-radius: var(--radius-pill);
}
.scatter-r.is-pos {
  border: 1px solid rgba(242, 163, 38, 0.55);
  color: var(--amber);
}
.scatter-r.is-neg {
  border: 1px solid rgba(21, 224, 161, 0.55);
  color: var(--mint);
}
body[data-theme="light"] .rcc {
  background: rgba(20, 37, 51, 0.04);
}
body[data-theme="light"] .pda-bar,
body[data-theme="light"] .pareto-bar {
  background: rgba(20, 37, 51, 0.1);
}

.node-connect-toggle {
  min-height: 36px;
  padding: 0 12px;
  border: 1px solid color-mix(in srgb, var(--accent), transparent 44%);
  border-radius: var(--radius-md);
  background: var(--field-2);
  color: var(--ink);
  font-weight: 800;
  box-shadow: var(--elev-1);
}
.node-connect-toggle:focus-visible,
.node-connect-close:focus-visible,
.node-connect-controls input:focus-visible,
.node-connect-controls select:focus-visible,
.node-connect-controls button:focus-visible,
.node-connect-row:focus-visible {
  outline: 2px solid var(--mint);
  outline-offset: 2px;
}
.node-connect-panel {
  position: fixed;
  z-index: 760;
  top: 64px;
  right: min(452px, calc(100vw - 432px));
  width: min(400px, calc(100vw - 40px));
  max-height: calc(100vh - 96px);
  overflow: auto;
  padding: 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--dock-strong), white 4%), var(--dock-strong)),
    var(--dock-strong);
  color: var(--ink);
  box-shadow: var(--elev-3);
  backdrop-filter: blur(18px);
}
body[data-theme="light"] .node-connect-panel {
  background: rgba(248, 251, 253, 0.98);
  box-shadow: 0 24px 80px rgba(20, 37, 51, 0.22);
}
.node-connect-head,
.node-connected-line,
.node-live-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.node-connect-head {
  display: grid;
  align-items: start;
  grid-template-columns: 1fr auto auto;
}
.node-connect-head small,
.node-connect-head em,
.node-connected-line span,
.node-live-meta span,
.node-belief span,
.node-section-title span {
  color: var(--ink-2);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}
.node-connect-head em {
  display: block;
  margin-top: 2px;
  font-style: normal;
}
.node-connect-head strong,
.node-connected-line b,
.node-section-title strong {
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 20px;
  line-height: var(--lh-tight);
}
.node-connect-close {
  width: 28px;
  height: 28px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--ink-2);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.node-connect-close:hover {
  color: var(--ink);
  border-color: var(--line-strong);
}
.node-status {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 0 9px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
}
.node-status-ok {
  color: var(--mint);
  border: 1px solid color-mix(in srgb, var(--mint), transparent 34%);
  background: color-mix(in srgb, var(--mint), transparent 88%);
}
.node-status-warn {
  color: var(--amber);
  border: 1px solid color-mix(in srgb, var(--amber), transparent 34%);
  background: color-mix(in srgb, var(--amber), transparent 88%);
}
.node-status-block {
  color: #ff8a8a;
  border: 1px solid rgba(229, 72, 77, 0.55);
  background: rgba(229, 72, 77, 0.12);
}
body[data-theme="light"] .node-status-block {
  color: #9b2529;
}
.node-connect-controls {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  margin-top: 10px;
}
.node-connect-controls label {
  display: grid;
  gap: 5px;
  min-width: 0;
}
.node-connect-controls label span {
  color: var(--ink-2);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.node-connect-controls input {
  min-width: 0;
  height: 35px;
  padding: 0 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface-input);
  color: var(--ink);
  font-size: 13px;
}
.node-connect-controls select {
  min-width: 0;
  height: 35px;
  padding: 0 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface-input);
  color: var(--ink);
  font-size: 13px;
}
.node-connect-controls button,
.node-connect-action,
.node-open {
  min-height: 35px;
  border: 1px solid color-mix(in srgb, var(--mint), transparent 35%);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--mint), transparent 84%);
  color: var(--ink);
  font-weight: 800;
  cursor: pointer;
}
.node-connect-controls button:hover,
.node-connect-action:hover,
.node-open:hover {
  background: color-mix(in srgb, var(--mint), transparent 76%);
}
.node-connect-controls button:disabled {
  cursor: default;
  opacity: 0.58;
}
.node-onboard-grid {
  grid-template-columns: minmax(0, 1fr) auto;
}
.node-onboard-grid label,
.node-onboard-grid .node-onboard-mode,
.node-onboard-grid .node-claim-field,
.node-onboard-grid .node-onboard-mode-note,
.node-onboard-grid .node-onboard-location-actions {
  grid-column: 1 / -1;
}
.node-onboard-grid #node-create-swarm,
.node-onboard-grid #node-save-placement,
.node-onboard-grid #node-add-hardware {
  grid-column: 1 / -1;
}
.node-onboard-mode {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-2);
}
.node-onboard-mode legend,
.node-onboard-note,
.node-onboard-result small {
  color: var(--ink-2);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}
.node-onboard-mode label {
  display: inline-flex;
  grid-column: auto;
  align-items: center;
  gap: 6px;
  color: var(--ink);
  font-size: 12px;
  font-weight: 800;
}
.node-onboard-mode input {
  width: auto;
  height: auto;
}
.node-onboard-location-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.node-onboard-note {
  margin: 8px 0 0;
  line-height: var(--lh-normal);
  text-transform: none;
  letter-spacing: 0;
}
.node-onboard-result {
  display: grid;
  gap: 5px;
  margin-top: 8px;
  padding: 9px;
  border: 1px solid color-mix(in srgb, var(--mint), transparent 45%);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--mint), transparent 90%);
}
.node-onboard-result.is-gated {
  border-color: color-mix(in srgb, var(--amber), transparent 42%);
  background: color-mix(in srgb, var(--amber), transparent 88%);
}
.node-onboard-result strong {
  color: var(--ink);
  font-size: 13px;
}
.node-onboard-result span {
  color: var(--ink-2);
  font-size: 12px;
}
.node-onboard-result code {
  max-width: 100%;
  overflow: auto;
  padding: 7px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-input);
  color: var(--ink);
  font-size: 11px;
}
.node-connect-controls-manual {
  margin-top: 8px;
}
.node-connected-line {
  margin-top: 10px;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.node-connected-line b {
  max-width: 236px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  font-family: var(--font-mono);
}
.node-connect-section {
  margin-top: 10px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.node-section-title {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 10px;
}
.node-section-title strong {
  font-size: 14px;
  text-transform: none;
}
.node-connect-manual-section {
  padding: 0;
}
.node-connect-manual-section summary {
  padding: 10px;
  cursor: pointer;
  list-style: none;
}
.node-connect-manual-section summary::-webkit-details-marker {
  display: none;
}
.node-connect-manual-section[open] {
  padding-bottom: 10px;
}
.node-connect-manual-section[open] summary {
  border-bottom: 1px solid var(--line);
}
.node-connect-list {
  display: grid;
  gap: 8px;
  margin-top: 10px;
  max-height: 124px;
  overflow: auto;
}
.node-connect-row {
  display: grid;
  gap: 3px;
  width: 100%;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}
.node-connect-row:hover {
  border-color: var(--accent-line);
  background: var(--accent-fill-soft);
}
.node-row-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.node-row-main i {
  padding: 1px 7px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  color: var(--mint);
  font-size: 10px;
  font-style: normal;
  text-transform: uppercase;
}
.node-connect-empty {
  margin-top: 10px;
  padding: 12px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.node-connect-empty strong,
.node-connect-empty span {
  display: block;
}
.node-connect-empty strong {
  color: var(--ink);
  font-size: 13px;
}
.node-connect-empty span {
  margin-top: 3px;
  color: var(--ink-2);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}
.node-connect-row span,
.node-connect-row code,
.node-empty,
.node-error {
  color: var(--ink-2);
  font-size: 12px;
  line-height: var(--lh-normal);
}
.node-connect-row code {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.node-error {
  color: #ffb3b3;
  margin: 0;
}
body[data-theme="light"] .node-error {
  color: #9b2529;
}
/* ── Fase 1 federación — secciones nuevas del panel node-connect. ── */
.node-fed-grid {
  grid-template-columns: minmax(0, 1fr) auto;
}
.node-fed-grid label {
  grid-column: 1 / -1;
}
.node-fed-grid button {
  grid-column: 1 / -1;
}
.node-fed-actions {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
.node-fed-actions button {
  grid-column: auto;
}
.node-fed-list {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}
.node-fed-list li {
  display: grid;
  gap: 2px;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.node-fed-list li code {
  font-size: 12px;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.node-fed-list li span {
  font-size: 11px;
  color: var(--ink-2);
}
.node-fed-token {
  margin-top: 8px;
  display: grid;
  gap: 4px;
  padding: 9px 10px;
  border: 1px solid color-mix(in srgb, var(--mint), transparent 45%);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--mint), transparent 88%);
}
.node-fed-token code {
  font-size: 12px;
  color: var(--ink);
  word-break: break-all;
}
.node-fed-token small {
  font-size: 10px;
  color: var(--ink-2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.node-fed-allowlist {
  margin: 8px 0 0;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
}
.node-fed-allowlist legend {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-2);
}
.node-fed-check {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--ink);
}
.node-fed-roadmap {
  border-left: 2px solid color-mix(in srgb, var(--amber, #d8a657), transparent 30%);
  padding-left: 8px;
}
.node-fed-ok {
  color: var(--mint, #8ec07c);
}
.node-live {
  margin-top: 10px;
  display: grid;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.node-live-stage {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: #03060a;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
}
.node-live.is-empty .node-live-stage {
  aspect-ratio: auto;
  min-height: 92px;
}
.node-live-stage img,
.node-live-stage canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.node-live.is-empty .node-live-stage img,
.node-live.is-empty .node-live-stage canvas,
.node-live-stage img:not([src]) {
  display: none;
}
.node-live-placeholder {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #d7e5f2;
  font-size: 12px;
  pointer-events: none;
}
.node-live.has-frame .node-live-placeholder {
  display: none;
}
.node-live-meta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
}
.node-live-meta > div,
.node-belief > div,
.node-spatial {
  flex: 1;
  min-width: 0;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-2);
}
.node-live-meta .node-spatial {
  grid-column: 1 / -1;
}
.node-live-meta strong,
.node-belief strong {
  display: block;
  margin-top: 3px;
  color: var(--ink);
  font-size: 13px;
}
.node-belief {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
.node-belief .node-null {
  grid-column: 1 / -1;
}
.node-null {
  color: var(--ink-2);
}

@media (max-width: 760px) {
  .node-connect-panel {
    top: 58px;
    right: 12px;
    left: 12px;
    width: auto;
    max-height: calc(100vh - 72px);
  }
  .node-connect-controls,
  .node-live-meta,
  .node-belief {
    grid-template-columns: 1fr;
    display: grid;
  }
}
/* ── AYUDA / ONBOARDING (atlas-help.js) ─────────────────────────────────────
   Capa de ayuda contextual: botón "?" en la topbar, panel GUÍA deslizante
   (flujos + glosario) y tarjeta de primera vez. Usa los tokens del sistema. */
.help-toggle {
  font-weight: 600;
}

.help-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(420px, 92vw);
  z-index: 4000;
  background: var(--dock-strong);
  border-left: 1px solid var(--line-strong);
  box-shadow: var(--shadow);
  backdrop-filter: blur(12px);
  display: flex;
  flex-direction: column;
  color: var(--ink);
  font-family: var(--font-sans);
}
.help-panel[hidden] {
  display: none;
}
.help-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: var(--fs-md);
}
.help-close {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--muted);
  border-radius: var(--radius-md);
  width: 30px;
  height: 30px;
  cursor: pointer;
}
.help-close:hover {
  color: var(--ink);
  border-color: var(--line-strong);
}
.help-panel-body {
  overflow-y: auto;
  padding: 12px 16px 28px;
}
.help-panel-body h3 {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--mint);
  margin: 18px 0 8px;
}
.help-panel-body section:first-child h3 {
  margin-top: 4px;
}
.help-panel-body p {
  font-size: var(--fs-sm);
  color: var(--muted);
  margin: 0 0 8px;
}

/* Flujos (secuencias paso a paso) */
.help-flow {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  margin: 8px 0;
  background: var(--field-1);
}
.help-flow > summary {
  cursor: pointer;
  padding: 10px 12px;
  font-weight: 600;
  font-size: var(--fs-sm);
  color: var(--ink);
  list-style: none;
}
.help-flow > summary::-webkit-details-marker {
  display: none;
}
.help-flow > summary::before {
  content: "▸ ";
  color: var(--amber);
}
.help-flow[open] > summary::before {
  content: "▾ ";
}
.help-flow-goal {
  padding: 0 12px;
  font-style: italic;
}
.help-flow-steps {
  margin: 6px 0 12px;
  padding: 0 12px 0 30px;
  counter-reset: step;
}
.help-flow-steps li {
  margin: 8px 0;
  font-size: var(--fs-sm);
  color: var(--ink);
}
.help-flow-steps li b {
  display: block;
}
.help-flow-steps li span {
  display: block;
  color: var(--muted);
  font-size: var(--fs-xs);
  margin-top: 2px;
}

/* Glosario de botones */
.help-group {
  margin: 6px 0 14px;
}
.help-group h4 {
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--quiet);
  margin: 10px 0 4px;
}
.help-group dl {
  margin: 0;
}
.help-group dt {
  font-weight: 600;
  font-size: var(--fs-xs);
  color: var(--ink);
  margin-top: 6px;
}
.help-group dd {
  margin: 0 0 2px;
  font-size: var(--fs-xs);
  color: var(--muted);
}
.help-group dd em {
  color: var(--quiet);
  font-style: italic;
}

/* Tarjeta de primera vez */
.help-firstrun {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 4100;
  width: min(360px, 92vw);
  background: var(--field-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 16px;
  color: var(--ink);
  font-family: var(--font-sans);
}
.help-firstrun strong {
  font-family: var(--font-display);
  font-size: var(--fs-md);
}
.help-firstrun p {
  font-size: var(--fs-sm);
  color: var(--muted);
  margin: 8px 0 12px;
}
.help-firstrun-actions {
  display: flex;
  gap: 8px;
}
.help-firstrun-go {
  background: var(--amber);
  color: #1a1206;
  border: 0;
  border-radius: var(--radius-md);
  padding: 8px 12px;
  font-weight: 600;
  cursor: pointer;
}
.help-firstrun-dismiss {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 8px 12px;
  cursor: pointer;
}

/* ── Ventana Conectar / Suscribirse (reemplaza el auth-panel viejo) ────────── */
.connect-overlay{position:fixed;inset:0;z-index:9000;display:flex;align-items:center;justify-content:center;padding:24px;background:radial-gradient(1200px 600px at 50% -10%, rgba(21,224,161,.06), transparent 60%), rgba(6,9,13,.72);backdrop-filter:blur(4px)}
.connect-win{width:440px;max-width:94vw;background:var(--panel,#11161d);border:1px solid var(--line,rgba(233,239,243,.08));border-radius:var(--radius-xl);overflow:hidden;box-shadow:0 24px 60px rgba(0,0,0,.5)}
.cw-head{padding:26px 26px 4px;text-align:center}
.cw-logo{width:64px;margin-bottom:10px}
.cw-head h2{font-family:'Space Grotesk',sans-serif;font-size:22px;font-weight:600;letter-spacing:-.01em;color:var(--ink,#e9eff3);margin:0}
.cw-head p{color:var(--muted,#9aa6b2);font-size:12.5px;margin-top:3px}
.cw-tabs{display:flex;gap:4px;margin:20px 22px 0;background:#0d1219;border:1px solid var(--line,rgba(233,239,243,.08));border-radius:var(--radius-lg);padding:4px}
.cw-tab{flex:1;text-align:center;padding:9px;border-radius:var(--radius-md);font-size:13px;font-weight:600;color:var(--muted,#9aa6b2);cursor:pointer;border:0;background:transparent;font-family:'Space Grotesk',sans-serif}
.cw-tab.on{background:var(--mint,#15e0a1);color:#04130d}
.cw-body{padding:20px 26px 26px}
.cw-body label{display:block;font-size:11.5px;color:var(--muted,#9aa6b2);margin:14px 0 5px;font-family:'JetBrains Mono',monospace;letter-spacing:.02em}
.cw-body label:first-child{margin-top:0}
.cw-inp{width:100%;padding:11px 13px;border-radius:var(--radius-md);border:1px solid var(--line-strong,rgba(233,239,243,.16));background:#0d1219;color:var(--ink,#e9eff3);font-size:13.5px;outline:none;font-family:'Inter',sans-serif}
.cw-inp:focus{border-color:var(--mint,#15e0a1)}
.cw-opt{color:var(--muted,#9aa6b2);font-weight:400;font-size:.9em}
/* Fase 2 · selector de nodos (dropdown del topbar) */
.node-switcher-menu{position:fixed;z-index:9500;min-width:232px;max-width:340px;background:var(--panel,#11161d);border:1px solid var(--line-strong,rgba(233,239,243,.16));border-radius:var(--radius-lg);padding:6px;box-shadow:0 18px 44px rgba(0,0,0,.5);display:flex;flex-direction:column;gap:2px}
.node-switcher-menu .nsw-row{display:flex;align-items:center;gap:2px;border-radius:var(--radius-md)}
.node-switcher-menu .nsw-row.on{background:rgba(21,224,161,.08)}
.node-switcher-menu .nsw-item{flex:1;display:flex;align-items:center;gap:9px;padding:9px 11px;border:0;background:transparent;color:var(--ink-2,#cdd7e2);font-size:13px;text-align:left;cursor:pointer;border-radius:var(--radius-md);font-family:'Space Grotesk','Inter',sans-serif;width:100%}
.node-switcher-menu .nsw-item:hover{background:rgba(233,239,243,.05);color:var(--ink,#e9eff3)}
.node-switcher-menu .nsw-item.on{color:var(--ink,#e9eff3)}
.node-switcher-menu .nsw-dot{width:8px;height:8px;border-radius:50%;background:var(--muted,#9aa6b2);flex:0 0 auto}
.node-switcher-menu .nsw-item.on .nsw-dot,.node-switcher-menu .nsw-row.on .nsw-dot{background:var(--mint,#15e0a1);box-shadow:0 0 8px rgba(21,224,161,.6)}
.node-switcher-menu .nsw-sub{margin-left:auto;color:#5f7385;font-size:10.5px;font-family:'JetBrains Mono',ui-monospace,monospace}
.node-switcher-menu .nsw-x{border:0;background:transparent;color:#5f7385;font-size:16px;line-height:1;cursor:pointer;padding:0 9px;border-radius:var(--radius-md)}
.node-switcher-menu .nsw-x:hover{color:var(--amber,#ffb454)}
.node-switcher-menu .nsw-add{margin-top:4px;border:0;border-top:1px solid var(--line,rgba(233,239,243,.08));padding:10px 11px 8px;background:transparent;color:var(--mint,#15e0a1);font-weight:600;font-size:12.5px;text-align:left;cursor:pointer;font-family:'Space Grotesk','Inter',sans-serif;width:100%}
.node-switcher-menu .nsw-add:hover{color:var(--ink,#e9eff3)}
.cw-btn{width:100%;margin-top:18px;padding:12px;border:0;border-radius:var(--radius-md);background:var(--mint,#15e0a1);color:#04130d;font-weight:700;font-size:14.5px;cursor:pointer;font-family:'Space Grotesk',sans-serif}
.cw-sub{display:flex;justify-content:center;gap:6px;margin-top:12px;font-size:12px;color:var(--muted,#9aa6b2)}
.cw-sub a{color:var(--mint,#15e0a1);font-weight:600;cursor:pointer}
.cw-hint{font-size:11px;color:#5f7385;margin-top:12px;text-align:center;line-height:1.5}
.cw-msg{font-size:12px;color:var(--amber,#ffb454);text-align:center;margin-top:10px;min-height:1em}
.cw-q{font-size:13px;color:var(--ink-2,#cdd7e2);margin:2px 0 14px}
.cw-chips{display:grid;grid-template-columns:1fr 1fr;gap:9px}
.cw-chip{display:flex;align-items:center;gap:9px;padding:12px 13px;border-radius:var(--radius-lg);border:1px solid var(--line-strong,rgba(233,239,243,.16));background:#0d1219;cursor:pointer;font-size:13px;color:var(--ink-2,#cdd7e2)}
.cw-dot{width:9px;height:9px;border-radius:var(--radius-sm);background:var(--muted,#9aa6b2)}
.cw-chip.on{border-color:var(--mint,#15e0a1);color:var(--ink,#e9eff3)}
.cw-chip.on .cw-dot{background:var(--mint,#15e0a1)}
.cw-chip b{font-weight:600;font-family:'Space Grotesk',sans-serif}
.cw-foot{border-top:1px solid var(--line,rgba(233,239,243,.08));padding:12px 26px;text-align:center;font-family:'JetBrains Mono',monospace;font-size:9px;letter-spacing:.18em;color:#5f7385;text-transform:uppercase}
/* Fabric · Energía Libre — panel del asignador (tab Fabric) */
.fab-stats{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin:10px 0}
.fab-stats>div{background:var(--panel2,#0d1219);border:1px solid var(--line,rgba(233,239,243,.08));border-radius:var(--radius-md);padding:9px 11px;display:flex;flex-direction:column;gap:2px}
.fab-stats span{font-size:10px;letter-spacing:.04em;color:var(--muted,#9aa6b2);text-transform:uppercase;font-family:'JetBrains Mono',monospace}
.fab-stats strong{font-size:14px;color:var(--ink,#e9eff3);font-family:'Space Grotesk',sans-serif}
.fab-alert{margin:10px 0;padding:10px 12px;border-radius:var(--radius-md);background:rgba(255,180,84,.10);border:1px solid rgba(255,180,84,.4);color:var(--amber,#ffb454);font-size:12.5px}
.fab-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin:6px 0 12px}
.fab-cell{position:relative;background:var(--panel2,#0d1219);border:1px solid var(--line-strong,rgba(233,239,243,.16));border-radius:var(--radius-lg);padding:12px;min-height:74px;transition:border-color .2s,box-shadow .2s}
.fab-cell.on{border-color:var(--mint,#15e0a1);box-shadow:0 0 16px rgba(21,224,161,.22) inset,0 0 10px rgba(21,224,161,.15)}
.fab-cell.surge{border-color:var(--amber,#ffb454);box-shadow:0 0 22px rgba(255,180,84,.28)}
.fab-cell.off{opacity:.5}
.fab-cam{font-family:'Space Grotesk',sans-serif;font-weight:600;font-size:14px;color:var(--ink,#e9eff3)}
.fab-meta{font-size:11px;color:var(--muted,#9aa6b2);margin-top:2px;font-family:'JetBrains Mono',monospace}
.fab-badge{margin-top:8px;display:inline-block;font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#04130d;background:var(--mint,#15e0a1);border-radius:var(--radius-sm);padding:2px 8px;font-family:'Space Grotesk',sans-serif}
.fab-badge.idle{background:transparent;color:#3a4652;padding:2px 0}
.fab-surge{position:absolute;top:10px;right:10px;font-size:11px;font-weight:700;color:var(--amber,#ffb454)}
.fab-note{font-size:10.5px;color:#5f7385;line-height:1.5;border-top:1px solid var(--line,rgba(233,239,243,.08));padding-top:9px;margin-top:4px}
/* Heatmap de incertidumbre (tab Fabric) — canvas + leyenda de la rampa entropyColor */
.fab-heatmap{display:block;width:100%;height:200px;margin:8px 0 10px;border-radius:var(--radius-md);background:var(--field-0,#0a0e13);border:1px solid var(--line,rgba(233,239,243,.08))}
.fab-heatmap-legend{display:flex;align-items:center;gap:8px;font-size:10px;color:var(--muted,#9aa6b2);font-family:'JetBrains Mono',monospace;margin:0 0 10px}
.fab-heatmap-legend .hm-ramp{width:56px;height:8px;border-radius:var(--radius-pill);background:linear-gradient(90deg,var(--cyan,#34c7e0),var(--amber,#ffb454),var(--ink,#e9eff3))}
.fab-heatmap-legend .hm-chosen{color:var(--mint,#15e0a1);font-weight:700;margin-left:4px}
/* KA2d · Floor-plan underlay controls — upload + manual alignment (opacity/position/size).
   HONESTY: the legend declares this is a reference plan aligned by hand, NOT metric
   calibration (no meters/m²). Sober, keyboard-accessible; focus-visible rings; the
   underlay itself carries no animation, so reduced-motion needs no special-casing here. */
.fab-plan{margin:0 0 10px;padding:9px 10px;border:1px solid var(--line,rgba(233,239,243,.08));border-radius:var(--radius-md);background:var(--field-1,#10151d)}
.fab-plan-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.fab-plan-upload{display:inline-flex;align-items:center;gap:6px;cursor:pointer}
.fab-plan-upload input[type="file"]{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}
.fab-plan-upload span{padding:5px 11px;border:1px solid rgba(21,224,161,.45);border-radius:var(--radius-md);background:rgba(21,224,161,.12);color:#bfeef0;font-size:11px;font-weight:700;letter-spacing:.02em}
.fab-plan-upload:hover span{background:rgba(21,224,161,.22);border-color:rgba(21,224,161,.75)}
.fab-plan-upload input[type="file"]:focus-visible+span{outline:2px solid var(--mint,#15e0a1);outline-offset:2px}
.fab-plan-name{font-size:11px;color:var(--ink,#e9eff3);font-family:'JetBrains Mono',monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:60%}
.fab-plan-hint{font-size:10.5px;color:var(--muted,#9aa6b2)}
.fab-plan-sliders{display:grid;grid-template-columns:1fr;gap:5px;margin:9px 0 4px}
.fab-plan-row{display:flex;align-items:center;gap:9px;font-size:10.5px;color:var(--muted,#9aa6b2)}
.fab-plan-row>span{flex:0 0 68px;text-transform:lowercase;letter-spacing:.02em}
.fab-plan-row input[type="range"]{flex:1;accent-color:var(--mint,#15e0a1);min-width:80px}
.fab-plan-row input[type="range"]:focus-visible{outline:2px solid var(--mint,#15e0a1);outline-offset:3px}
.fab-plan-val{flex:0 0 40px;text-align:right;font-family:'JetBrains Mono',monospace;font-size:10.5px;color:#cfe0f0}
.fab-plan-actions{display:flex;gap:8px;margin-top:6px}
.fab-plan-btn{padding:5px 11px;border:1px solid var(--line,rgba(233,239,243,.14));border-radius:var(--radius-md);background:rgba(233,239,243,.05);color:var(--muted,#9aa6b2);font-size:10.5px;cursor:pointer}
.fab-plan-btn:hover{background:rgba(233,239,243,.1);color:var(--ink,#e9eff3)}
.fab-plan-btn:focus-visible{outline:2px solid var(--mint,#15e0a1);outline-offset:2px}
.fab-plan-remove{border-color:rgba(229,72,77,.4);color:var(--red,#e5484d)}
.fab-plan-remove:hover{background:rgba(229,72,77,.12);border-color:rgba(229,72,77,.7)}
.fab-plan-legend{font-size:9.5px;color:#5f7385;line-height:1.5;margin:8px 0 0;font-family:'JetBrains Mono',monospace}
.fab-plan-err{font-size:10.5px;color:var(--red,#e5484d);margin:6px 0 0;line-height:1.4}
.fab-plan-err[hidden]{display:none}
/* W2 · banda "por qué" del cerebro — franja compacta persistente (app-level).
   Estado del cerebro en una línea: modo · razón legible · frescura · control. */
.brain-band{display:flex;align-items:center;gap:9px;flex-wrap:wrap;flex:none;padding:6px 14px;font-size:11.5px;font-family:'JetBrains Mono',monospace;color:var(--muted,#9aa6b2);background:var(--field-1,#10151d);border-bottom:1px solid var(--line,rgba(233,239,243,.08));min-height:30px}
.brain-band .bb-dot{width:8px;height:8px;border-radius:var(--radius-pill);flex:none;background:var(--muted,#9aa6b2)}
.brain-band[data-state="live"] .bb-dot{background:var(--mint,#15e0a1);box-shadow:0 0 8px rgba(21,224,161,.6)}
.brain-band[data-state="shadow"] .bb-dot{background:var(--blue,#5b86c9)}
.brain-band[data-state="gated"] .bb-dot{background:var(--amber,#f2b33c)}
.brain-band .bb-label{text-transform:uppercase;letter-spacing:.08em;font-size:10px;color:var(--muted,#9aa6b2)}
.brain-band .bb-mode{color:var(--ink,#e9eff3);font-weight:600}
.brain-band .bb-sep{color:var(--line-strong,rgba(233,239,243,.16))}
.brain-band .bb-reason{color:var(--ink,#e9eff3)}
.brain-band .bb-meta{color:var(--muted,#9aa6b2);font-size:10.5px}
.brain-band .bb-tag{margin-left:auto;font-size:9.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;border-radius:var(--radius-sm);padding:2px 7px}
.brain-band .bb-live{color:#04130d;background:var(--mint,#15e0a1)}
.brain-band .bb-shadow{color:var(--blue,#5b86c9);background:rgba(91,134,201,.14)}
.brain-band .bb-gated{color:var(--amber,#f2b33c);background:rgba(242,179,60,.14)}
.brain-band .bb-fresh{color:var(--muted,#9aa6b2);font-size:10px;opacity:.85}
@keyframes bbReasonFlip{from{opacity:.3;transform:translateY(-2px)}to{opacity:1;transform:none}}
.brain-band.brain-band-flip .bb-reason{animation:bbReasonFlip .32s ease-out}
.brain-band{cursor:pointer;outline:none;transition:background-color .18s,border-color .18s}
.brain-band:hover,.brain-band:focus-visible{background:var(--field-2,#161d27);border-color:var(--accent-line,rgba(21,224,161,.52))}
.brain-panel-host{position:fixed;z-index:9300;right:14px;top:64px;width:min(520px,calc(100vw - 28px));max-height:calc(100vh - 82px);pointer-events:none}
.brain-panel-host[hidden]{display:none}
.brain-panel{pointer-events:auto;display:flex;flex-direction:column;gap:10px;max-height:calc(100vh - 82px);overflow:auto;background:var(--field-1,#10151d);border:1px solid var(--line-strong,rgba(233,239,243,.16));border-radius:var(--radius-lg);box-shadow:var(--elev-2,0 12px 40px rgba(0,0,0,.4));padding:12px;color:var(--ink,#e9eff3)}
.brain-panel-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:8px;border-bottom:1px solid var(--line,rgba(233,239,243,.08))}
.brain-panel-head span,.brain-section header span{display:block;font:700 10px/1 var(--font-mono,'JetBrains Mono',monospace);letter-spacing:.08em;text-transform:uppercase;color:var(--muted,#9aa6b2)}
.brain-panel-head strong{display:block;margin-top:3px;font:700 18px/1.2 var(--font-display,'Space Grotesk',sans-serif);color:var(--ink,#e9eff3)}
.brain-panel-head button{width:30px;height:30px;border-radius:var(--radius-md);border:1px solid var(--line-strong,rgba(233,239,243,.16));background:var(--surface-2,rgba(255,255,255,.06));color:var(--ink,#e9eff3);cursor:pointer}
.brain-panel-head button:focus-visible,.brain-panel button:focus-visible,.brain-panel input:focus-visible,.brain-panel select:focus-visible{outline:2px solid var(--accent,var(--mint,#15e0a1));outline-offset:2px}
.brain-panel-status{display:flex;justify-content:space-between;gap:10px;align-items:center;border:1px solid var(--line,rgba(233,239,243,.08));border-radius:var(--radius-md);background:var(--field-2,#161d27);padding:9px 10px;font-size:12px}
.brain-panel-status b{color:var(--ink,#e9eff3)}
.brain-panel-status span{color:var(--muted,#9aa6b2);font-family:var(--font-mono,'JetBrains Mono',monospace);font-size:10.5px;text-align:right;overflow-wrap:anywhere}
.brain-panel-status.ok{border-color:rgba(21,224,161,.4)}
.brain-panel-status.warn{border-color:rgba(242,179,60,.45)}
.brain-panel-error,.brain-panel-ok,.brain-empty{border-radius:var(--radius-md);padding:8px 10px;font-size:12px;line-height:1.35}
.brain-panel-error,.brain-empty.warn{background:rgba(229,72,77,.10);border:1px solid rgba(229,72,77,.36);color:#ffb8ba}
.brain-panel-ok{background:rgba(21,224,161,.10);border:1px solid rgba(21,224,161,.34);color:var(--mint,#15e0a1)}
.brain-empty{background:var(--field-2,#161d27);border:1px solid var(--line,rgba(233,239,243,.08));color:var(--muted,#9aa6b2)}
.brain-section{border:1px solid var(--line,rgba(233,239,243,.08));border-radius:var(--radius-md);background:rgba(255,255,255,.018);padding:10px}
.brain-section header{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:9px}
.brain-section header b{font:700 11px/1 var(--font-mono,'JetBrains Mono',monospace);color:var(--mint,#15e0a1)}
.brain-config-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.brain-config-grid label,.brain-knob{display:flex;flex-direction:column;gap:6px;font-size:11px;color:var(--muted,#9aa6b2)}
.brain-config-grid select,.brain-config-grid input,.brain-knob input,.brain-feedback input{min-height:34px;border-radius:var(--radius-md);border:1px solid var(--line-strong,rgba(233,239,243,.16));background:var(--surface-input,rgba(0,0,0,.26));color:var(--ink,#e9eff3);padding:7px 9px}
.brain-config-grid em,.brain-knob em{font-style:normal;font:500 10px/1.2 var(--font-mono,'JetBrains Mono',monospace);color:var(--quiet,#86909c)}
.brain-control-toggle input{width:20px;height:20px;accent-color:var(--mint,#15e0a1)}
.brain-gates{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.brain-gate{display:grid;grid-template-columns:auto 1fr;grid-template-areas:"check label" "check meta";gap:2px 7px;align-items:center;border:1px solid var(--line,rgba(233,239,243,.08));border-radius:var(--radius-md);background:var(--field-2,#161d27);padding:8px}
.brain-gate.on{border-color:rgba(21,224,161,.42);background:rgba(21,224,161,.06)}
.brain-gate input{grid-area:check;accent-color:var(--mint,#15e0a1)}
.brain-gate span{grid-area:label;font-size:12px;color:var(--ink,#e9eff3)}
.brain-gate small{grid-area:meta;font:500 10px/1.2 var(--font-mono,'JetBrains Mono',monospace);color:var(--quiet,#86909c)}
.brain-knobs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}
.brain-knob span{display:flex;flex-direction:column;gap:2px;color:var(--ink,#e9eff3)}
.brain-knob small{font:500 10px/1.2 var(--font-mono,'JetBrains Mono',monospace);color:var(--quiet,#86909c)}
.brain-feedback{display:grid;grid-template-columns:1fr 1fr auto auto;gap:8px}
.brain-feedback button,.brain-panel-actions button,.brain-approval-actions button{border:1px solid var(--line-strong,rgba(233,239,243,.16));border-radius:var(--radius-md);background:var(--field-2,#161d27);color:var(--ink,#e9eff3);min-height:34px;padding:7px 10px;cursor:pointer}
.brain-feedback button:hover,.brain-panel-actions button:hover,.brain-approval-actions button:hover{border-color:var(--accent-line,rgba(21,224,161,.52))}
.brain-panel-actions{position:sticky;bottom:-12px;display:flex;gap:8px;justify-content:flex-end;background:linear-gradient(180deg,rgba(16,21,29,0),var(--field-1,#10151d) 32%);padding-top:14px}
.brain-panel-actions .primary{background:var(--amber,#f2b33c);border-color:var(--amber,#f2b33c);color:#1a1205;font-weight:700} /* aplicar = ACCIÓN (DC) */
.brain-panel-actions .warn{background:rgba(242,179,60,.14);border-color:rgba(242,179,60,.45);color:var(--amber,#f2b33c);font-weight:700}
.brain-panel button:disabled{opacity:.45;cursor:not-allowed}
.brain-audit-list,.brain-approval-list{display:flex;flex-direction:column;gap:7px}
.brain-audit-row,.brain-approval-row{border:1px solid var(--line,rgba(233,239,243,.08));border-radius:var(--radius-md);background:var(--field-2,#161d27);padding:8px 9px}
.brain-audit-row strong,.brain-approval-row strong{display:block;color:var(--ink,#e9eff3);font-size:12px}
.brain-audit-row span,.brain-approval-row span{display:block;margin-top:2px;color:var(--muted,#9aa6b2);font-size:11px}
.brain-audit-row small{display:block;margin-top:4px;color:var(--quiet,#86909c);font:500 10px/1.3 var(--font-mono,'JetBrains Mono',monospace)}
.brain-approval-row{display:flex;align-items:center;justify-content:space-between;gap:10px}
.brain-approval-row.ok{border-color:rgba(21,224,161,.35)}
.brain-approval-row.warn{border-color:rgba(242,179,60,.32)}
.brain-approval-actions{display:flex;gap:6px;flex:none}
@media (max-width:760px){.brain-panel-host{left:10px;right:10px;top:54px;width:auto}.brain-config-grid,.brain-gates,.brain-knobs,.brain-feedback{grid-template-columns:1fr}.brain-approval-row{align-items:stretch;flex-direction:column}.brain-approval-actions{justify-content:flex-end}}
@media (prefers-reduced-motion:reduce){.brain-band.brain-band-flip .bb-reason{animation:none}.brain-band{transition:none}}
/* F4 · "¿quién recibe el cómputo?" — capacity/economics + causa por cámara + γ pulse. */
.fab-capacity{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:2px 0 10px;font-size:10.5px;font-family:'JetBrains Mono',monospace;color:var(--muted,#9aa6b2)}
.fab-cap-fixed{color:var(--mint,#15e0a1)}
.fab-cap-sep{color:var(--line-strong,rgba(233,239,243,.16))}
.fab-compute-head{display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin:2px 0 8px;font-size:11px;font-family:'JetBrains Mono',monospace;color:var(--muted,#9aa6b2);text-transform:uppercase;letter-spacing:.04em}
.fab-compute-head small{text-transform:none;letter-spacing:0;font-size:10px;opacity:.75}
.fab-cell[data-camera]{cursor:pointer;outline:none}
.fab-cell[data-camera]:focus-visible{box-shadow:0 0 0 2px var(--accent,var(--mint,#15e0a1))}
.fab-alloc{margin-top:8px;height:5px;border-radius:var(--radius-pill);background:rgba(120,134,148,.16);overflow:hidden}
.fab-alloc-fill{display:block;height:100%;border-radius:var(--radius-pill);background:var(--muted,#9aa6b2);transition:width .5s cubic-bezier(.2,.7,.2,1)}
.fab-alloc-fill.fab-alloc-on{background:var(--mint,#15e0a1)}
.fab-alloc-fill.fab-alloc-surge{background:var(--amber,#f2b33c)}
.fab-alloc-fill.fab-alloc-idle{background:rgba(120,134,148,.5)}
.fab-cause{margin-top:6px;font-size:10.5px;line-height:1.35;font-family:'JetBrains Mono',monospace;color:var(--muted,#9aa6b2)}
.fab-cause-on{color:var(--mint,#15e0a1)}
.fab-cause-surge{color:var(--amber,#f2b33c)}
@keyframes gammaRise{0%{box-shadow:none}30%{box-shadow:0 0 22px rgba(242,179,60,.55)}100%{box-shadow:none}}
.fab-cell.gamma-rise{animation:gammaRise .7s ease-out}
/* W5 · la celda consultada PULSA mientras dura el surge (atención continua, no un
   flash único). El borde ámbar de .fab-cell.surge se conserva; esto le suma latido. */
@keyframes fabSurgePulse{0%,100%{box-shadow:0 0 14px rgba(255,180,84,.20)}50%{box-shadow:0 0 26px rgba(255,180,84,.55)}}
.fab-cell.surge{animation:fabSurgePulse 1.6s var(--ease-standard,ease-in-out) infinite}
/* W5 · Ledger del oráculo — costo del cómputo elástico/nube, SIEMPRE visible (incluso
   $0 honesto cuando el dispatcher está gated). is-active = hubo gasto real; is-surging
   = hay surge en curso (correlación visual, sin implicar que el surge costó nube). */
.fab-ledger{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 8px;margin:2px 0 10px;padding:8px 10px;border-radius:var(--radius-md);border:1px solid var(--line,rgba(233,239,243,.08));background:var(--panel2,#0d1219);font-size:10.5px;font-family:'JetBrains Mono',monospace;color:var(--muted,#9aa6b2)}
.fab-ledger .fab-ledger-k{text-transform:uppercase;letter-spacing:.06em;font-size:9.5px;color:var(--quiet,#86909c)}
.fab-ledger .fab-ledger-spent{color:var(--ink,#e9eff3);font-weight:600}
.fab-ledger .fab-ledger-sep{color:var(--line-strong,rgba(233,239,243,.16))}
.fab-ledger .fab-ledger-note{flex-basis:100%;color:#5f7385;font-size:10px}
.fab-ledger.is-active{border-color:rgba(21,224,161,.34);background:rgba(21,224,161,.06)}
.fab-ledger.is-active .fab-ledger-spent{color:var(--mint,#15e0a1)}
.fab-ledger.is-surging{border-color:rgba(255,180,84,.4)}
.fab-ledger.is-surging .fab-ledger-k{color:var(--amber,#ffb454)}
@media (prefers-reduced-motion:reduce){.fab-cell.gamma-rise{animation:none}.fab-cell.surge{animation:none}.fab-alloc-fill{transition:none}}
/* W6 · Home "Mundo" — overview de un vistazo (reusa el heatmap/ledger; no computa). */
/* W6 + KA2c wow capa 2 · Operational Hero — jerarquía premium (sin dato nuevo). */
.mundo-hero{position:relative;overflow:hidden}
.mundo-hero::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:linear-gradient(90deg,var(--mint),transparent 60%);opacity:.7;pointer-events:none}
.mundo-hero>header b{color:var(--mint)}
.mundo-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:12px 0 10px}
.mundo-stats>div{position:relative;overflow:hidden;background:var(--surface-1);border:1px solid var(--line);border-radius:var(--radius-md);padding:10px 11px 9px;display:flex;flex-direction:column;gap:3px;transition:border-color .18s}
.mundo-stats>div::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:transparent;transition:background-color .18s}
.mundo-stats span{font-size:9px;letter-spacing:.06em;color:var(--muted);text-transform:uppercase;font-family:var(--font-mono)}
.mundo-stats strong{font-size:20px;line-height:1.05;color:var(--ink);font-family:var(--font-display,'Space Grotesk',sans-serif);font-variant-numeric:tabular-nums}
/* honest emphasis — derived from the SAME numbers already shown, never a new datum. */
.ms-tile.ms-on::before,.ms-tile.ms-good::before{background:var(--mint)}
.ms-tile.ms-on strong,.ms-tile.ms-good strong{color:var(--mint)}
.ms-tile.ms-hot::before{background:var(--amber)}
.ms-tile.ms-hot strong{color:var(--amber)}
.ms-tile.ms-warn::before{background:var(--red)}
.ms-tile.ms-warn strong{color:var(--red)}
.mundo-health{margin-top:2px;font-size:11px}
.mundo-brain{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:2px 0 8px;padding:9px 11px;border-radius:var(--radius-md);border:1px solid var(--line,rgba(233,239,243,.08));border-left-width:2px;background:var(--field-2,#161d27);font-size:11.5px;font-family:'JetBrains Mono',monospace}
.mundo-brain[data-state="live"]{border-left-color:var(--mint)}
.mundo-brain[data-state="shadow"]{border-left-color:var(--blue)}
.mundo-brain[data-state="gated"]{border-left-color:var(--amber)}
.mundo-brain .mb-k{text-transform:uppercase;letter-spacing:.06em;font-size:9.5px;color:var(--muted,#9aa6b2)}
.mundo-brain .mb-reason{color:var(--ink,#e9eff3)}
.mundo-brain .mb-tag{margin-left:auto;font-size:9.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;border-radius:var(--radius-sm);padding:2px 7px;color:var(--amber,#f2b33c);background:rgba(242,179,60,.14)}
.mundo-brain[data-state="live"] .mb-tag{color:#04130d;background:var(--mint,#15e0a1)}
.mundo-brain[data-state="shadow"] .mb-tag{color:var(--blue,#5b86c9);background:rgba(91,134,201,.14)}
.mundo-jump{display:flex;flex-wrap:wrap;gap:8px;margin:2px 0 4px}
.mundo-jump button{flex:1 1 auto;min-height:36px;border:1px solid var(--line-strong,rgba(233,239,243,.16));border-radius:var(--radius-md);background:var(--field-2,#161d27);color:var(--ink,#e9eff3);font-size:12px;font-family:'Space Grotesk',sans-serif;cursor:pointer;transition:border-color .18s,background-color .18s}
.mundo-jump button:hover{border-color:var(--accent-line,rgba(21,224,161,.52));background:var(--field-1,#10151d)}
.mundo-jump button:focus-visible{outline:2px solid var(--accent,var(--mint,#15e0a1));outline-offset:2px}
/* W8 · Teclado del dock — botón de ayuda (⌨) + overlay de atajos ("?"). */
.kbd-hint{min-width:34px;padding:0 9px;border:1px solid var(--line-strong,rgba(233,239,243,.16));border-radius:var(--radius-md);background:var(--field-2,#161d27);color:var(--muted,#9aa6b2);cursor:pointer;font-size:14px;line-height:1}
.kbd-hint:hover{border-color:var(--accent-line,rgba(21,224,161,.52));color:var(--ink,#e9eff3)}
.kbd-hint:focus-visible{outline:2px solid var(--accent,var(--mint,#15e0a1));outline-offset:2px}
.kbd-overlay{position:fixed;inset:0;z-index:9600;display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(4,8,13,.6);backdrop-filter:blur(2px)}
.kbd-overlay .kbd-card{width:min(420px,calc(100vw - 40px));background:var(--field-1,#10151d);border:1px solid var(--line-strong,rgba(233,239,243,.16));border-radius:var(--radius-lg);box-shadow:var(--elev-2,0 12px 40px rgba(0,0,0,.4));color:var(--ink,#e9eff3);overflow:hidden}
.kbd-overlay .kbd-card>header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 14px;border-bottom:1px solid var(--line,rgba(233,239,243,.08))}
.kbd-overlay .kbd-card>header span{font:700 12px/1 var(--font-mono,'JetBrains Mono',monospace);letter-spacing:.06em;text-transform:uppercase;color:var(--muted,#9aa6b2)}
.kbd-overlay .kbd-close{width:28px;height:28px;border-radius:var(--radius-md);border:1px solid var(--line-strong,rgba(233,239,243,.16));background:var(--surface-2,rgba(255,255,255,.06));color:var(--ink,#e9eff3);cursor:pointer}
.kbd-overlay .kbd-close:focus-visible{outline:2px solid var(--accent,var(--mint,#15e0a1));outline-offset:2px}
.kbd-overlay .kbd-rows{display:flex;flex-direction:column;gap:6px;padding:12px 14px}
.kbd-overlay .ks-row{display:flex;align-items:center;gap:12px}
.kbd-overlay .ks-keys{flex:none;min-width:78px;text-align:center;font:700 12px/1 var(--font-mono,'JetBrains Mono',monospace);color:var(--mint,#15e0a1);background:var(--field-2,#161d27);border:1px solid var(--line,rgba(233,239,243,.08));border-radius:var(--radius-sm);padding:5px 6px}
.kbd-overlay .ks-label{font-size:12.5px;color:var(--ink,#e9eff3)}
.kbd-overlay .kbd-card>footer{padding:9px 14px;border-top:1px solid var(--line,rgba(233,239,243,.08));font-size:10.5px;color:#5f7385;font-family:'JetBrains Mono',monospace}

/* ── Validación · dashboard de metric_results de TestOps (KA2c) ──────────────────
   La superficie de honestidad del programa de validación: renderiza los 4 niveles que
   el hub YA computó (confirmado=verde · parcial=ámbar · no confirmado / sin datos=gris),
   nunca recalcula. Colores por token (theme-aware); el significado vive en el texto. */
.tv-intro-copy{margin:0 0 10px;font-size:12px;line-height:1.5;color:var(--ink-2)}
.tv-intro-copy code,.tv-not-live code{font-family:var(--font-mono);font-size:11px;color:var(--ink-2)}
.tv-legend{display:flex;flex-wrap:wrap;gap:8px 14px;margin:8px 0 4px;font-size:10.5px;font-family:var(--font-mono);color:var(--muted)}
.tv-legend-item{display:inline-flex;align-items:center;gap:6px;letter-spacing:.02em}
.tv-dot{width:9px;height:9px;border-radius:50%;flex:none} /* structural circle — exempt from the radius-token sweep */
.tv-dot-confirmed{background:var(--mint)}
.tv-dot-partial{background:var(--amber)}
.tv-dot-unmet{background:var(--quiet)}
.tv-dot-nodata{background:transparent;border:1.5px dashed var(--quiet)}
/* run provenance */
.tv-run-title{margin:2px 0 8px;font-size:12.5px;color:var(--ink)}
.tv-run-meta{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin:8px 0}
.tv-run-meta>div{background:var(--surface-1);border:1px solid var(--line);border-radius:var(--radius-md);padding:7px 9px;display:flex;flex-direction:column;gap:2px;min-width:0}
.tv-run-meta span{font-size:9px;letter-spacing:.05em;text-transform:uppercase;font-family:var(--font-mono);color:var(--muted)}
.tv-run-meta strong{font-size:12px;color:var(--ink-2);font-family:var(--font-mono);word-break:break-word}
.tv-not-live{margin:8px 0;padding:7px 10px;border-left:2px solid var(--honesty-gated);background:var(--surface-1);border-radius:var(--radius-sm);font-size:11px;line-height:1.45;color:var(--muted)}
.tv-not-live b{color:var(--honesty-gated)}
/* run-level rollup + histogram (tally of the emitted levels, never a recompute) */
.tv-rollup{margin:8px 0;padding:8px 10px;border:1px solid var(--line-strong);border-radius:var(--radius-md);font-size:12px;color:var(--ink-2)}
.tv-rollup.tv-confirmed{border-color:var(--mint)}
.tv-rollup.tv-partial{border-color:var(--amber)}
.tv-histogram{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0}
.tv-hist{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:var(--radius-pill);border:1px solid var(--line-strong);font-family:var(--font-mono);font-size:11px;color:var(--ink-2)}
.tv-hist b{font-size:13px}
.tv-hist.tv-confirmed{border-color:var(--mint);color:var(--mint)}
.tv-hist.tv-partial{border-color:var(--amber);color:var(--amber)}
.tv-hist.tv-unmet{color:var(--muted)}
.tv-hist.tv-nodata{color:var(--quiet);border-style:dashed}
.tv-hist.tv-zero{opacity:.5}
/* metric cards — one per metric_results item */
.tv-metrics{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:10px;margin-top:10px}
.tv-metric{border:1px solid var(--line);border-left-width:3px;border-radius:var(--radius-md);background:var(--surface-1);padding:10px 11px;display:flex;flex-direction:column;gap:6px;min-width:0}
.tv-metric.tv-confirmed{border-left-color:var(--mint)}
.tv-metric.tv-partial{border-left-color:var(--amber)}
.tv-metric.tv-unmet{border-left-color:var(--quiet)}
.tv-metric.tv-nodata{border-left-color:var(--quiet);border-left-style:dashed}
.tv-metric-head{display:flex;align-items:center;flex-wrap:wrap;gap:6px}
.tv-level{font-family:var(--font-mono);font-size:9px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:2px 7px;border-radius:var(--radius-pill);background:var(--surface-2)}
.tv-level-confirmed{color:var(--mint);border:1px solid var(--mint)}
.tv-level-partial{color:var(--amber);border:1px solid var(--amber)}
.tv-level-unmet{color:var(--ink-2);border:1px solid var(--line-strong)}
.tv-level-nodata{color:var(--quiet);background:transparent;border:1px dashed var(--quiet)}
.tv-metric-label{font-size:12px;font-weight:600;color:var(--ink);flex:1 1 auto;min-width:0}
.tv-metric-id{font-family:var(--font-mono);font-size:9.5px;color:var(--muted);word-break:break-all}
.tv-metric-value{display:flex;align-items:baseline;gap:5px}
.tv-metric-value strong{font-size:22px;font-family:var(--font-display,'Space Grotesk',sans-serif);color:var(--ink);font-variant-numeric:tabular-nums}
.tv-unit{font-size:11px;color:var(--muted);font-family:var(--font-mono)}
.tv-claim{margin:0;font-size:11px;line-height:1.4;color:var(--muted)}
.tv-metric-foot{display:flex;flex-wrap:wrap;gap:6px;align-items:center;font-family:var(--font-mono);font-size:9.5px}
.tv-gate{padding:2px 7px;border-radius:var(--radius-sm);letter-spacing:.03em}
.tv-gate-pass{color:var(--mint);border:1px solid var(--mint)}
.tv-gate-fail{color:var(--muted);border:1px dashed var(--line-strong)}
.tv-target,.tv-samples{color:var(--quiet)}
/* actions + loader */
.tv-run-actions{margin-top:12px}
.tv-run-actions button,.tv-loader-actions button{min-height:34px;padding:0 14px;border-radius:var(--radius-md);border:1px solid var(--line-strong);background:var(--surface-2);color:var(--ink-2);font-family:var(--font-display,'Space Grotesk',sans-serif);font-size:12px;cursor:pointer;transition:border-color .18s,background-color .18s}
.tv-run-actions button:hover,.tv-loader-actions button:hover{border-color:var(--accent-line)}
.tv-run-actions button:focus-visible,.tv-loader-actions button:focus-visible,.tv-input:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.tv-input{width:100%;box-sizing:border-box;resize:vertical;min-height:64px;font-family:var(--font-mono);font-size:11px;line-height:1.45;color:var(--ink);background:var(--surface-1);border:1px solid var(--line-strong);border-radius:var(--radius-md);padding:8px 10px}
.tv-input:focus{border-color:var(--accent-line)}
.tv-loader-actions{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:8px}
.tv-loader-note{font-size:10px;color:var(--quiet);font-family:var(--font-mono)}
.tv-error{margin:8px 0 0;padding:7px 10px;border-radius:var(--radius-sm);border:1px solid var(--red);color:var(--red);background:var(--surface-1);font-size:11px;font-family:var(--font-mono)}

/* ── IDENTIDAD (ID3) — enrolar · Re-ID vs Face-ID · purgar ─────────────────────
   Re-ID (apariencia, sin identidad) y Face-ID (identidad vs galería) NUNCA se
   confunden: kind chip con color propio (Face-ID = ESTADO green, Re-ID = ACCIÓN
   amber, Desconocido = neutro). Todo sobre los tokens (radius/surface/motion). */
.id-section .id-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-md);
}
.id-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
.id-h3 {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.id-h3 small {
  color: var(--quiet);
  text-transform: none;
  letter-spacing: 0;
}
/* The privacy label — always visible governance note. */
.id-privacy {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  margin: 0;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  font-size: var(--fs-2xs);
  line-height: var(--lh-normal);
  color: var(--ink-2);
}
.id-privacy-mark {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  margin-top: 3px;
  border-radius: 50%;
  background: var(--honesty-representative);
}
/* Kind chips — the Re-ID vs Face-ID colour contract. */
.id-kind {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.id-kind--faceid {
  color: var(--mint);
  border-color: rgba(var(--accent-rgb), 0.45);
  background: rgba(var(--accent-rgb), 0.08);
}
.id-kind--reid {
  color: var(--amber);
  border-color: var(--amber);
  background: transparent;
}
.id-kind--unknown {
  color: var(--quiet);
  border-style: dashed;
}
/* Capability strip (reid_only / face_id_active). */
.id-capability {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.id-cap-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: var(--fs-2xs);
  color: var(--ink-2);
}
.id-cap-row small {
  color: var(--quiet);
  min-width: 0;
  overflow-wrap: anywhere;
}
.id-cap-state {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.04em;
}
.id-cap-state.is-on {
  color: var(--mint);
}
.id-cap-state.is-off {
  color: var(--quiet);
}
/* Match + gallery rows. */
.id-match-list,
.id-row-list,
.id-audit-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
.id-match,
.id-row {
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.id-match-head,
.id-row-head {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}
.id-name {
  font-size: var(--fs-sm);
  color: var(--ink);
}
.id-anon {
  font-size: var(--fs-2xs);
  color: var(--ink-2);
}
.id-anon code,
.id-audit-target {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--quiet);
}
.id-unknown-name {
  color: var(--quiet);
  font-style: italic;
}
.id-role,
.id-track,
.id-sim {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--quiet);
}
.id-sim {
  color: var(--mint);
}
.id-live {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--mint);
  border: 1px solid rgba(var(--accent-rgb), 0.4);
  border-radius: var(--radius-pill);
  padding: 0 6px;
}
.id-tags {
  display: inline-flex;
  gap: var(--space-xs);
  flex-wrap: wrap;
}
.id-tag {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--amber);
  border: 1px solid var(--amber);
  border-radius: var(--radius-pill);
  padding: 0 6px;
}
.id-match-actions,
.id-row-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--space-xs);
}
/* Buttons. */
.id-enrol-open,
.id-enroll-cancel,
.id-enroll-submit,
.id-purge {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  padding: 4px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-standard), color var(--dur-1) var(--ease-standard);
}
.id-enrol-open:hover,
.id-enroll-submit:hover {
  border-color: var(--accent-line);
  color: var(--ink);
}
.id-enroll-submit.primary {
  border-color: var(--accent-line);
  background: var(--accent-fill);
  color: var(--ink);
}
.id-purge {
  color: var(--red);
  border-color: var(--red);
}
.id-purge:hover {
  background: var(--red);
  color: var(--bg);
}
.id-enrol-open[disabled],
.id-enroll-submit[disabled],
.id-purge[disabled] {
  opacity: var(--opacity-muted);
  cursor: not-allowed;
}
.id-enrol-open:focus-visible,
.id-enroll-cancel:focus-visible,
.id-enroll-submit:focus-visible,
.id-purge:focus-visible,
.id-enroll-form input:focus-visible,
.id-enroll-form select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* Enrol form. */
.id-enroll-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.id-enroll-title {
  font-size: var(--fs-2xs);
  color: var(--ink);
  font-weight: var(--fw-semibold);
}
.id-enroll-form label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--quiet);
}
.id-enroll-form input,
.id-enroll-form select {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--ink);
  background: var(--surface-input);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 6px 8px;
}
.id-enroll-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-sm);
}
.id-enroll-error {
  margin: 0;
  color: var(--red);
  font-size: var(--fs-2xs);
}
.id-enroll-note,
.id-rbac-note {
  margin: 0;
  font-size: var(--fs-2xs);
  color: var(--quiet);
}
.id-rbac-note.is-denied {
  color: var(--amber);
}
/* Audit trail. */
.id-audit-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  padding: 4px var(--space-sm);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-2xs);
  color: var(--ink-2);
}
.id-audit-actor {
  color: var(--ink);
}
.id-audit-action {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.04em;
}
.id-audit-action--enroll_track {
  color: var(--mint);
}
.id-audit-action--delete {
  color: var(--red);
}
.id-audit-action--meta,
.id-audit-action--dedup {
  color: var(--amber);
}
.id-audit-when {
  margin-left: auto;
  color: var(--quiet);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
}
.id-audit-empty {
  margin: 0;
  font-size: var(--fs-2xs);
  color: var(--quiet);
}
@media (prefers-reduced-motion: reduce) {
  .id-enrol-open,
  .id-enroll-cancel,
  .id-enroll-submit,
  .id-purge {
    transition: none;
  }
}

/* ==========================================================================
   KM1 · PWA phone-portrait polish (APPEND-ONLY, additive).
   Layered ON TOP of the existing <=760px mobile treatment; these rules only
   tighten the very-narrow (<=420px) portrait case so the core one-handed flow
   "open -> see state/alerts -> connect to a node" stays usable. This is not a
   redesign: it prevents horizontal page bleed, enforces >=44px tap targets on
   topbar + dock controls, and stops the runtime meta strip from clipping. No
   pre-existing @media block is edited (KF1 owns atlas.js and other CSS work in
   parallel; these selectors are additive and safe to merge).
   ========================================================================== */
@media (max-width: 420px) {
  /* The page itself must never scroll sideways; dense panels scroll inside
     their own box (.dock-pane already has overflow:auto). */
  html,
  body {
    overflow-x: hidden;
  }

  /* Tap targets — WCAG 2.5.5: >=44px on every topbar + dock control. */
  .theme-toggle,
  .help-toggle,
  .node-connect-toggle,
  .guardian-demo-toggle,
  #run-command,
  .right-dock footer button,
  .tabs button,
  .tenant-switch select,
  .language-switch select,
  #atlas-command,
  #site-search-input {
    min-height: 44px;
  }

  .scope button {
    min-height: 40px;
    padding-top: 6px;
    padding-bottom: 6px;
  }

  /* Parked theme toggle: keep it reachable and full 44px at the top-right. */
  #theme-toggle.theme-toggle {
    top: 8px;
    height: 44px;
  }

  /* Runtime meta strip (api/mode/profile): wrap instead of clipping on the
     right edge; it is white-space:nowrap by default and overflows at ~360px. */
  .runtime {
    height: auto;
    flex-wrap: wrap;
    white-space: normal;
    border-left: 0;
    padding: 6px 10px 9px;
  }
  .runtime strong {
    max-width: 46vw;
  }

  /* Tabs: a touch wider min column so 15 labels stay legible while the row
     keeps its existing horizontal scroll. */
  .tabs {
    grid-auto-columns: minmax(96px, 1fr);
  }

  /* Defensive: very wide inner content (code blocks, tables) scrolls inside
     its own box rather than forcing the whole sheet wider than the screen. */
  .dock-pane table,
  .dock-pane pre {
    display: block;
    max-width: 100%;
    overflow-x: auto;
  }
}

/* ── FED-3 · Cartera modo GOSSIP (enjambres federados rankeados por atención) ────────────────
   Append-only. Reuses the cartera tokens (--ink/--line/--mint/--amber/--red/--radius-*). The
   federated view floats exception swarms and collapses nominal ones (management-by-exception);
   the drill panel shows the on-demand per-node breakdown. attention is an ORDER, styled as a
   quiet chip — never as a loud calibrated metric. */
.fed-swarm-list {
  display: grid;
  gap: 8px;
  padding: 10px;
}
.fed-swarm {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.035);
}
.fed-swarm.fed-exception {
  border-color: rgba(242, 179, 60, 0.44);
}
.fed-swarm.fed-stale {
  border-color: rgba(229, 72, 77, 0.44);
}
.fed-swarm.fed-nominal {
  border-color: var(--line);
}
.fed-swarm-head {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 10px;
  padding: 10px;
  border: 0;
  background: transparent;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}
.fed-swarm-head strong {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 13px;
}
.fed-swarm-meta {
  color: var(--muted);
  font-size: 11px;
  overflow-wrap: anywhere;
}
.fed-swarm-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-left: auto;
}
.fed-att {
  flex: none;
  border-radius: var(--radius-pill);
  padding: 2px 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--quiet);
  border: 1px dashed var(--line-strong);
  white-space: nowrap;
}
.fed-chip {
  flex: none;
  border-radius: var(--radius-pill);
  padding: 2px 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
  border: 1px solid var(--line);
  color: var(--ink-2);
  white-space: nowrap;
}
.fed-chip-ok {
  color: var(--mint);
  border-color: rgba(21, 224, 161, 0.5);
  background: rgba(21, 224, 161, 0.1);
}
.fed-chip-warn,
.fed-chip-stale {
  color: var(--amber);
  border-color: rgba(242, 179, 60, 0.5);
  background: rgba(242, 179, 60, 0.1);
}
.fed-chip-dark {
  color: var(--red);
  border-color: rgba(229, 72, 77, 0.5);
  background: rgba(229, 72, 77, 0.1);
}
.fed-chip-trust {
  color: var(--muted);
}
.fed-nominal {
  padding: 0 10px 10px;
}
.fed-nominal-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--muted);
  padding: 0 12px;
  font-size: 12px;
  cursor: pointer;
}
.fed-nominal-mark {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--mint);
  flex: none;
}
.fed-nominal-list {
  display: grid;
  gap: 8px;
  margin-top: 8px;
}
.fed-drill {
  margin: 0 10px 10px;
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.025);
  padding: 10px;
}
.fed-drill-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}
.fed-drill-head strong {
  color: var(--ink);
  font-size: 12px;
  overflow-wrap: anywhere;
}
.fed-drill-close {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--muted);
  min-height: 26px;
  padding: 0 10px;
  cursor: pointer;
}
.fed-drill-note {
  color: var(--ink-2);
  font-size: 12px;
}
.fed-drill-sub {
  color: var(--quiet);
  font-size: 11px;
  margin-top: 4px;
}
.fed-node-list {
  display: grid;
  gap: 8px;
}
.fed-node {
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 8px 10px;
}
.fed-node-id {
  min-width: 0;
  overflow-wrap: anywhere;
  color: var(--ink);
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.fed-node-facts {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  color: var(--muted);
  font-size: 11px;
}
.fed-node-connect {
  margin-left: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
  min-height: 28px;
  padding: 0 12px;
  cursor: pointer;
}
.fed-swarm-head:focus-visible,
.fed-nominal-toggle:focus-visible,
.fed-drill-close:focus-visible,
.fed-node-connect:focus-visible {
  outline: 2px solid var(--accent-line);
  outline-offset: 2px;
}

/* ── FED-5 · deep-link de video on-demand (carril 2: índice→origen) ─────────────
   The drill node's action row: reuse "Conectar" (FED-3) + a minty "Ver video" CTA
   that pulls THAT node's stream on-demand (switchToNode → its media tab). The
   redacted INDEX thumbnail only renders when the digest brings one (FED-1 = null). */
.fed-node-actions {
  margin-left: auto;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.fed-node-media {
  border: 1px solid var(--mint);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--mint);
  min-height: 28px;
  padding: 0 12px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.fed-node-media:hover {
  background: rgba(21, 224, 161, 0.12);
}
.fed-node-media:focus-visible {
  outline: 2px solid var(--accent-line);
  outline-offset: 2px;
}
.fed-node-thumb {
  flex-basis: 100%;
  margin: 2px 0 0;
}
.fed-node-thumb img {
  max-width: 96px;
  height: auto;
  display: block;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}
.fed-node-thumb figcaption {
  margin-top: 2px;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0.02em;
}
.fed-node-clip {
  flex-basis: 100%;
  color: var(--muted);
  border: 1px dashed var(--line);
  border-radius: var(--radius-md);
  padding: 2px 8px;
  font-size: 11px;
}

/* ==========================================================================
   MOB-1 · Atlas PWA full-responsive — remaining dense operative panels @<=420px.
   APPEND-ONLY, additive. Layers ON TOP of the KM1 <=420px block above (which
   already handled the page bleed guard `body{overflow-x:hidden}`, the topbar +
   dock chrome tap targets, the runtime strip, and the first core panels). These
   rules bring the REST of the shipped dense panels — Mundo, Nodos, Validación,
   Identidad, Cartera federada (FED-3/5), Media, Productos — to one-hand usability
   in phone-portrait. It is adaptation, not a redesign:
     · over-wide 4-column stat/tile grids reflow to 2 columns so the numbers
       stay legible instead of clipping to a sliver;
     · every PRIMARY action button + form control in the
       "open -> state/alerts -> cartera -> enter a site -> detail" flow reaches
       the 44px WCAG 2.5.5 touch minimum;
     · dense canvases need NO rule here — the Fabric uncertainty heatmap is
       width:100%;height:200px (scales inside its own box), and the node-live /
       COP tile canvases are inset:0;width:100% (contained). They never widen the
       sheet, and the body already refuses horizontal scroll.
   No pre-existing rule is edited. Only additive, more-specific overrides.
   DESKTOP-FIRST (declared, not polished here): the guardian-console / Consola de
   Puesto (.gc-*) is a fixed-height, 3-column (rail | stage | copdock) fullscreen
   overlay with `overflow:hidden`; making it stack on a phone needs an HTML/layout
   refactor (scrollable body or a tab-per-panel mobile mode), not a CSS collapse
   that would clip the lower panels — see the CLAUDE-69 STOP note. It is a
   secondary security-vertical console, outside the core mobile flow. Likewise the
   Fabric floor-plan aligner (.fab-plan-*) stays an advanced desktop-first tool;
   the core Fabric panel (stats + heatmap + cells) is already 2-col responsive.
   ========================================================================== */
@media (max-width: 420px) {
  /* Reflow: 4-column stat/tile grids are illegible at phone width. Collapse to
     2 columns; tiles keep their type size instead of clipping. (3-column
     minmax(0,1fr) grids already fit at this width, so they are left untouched.)
     None of these grids place children with an explicit `grid-column`, so a
     2-track template cannot spawn implicit overflow tracks. */
  .mundo-stats,           /* Mundo — 4 headline tiles (atlas.js:4791) */
  .media-stats,           /* Media — 4 stream stats (atlas.js:12003) */
  .product-lifecycle {    /* Productos — 4 lifecycle stages (atlas.js:11667) */
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  /* NOTE: the .sigviz-* / .pf-aggregate CSS also in this file is rendered ONLY by
     tests/_fixtures.js (per-vertical signature viz + portfolio aggregate), never
     by the shipped atlas.js — 0 emissions there — so it is not a shipped panel and
     gets no responsive rule here (would be dead CSS dressed as an operative panel). */

  /* Tap targets: raise every PRIMARY action button in the operative flow to the
     44px minimum. Inline chips/badges stay display-only (not tap targets). */
  .mundo-jump button,               /* Mundo — jump-to-tab shortcuts */
  .tv-run-actions button,           /* Validación — run / export */
  .tv-loader-actions button,
  .node-connect-controls button,    /* Nodos — connect a node (core flow) */
  .node-connect-action,
  .node-open,
  .node-fed-grid button,            /* Nodos — federation add/join form */
  .node-fed-actions button,
  .fed-swarm-head,                  /* Cartera FED-3 — tap a swarm to drill */
  .fed-nominal-toggle,
  .fed-drill-close,
  .fed-node-connect,                /* Cartera FED-3/5 — drill-row actions */
  .fed-node-media,
  .id-enrol-open,                   /* Identidad — enrol / purge governance */
  .id-enroll-cancel,
  .id-enroll-submit,
  .id-purge,
  .site-edit-actions button {       /* site edit — form actions */
    min-height: 44px;
  }

  /* Form controls in the core flow share the same 44px touch minimum
     (min-height wins over their desktop height:35px). */
  .node-connect-controls input,
  .node-connect-controls select,
  .id-enroll-form input,
  .id-enroll-form select {
    min-height: 44px;
  }

  /* Site-edit action row: stack the three buttons full-width so each keeps its
     44px height AND a legible label instead of squeezing into a 3-up row. */
  .site-edit-actions {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ── World scaffold — the empty MAP FRAME + honest overlay (UX-SPLASH · pieza 1) ──
   The world heatmap panel is NEVER blank: with no field published, the map STRUCTURE
   (the cols×rows frame) is drawn EMPTY into .world-scaffold-canvas, under a centered
   honest label that names the REAL reason (read from state.api.world, not guessed).
   STRICT HONESTY (REGLA-01): the frame is structure, not data — no colored cells, no
   fabricated heat. When the real world arrives the existing heatmap fills the same box.
   Tokens only; no new literals beyond the neutral ink veil for label legibility. */
.world-scaffold {
  position: relative;
  grid-column: 1 / -1;
  min-height: 190px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  overflow: hidden;
}
.world-scaffold.is-compact {
  min-height: 150px;
}
.world-scaffold-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.world-scaffold-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  padding: var(--space-lg);
  text-align: center;
  /* soft ink vignette so the label reads over the grid frame — not a solid fill */
  background: radial-gradient(58% 72% at 50% 50%, rgba(10, 14, 19, 0.74), rgba(10, 14, 19, 0) 100%);
}
.world-scaffold .ws-mark {
  width: 10px;
  height: 10px;
  border-radius: 50%; /* structural circle — exempt from the radius-token sweep */
  border: 1.5px solid var(--quiet);
  margin-bottom: var(--space-xs);
}
.world-scaffold .ws-mark-gated {
  border-color: var(--honesty-gated);
  border-style: dashed;
}
.world-scaffold .ws-mark-offline {
  border-color: var(--red);
}
.world-scaffold .ws-title {
  color: var(--ink-2);
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}
.world-scaffold .ws-why {
  margin: var(--space-xs) 0 0;
  max-width: 32ch;
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: var(--lh-normal);
}
.world-scaffold .ws-chips {
  margin-top: var(--space-sm);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
  justify-content: center;
}
.world-scaffold .ws-chip {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  padding: 2px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  color: var(--quiet);
}
.world-scaffold .ws-chip-cal {
  color: var(--honesty-gated);
  border-color: var(--honesty-gated);
  border-style: dashed;
}
.world-scaffold .ws-chip-ref {
  color: var(--muted);
}

/* ── UX-ONBOARD · first-run "sin nodo" screen (covers the empty geo map) ──────
   Branded welcome shown by renderOnboarding() while there is no connected node
   AND no fleet pinned. Its PRIMARY job is adding the first node. Opaque ink cover
   over #map-space (z2)/#field-canvas (z3) but BELOW the fixed panels it launches
   (node-connect-panel z760, connect-overlay z9000) so those stack on top. Theme-
   aware (tokens flip in light), reduced-motion safe, focus-visible. */
.atlas-onboarding {
  position: absolute;
  inset: 0;
  z-index: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: auto;
  padding: var(--space-lg);
  background:
    radial-gradient(1100px 520px at 50% -12%, rgba(21, 224, 161, 0.08), transparent 62%),
    radial-gradient(760px 420px at 50% 118%, rgba(61, 139, 212, 0.06), transparent 60%),
    var(--bg);
}
.atlas-onboarding[hidden] {
  display: none;
}
.atlas-onboarding-card {
  width: min(560px, 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-lg);
  animation: onboarding-in 0.5s ease-out both;
}
.atlas-onboarding-brand {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}
.atlas-onboarding-mark {
  width: 72px;
  height: 72px;
  border-radius: var(--radius-lg);
  /* subtle brand-green halo — the ISOTIPO is reused as an <img>, never redrawn */
  filter: drop-shadow(0 0 22px rgba(21, 224, 161, 0.32));
}
.atlas-onboarding-word {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}
.atlas-onboarding-word strong {
  font-family: var(--font-display);
  font-weight: var(--fw-bold, 700);
  font-size: var(--fs-hero);
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.atlas-onboarding-word span {
  font-size: var(--fs-sm);
  color: var(--mint);
  letter-spacing: 0.01em;
}
.atlas-onboarding-lead {
  margin: 0;
  max-width: 46ch;
  font-size: var(--fs-md);
  line-height: 1.5;
  color: var(--muted);
}
.atlas-onboarding-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
  width: 100%;
}
.atlas-onboarding-cta-secondary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
}
.atlas-onboarding-primary {
  appearance: none;
  cursor: pointer;
  min-width: 260px;
  padding: 14px var(--space-lg);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--mint);
  color: #0a0e13;
  font-family: var(--font-display);
  font-weight: var(--fw-semibold, 600);
  font-size: var(--fs-lg);
  letter-spacing: 0.01em;
  box-shadow: 0 12px 34px rgba(21, 224, 161, 0.24);
  transition: transform 0.16s ease, box-shadow 0.16s ease, filter 0.16s ease;
}
.atlas-onboarding-primary:hover {
  filter: brightness(1.04);
  transform: translateY(-1px);
  box-shadow: 0 16px 40px rgba(21, 224, 161, 0.3);
}
.atlas-onboarding-secondary,
.atlas-onboarding-ghost {
  appearance: none;
  cursor: pointer;
  padding: 9px var(--space-md);
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm);
  font-family: var(--font-sans);
  transition: border-color 0.16s ease, color 0.16s ease, background 0.16s ease;
}
.atlas-onboarding-secondary {
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
}
.atlas-onboarding-secondary:hover {
  border-color: var(--mint);
  color: var(--mint);
}
.atlas-onboarding-ghost {
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted);
}
.atlas-onboarding-ghost:hover {
  color: var(--ink);
  border-color: var(--line);
}
.atlas-onboarding-primary:focus-visible,
.atlas-onboarding-secondary:focus-visible,
.atlas-onboarding-ghost:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.atlas-onboarding-preview {
  margin: 0;
  position: relative;
  width: min(360px, 100%);
  padding: var(--space-md);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  background: rgba(10, 14, 19, 0.35);
}
body[data-theme="light"] .atlas-onboarding-preview {
  background: rgba(20, 37, 51, 0.04);
}
.atlas-onboarding-preview-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs, 10px);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--honesty-gated);
  color: var(--honesty-gated);
  background: var(--bg);
}
.atlas-onboarding-preview-art {
  display: block;
  width: 100%;
  height: auto;
  color: var(--quiet);
  opacity: 0.9;
}
.atlas-onboarding-preview figcaption {
  margin-top: var(--space-sm);
  font-size: var(--fs-2xs, 11px);
  line-height: 1.4;
  color: var(--quiet);
}
.atlas-onboarding-note {
  margin: 0;
  font-size: var(--fs-2xs, 11px);
  color: var(--quiet);
}
@keyframes onboarding-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .atlas-onboarding-card {
    animation: none;
  }
  .atlas-onboarding-primary,
  .atlas-onboarding-secondary,
  .atlas-onboarding-ghost {
    transition: none;
  }
  .atlas-onboarding-primary:hover {
    transform: none;
  }
}
