/* ============================================================
   Hotrack - local styles. Pairs with ../iz.css for the ECT
   header. Defines the three-pane layout, palette, heat map,
   rack elevation, details pane, menu submenus, modals, toasts,
   and dark/light/auto + high-visibility themes.
   ============================================================ */

:root {
  /* light theme defaults (override below for dark) */
  --hr-bg:        #f5f5f0;
  --hr-surface:   #ffffff;
  --hr-panel:     #fafaf6;
  --hr-ink:       #1c211e;
  --hr-ink-muted: #5c6660;
  --hr-line:      #d9d8cf;
  --hr-line-soft: #ecead8;
  --hr-room-bg:   #e9eee3;
  --hr-cell-line: rgba(0,0,0,0.07);
  --hr-rack-fill: #024230;
  --hr-rack-bord: #00694e;
  --hr-rack-sel:  #aa8a00;
  --hr-rack-err:  #c0392b;
  --hr-accent:    #00694e;
  --hr-accent-dk: #024230;
  --hr-warn-bg:   #fff3cd;
  --hr-warn-fg:   #5a4000;
  --hr-err-bg:    #fce6e6;
  --hr-err-fg:    #b81b1b;
  --hr-shadow:    0 4px 14px rgba(0,0,0,0.12);
}

html[data-theme="dark"] {
  --hr-bg:        #161916;
  --hr-surface:   #1d2220;
  --hr-panel:     #22272a;
  --hr-ink:       #d8dad2;
  --hr-ink-muted: #a4a89e;
  --hr-line:      #2c3531;
  --hr-line-soft: #2c3531;
  --hr-room-bg:   #1a201d;
  --hr-cell-line: rgba(255,255,255,0.06);
  --hr-rack-fill: #2f6f5b;
  --hr-rack-bord: #4fc3a1;
  --hr-rack-sel:  #e3b341;
  --hr-rack-err:  #e2654f;
  --hr-accent:    #4fc3a1;
  --hr-accent-dk: #024230;
  --hr-warn-bg:   #3a3416;
  --hr-warn-fg:   #ffd560;
  --hr-err-bg:    #3a1818;
  --hr-err-fg:    #ff7f7f;
  --hr-shadow:    0 4px 18px rgba(0,0,0,0.55);
}

@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] {
    --hr-bg:        #161916;
    --hr-surface:   #1d2220;
    --hr-panel:     #22272a;
    --hr-ink:       #d8dad2;
    --hr-ink-muted: #a4a89e;
    --hr-line:      #2c3531;
    --hr-line-soft: #2c3531;
    --hr-room-bg:   #1a201d;
    --hr-cell-line: rgba(255,255,255,0.06);
    --hr-rack-fill: #2f6f5b;
    --hr-rack-bord: #4fc3a1;
    --hr-rack-sel:  #e3b341;
    --hr-rack-err:  #e2654f;
    --hr-accent:    #4fc3a1;
    --hr-warn-bg:   #3a3416;
    --hr-warn-fg:   #ffd560;
    --hr-err-bg:    #3a1818;
    --hr-err-fg:    #ff7f7f;
    --hr-shadow:    0 4px 18px rgba(0,0,0,0.55);
  }
}

/* ── high-visibility: bigger fonts, heavier weight, stronger contrast ── */
html.hr-hivis {
  font-size: 17px;
}
html.hr-hivis body { font-weight: 600; }
html.hr-hivis {
  --hr-ink: #000000;
  --hr-line: #444;
  --hr-line-soft: #666;
}
html.hr-hivis[data-theme="dark"] {
  --hr-ink: #ffffff;
  --hr-line: #ddd;
  --hr-line-soft: #999;
}

/* ── shell ─────────────────────────────────────────────────── */

html, body { height: 100%; }
body {
  background: var(--hr-bg);
  color: var(--hr-ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

/* iz.css already styles .ect-header - we add dark-mode tweaks and a hide affordance */
.ect-header {
  background: var(--hr-surface);
  flex: 0 0 auto;
  padding: 4px 12px;        /* tighter than iz.css default */
}
.ect-header img {
  height: 36px;             /* shrink the ducky from iz.css's 68px */
}
.ect-header-divider {
  height: 32px;             /* match the smaller logo */
}
html[data-theme="dark"] .ect-header {
  background: var(--hr-surface);
  border-bottom-color: var(--hr-accent);
}
html[data-theme="dark"] .ect-header-title .college { color: var(--hr-accent); }
html[data-theme="dark"] .ect-header-title .school  { color: var(--hr-accent); }
html[data-theme="dark"] .ect-header-app-title .app-name { color: var(--hr-accent); }
html[data-theme="dark"] .ect-header-app-title .app-description { color: var(--hr-ink-muted); }
html[data-theme="dark"] .ect-hamburger-btn {
  border-color: var(--hr-accent);
  color: var(--hr-accent);
  background: transparent;
}
html[data-theme="dark"] .ect-hamburger-btn:hover {
  background: var(--hr-accent);
  color: var(--hr-surface);
}

@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] .ect-header { background: var(--hr-surface); border-bottom-color: var(--hr-accent); }
  html[data-theme="auto"] .ect-header-title .college { color: var(--hr-accent); }
  html[data-theme="auto"] .ect-header-title .school { color: var(--hr-accent); }
  html[data-theme="auto"] .ect-header-app-title .app-name { color: var(--hr-accent); }
  html[data-theme="auto"] .ect-header-app-title .app-description { color: var(--hr-ink-muted); }
  html[data-theme="auto"] .ect-hamburger-btn {
    border-color: var(--hr-accent); color: var(--hr-accent); background: transparent;
  }
}


/* ── menu / submenu styling override (iz.css base + our submenu) ─ */

/* ─── Hamburger menu - ENE-style light surface theme ───────────────────
   Overrides iz.css's dark-green dropdown look with ENE's lighter,
   higher-contrast menu (white surface, green border, green-dark text,
   sycamore hover). */
.ect-nav-menu {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  background: var(--hr-surface);
  border: 2px solid var(--hr-accent);
  border-radius: 8px;
  padding: 6px;
  min-width: 280px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.20);
  /* overflow stays visible so flyouts (.hr-flyout) can stick out the side */
}
.ect-nav-menu a {
  display: block;
  padding: 8px 10px;
  color: var(--hr-accent-dk);
  font-weight: 600;
  background: transparent;
  border: none;
  border-radius: 4px;
  text-decoration: none;
}
html[data-theme="dark"] .ect-nav-menu a { color: var(--hr-accent); }
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] .ect-nav-menu a { color: var(--hr-accent); }
}
.ect-nav-menu a:hover {
  background: var(--hr-line-soft);
  color: var(--hr-accent-dk);
}
html[data-theme="dark"] .ect-nav-menu a:hover { color: var(--hr-accent); }
.ect-nav-menu a.on::before { content: "✓ "; }
/* Danger item - uses the error palette regardless of theme. Spelled out
   per theme so the data-theme=dark rule above doesn't override us. */
.ect-nav-menu a.hr-menu-danger,
html[data-theme="dark"] .ect-nav-menu a.hr-menu-danger {
  color: var(--hr-err-fg);
}
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] .ect-nav-menu a.hr-menu-danger { color: var(--hr-err-fg); }
}
.ect-nav-menu a.hr-menu-danger:hover,
html[data-theme="dark"] .ect-nav-menu a.hr-menu-danger:hover {
  background: var(--hr-err-bg);
  color: var(--hr-err-fg);
}
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] .ect-nav-menu a.hr-menu-danger:hover {
    background: var(--hr-err-bg);
    color: var(--hr-err-fg);
  }
}

.ect-nav-menu .nav-divider {
  border-top: 1px solid var(--hr-line);
  margin: 4px 0;
  opacity: 1;
}

/* Toggle/cycle rows (label + state pill) - ENE's drawer-toggle layout */
.ect-nav-menu a[data-act="cycle-dark-mode"],
.ect-nav-menu a[data-act="hivis"],
.ect-nav-menu a[data-act="hide-notes"],
.ect-nav-menu a[data-act="show-kpis"],
.ect-nav-menu a[data-act="view-only"] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
/* These rows carry their own On/Off pill, so suppress the ✓ checkmark. */
.ect-nav-menu a[data-act="hivis"].on::before,
.ect-nav-menu a[data-act="hide-notes"].on::before,
.ect-nav-menu a[data-act="show-kpis"].on::before,
.ect-nav-menu a[data-act="view-only"].on::before { content: ""; }
.hr-menu-state {
  font-size: 0.78em;
  font-weight: 700;
  padding: 1px 8px;
  border-radius: 10px;
  background: var(--hr-accent);
  color: var(--hr-surface);
  letter-spacing: 0.04em;
}
/* "Off" state reads as a muted/neutral pill; "On" keeps the accent. */
.hr-menu-state.is-off {
  background: var(--hr-line);
  color: var(--hr-ink-muted);
}

/* Flyout / popout submenu - same look as the main menu, anchored to the
   left of the parent item. */
.hr-menu-flyout-host { position: relative; }
.hr-flyout {
  display: none;
  position: absolute;
  right: calc(100% + 6px);
  top: -6px;
  min-width: 220px;
  padding: 6px;
  background: var(--hr-surface);
  border: 2px solid var(--hr-accent);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.20);
  z-index: 1100;
}
.hr-flyout.open { display: block; }
/* When the Scenarios group is "replaced" by its Library sub-flyout,
   the group itself disappears so only Library is visible in the same
   slot. The DOM also moves Library up one level so its
   `right: calc(100% + 6px)` anchors against the outer host. */
.hr-flyout.hr-flyout-replaced { display: none !important; }
.hr-flyout a { font-weight: 500; }
/* Tier heading inside the scenario flyout (legacy, kept for any future
   inline grouping). Small bold uppercase label. */
.hr-menu-tier-head {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 700;
  color: var(--hr-ink-muted);
  padding: 6px 10px 2px;
  border-top: 1px solid var(--hr-line-soft);
}
.hr-menu-tier-head:first-child { border-top: 0; padding-top: 2px; }

/* Scenario category rows in the top-level scenario flyout. Each row
   pops its sub-flyout to the left; the trailing ▸ rotates to ◀ when the
   category is open. Empty categories ("(no scenarios yet)") stay
   greyed-out and non-interactive. */
.hr-scenario-cat-host > a::after {
  content: " \25B8";                                    /* ▸ */
  margin-left: 8px;
  color: var(--hr-ink-muted);
  font-size: 0.9em;
}
.hr-scenario-cat-host > a[aria-expanded="true"]::after { content: " \25C2"; }   /* ◂ */
.hr-scenario-cat-host > a[aria-disabled="true"] {
  color: var(--hr-ink-muted);
  opacity: 0.55;
  cursor: default;
}
/* Sub-flyout containing the scenarios for one category. Same surface
   look as the parent flyout, sized for the title + description card. */
.hr-scenario-cat-sub {
  min-width: 260px;
  max-width: 360px;
}
.hr-scenario-item {
  display: block;
  padding: 6px 10px;
}
.hr-scenario-item .hr-scenario-title {
  font-weight: 700;
  font-size: 0.92rem;
  line-height: 1.2;
}
.hr-scenario-item .hr-scenario-desc {
  font-size: 0.78rem;
  color: var(--hr-ink-muted);
  font-weight: 400;
  line-height: 1.3;
  margin-top: 2px;
  white-space: normal;
}
.hr-scenario-empty {
  padding: 8px 10px;
  font-style: italic;
  font-size: 0.82rem;
  color: var(--hr-ink-muted);
}
/* "External" row in the Scenario Library flyout. Mirrors the look of
   a category-host row but uses a different data-act that replaces the
   Library body with the External body. Sits at the TOP of the Library
   flyout with a bottom border to separate it from the built-in
   categories below. */
.hr-scenario-external-link {
  display: block;
  margin-bottom: 4px;
  padding-bottom: 6px !important;
  border-bottom: 1px solid var(--hr-line-soft);
}
/* Header label inside the External flyout body so users see where
   the pane swap landed them. */
.hr-external-header {
  padding: 4px 10px 6px;
  margin-bottom: 4px;
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--hr-accent);
  border-bottom: 1px solid var(--hr-line-soft);
}

/* Floating scenario-notes window (ENE parity). Non-modal - the room
   stays interactive while it's visible. Drag by the title bar. */
.hr-notes-window {
  position: fixed;
  left: 120px; top: 96px;
  width: 520px;
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 32px);
  display: flex;
  flex-direction: column;
  background: var(--hr-surface);
  border: 2px solid var(--hr-accent);
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.28);
  z-index: 1200;
  overflow: hidden;
}
.hr-notes-titlebar {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px 6px 12px;
  background: var(--hr-accent);
  color: var(--hr-surface);
  cursor: grab;
  user-select: none;
  flex: 0 0 auto;
}
.hr-notes-titlebar.hr-notes-dragging { cursor: grabbing; }
.hr-notes-name {
  flex: 1 1 auto;
  font-weight: 700;
  font-size: 0.95rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hr-notes-btn {
  border: 0;
  background: transparent;
  color: var(--hr-surface);
  width: 26px; height: 22px;
  border-radius: 4px;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.hr-notes-btn:hover { background: rgba(255,255,255,0.18); }
.hr-notes-close { font-size: 1.25rem; }
.hr-notes-body {
  padding: 12px 14px;
  overflow: auto;
  white-space: pre-wrap;
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--hr-ink);
}

/* Floating scenario-builder window (SC2). Non-modal so the room stays
   interactive while faculty author. Same drag-by-titlebar pattern as
   the notes popup. */
.hr-builder-window {
  position: fixed;
  right: 24px; top: 60px;
  width: 460px;
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 80px);
  display: flex;
  flex-direction: column;
  background: var(--hr-surface);
  border: 2px solid var(--hr-accent);
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.28);
  z-index: 1200;
  overflow: hidden;
}
.hr-builder-titlebar {
  display: flex; align-items: center;
  padding: 6px 8px 6px 12px;
  background: var(--hr-accent);
  color: var(--hr-surface);
  cursor: grab;
  user-select: none;
  flex: 0 0 auto;
}
.hr-builder-titlebar:active { cursor: grabbing; }
.hr-builder-name {
  flex: 1 1 auto;
  font-weight: 700;
  font-size: 0.95rem;
}
.hr-builder-close {
  border: 0;
  background: transparent;
  color: var(--hr-surface);
  width: 26px; height: 22px;
  border-radius: 4px;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}
.hr-builder-close:hover { background: rgba(255,255,255,0.18); }
.hr-builder-body {
  padding: 10px 14px 14px;
  overflow: auto;
  flex: 1 1 auto;
}
.hr-builder-h {
  margin: 8px 0 4px;
  color: var(--hr-accent);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.hr-builder-h:first-of-type { margin-top: 4px; }
.hr-builder-row {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 6px;
}
.hr-builder-row-block { flex-direction: column; align-items: stretch; }
/* In the column (textarea) variant the main axis is vertical, so the
   label's `flex: 0 0 110px` would make it 110px TALL - the source of
   the big gap above Notes / Goal. Reset it to size to content. */
.hr-builder-row-block .hr-builder-label { margin-bottom: 2px; flex: 0 0 auto; }
.hr-builder-label {
  flex: 0 0 110px;
  font-size: 0.82rem;
  color: var(--hr-ink-muted);
}
.hr-builder-input {
  flex: 1 1 auto;
  padding: 4px 8px;
  border: 1px solid var(--hr-line);
  border-radius: 4px;
  background: var(--hr-surface);
  color: var(--hr-ink);
  font: inherit;
  font-size: 0.85rem;
}
.hr-builder-input:focus {
  outline: 2px solid var(--hr-accent);
  outline-offset: -1px;
  border-color: var(--hr-accent);
}
textarea.hr-builder-input { font-family: ui-monospace, "SF Mono", Consolas, monospace; }
.hr-builder-preview {
  width: 100%;
  box-sizing: border-box;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 0.75rem;
  border: 1px solid var(--hr-line);
  border-radius: 4px;
  padding: 6px 8px;
  background: var(--hr-panel);
  color: var(--hr-ink);
  resize: vertical;
}
.hr-builder-actions {
  display: flex; gap: 6px;
  margin-top: 10px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.hr-builder-action {
  padding: 5px 10px;
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink);
  border-radius: 4px;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}
.hr-builder-action:hover { border-color: var(--hr-accent); color: var(--hr-accent); }
.hr-builder-primary {
  background: var(--hr-accent);
  color: var(--hr-surface);
  border-color: var(--hr-accent-dk);
  font-weight: 600;
}
.hr-builder-primary:hover { filter: brightness(1.08); color: var(--hr-surface); border-color: var(--hr-accent-dk); }

/* Administrative Tools - collapsed-by-default drawer for the dev-only
   CSV/state exports. */
.hr-builder-admin {
  margin-top: 8px;
}
.hr-builder-admin-summary {
  cursor: pointer;
  color: var(--hr-accent);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
  padding: 4px 0;
  user-select: none;
  list-style: none;
}
.hr-builder-admin-summary::-webkit-details-marker { display: none; }
.hr-builder-admin-summary::before {
  content: "\25B8\00a0";          /* ▸ collapsed */
}
.hr-builder-admin[open] .hr-builder-admin-summary::before {
  content: "\25BE\00a0";          /* ▾ expanded */
}
.hr-builder-subh {
  margin: 8px 0 4px;
  color: var(--hr-ink-muted);
  font-size: 0.78rem;
  font-weight: 600;
}
.ect-nav-menu .hr-submenu {
  display: none;
  background: rgba(0,0,0,0.25);
  padding: 2px 0;
}
.ect-nav-menu .hr-submenu.open { display: block; }
.ect-nav-menu .hr-submenu a {
  padding-left: 32px;
  font-size: 0.95rem;
  border-bottom: 1px solid var(--hr-accent-dk);
}
.ect-nav-menu .nav-divider {
  border-top: 1px solid var(--hr-accent);
  margin: 0;
  opacity: 0.55;
}

/* U1: faculty read-only viewer. The root #hr-app gets .hr-view-only - hide the
   palette + every build-mutating affordance, disable edit inputs (values stay
   visible), and surface a badge where the edit tools were. The room.js mutators
   also no-op, so this is presentation; nothing here is load-bearing for safety. */
.hr-vo-badge { display: none; }
.hr-view-only .hr-vo-badge {
  display: inline-flex; align-items: center;
  background: var(--hr-accent); color: var(--hr-surface);
  font-weight: 700; font-size: 0.82rem; padding: 3px 10px; border-radius: 4px;
}
.hr-view-only .hr-palette { display: none; }
.hr-view-only [data-act="add-rack"],
.hr-view-only [data-act="rotate-rack"],
.hr-view-only [data-act="remove-rack"],
.hr-view-only [data-act="add-uplink-tool"],
.hr-view-only .hr-detail-actions,
.hr-view-only .hr-acq-toggle,
.hr-view-only .hr-edit-actions,
.hr-view-only .hr-rack-desc-pencil { display: none; }
.hr-view-only .hr-field input,
.hr-view-only .hr-field textarea,
.hr-view-only .hr-field select { pointer-events: none; opacity: 0.7; }

/* ── main grid ─────────────────────────────────────────────── */

.hr-app {
  flex: 1 1 auto;
  display: grid;
  grid-template-rows: var(--hr-split-v, 62%) 6px 1fr;
  grid-template-columns: 0fr 1fr;
  min-height: 0;
  position: relative;
  background: var(--hr-bg);
}
.hr-app::before { /* leave gutter for the palette tab */
  content: "";
  width: 18px;
  grid-row: 1 / span 3;
  grid-column: 1;
}

/* Boot states: shown in #hr-app before the UI mounts (catalog fetch). */
.hr-boot-loading, .hr-boot-error {
  grid-row: 1 / span 3;
  grid-column: 1 / span 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 4px;
  padding: 32px;
  color: var(--hr-ink-muted);
}
.hr-boot-error { color: var(--hr-ink); }
.hr-boot-error h2 { margin: 0 0 6px; color: var(--hr-err-fg, #b00020); }
.hr-boot-error p { max-width: 460px; margin: 2px 0; }
.hr-boot-error code {
  background: var(--hr-line-soft); padding: 1px 5px; border-radius: 3px;
}

.hr-pane {
  background: var(--hr-surface);
  border: 1px solid var(--hr-line);
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}
.hr-pane-top {
  grid-row: 1; grid-column: 2;
  margin: 4px 4px 0 4px;
}
.hr-divider-h {
  grid-row: 2; grid-column: 2;
  margin: 0 4px;
}
.hr-pane-row {
  grid-row: 3; grid-column: 2;
  display: grid;
  grid-template-columns: var(--hr-split-h, 35%) 6px 1fr;
  margin: 0 4px 4px 4px;
  min-height: 0;
}
.hr-pane-details { grid-column: 1; grid-row: 1; }
.hr-divider-v    { grid-column: 2; grid-row: 1; }
.hr-pane-rack    { grid-column: 3; grid-row: 1; }

.hr-divider {
  background: var(--hr-line);
  position: relative;
  flex: 0 0 auto;
  user-select: none;
  transition: background-color 0.12s ease;
}
.hr-divider:hover, .hr-divider-active {
  background: var(--hr-accent);
}
.hr-divider-h { cursor: ns-resize; height: 6px; }
.hr-divider-v { cursor: ew-resize; width:  6px; }
.hr-divider-h::after {
  content: ""; position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 28px; height: 2px;
  background: var(--hr-ink-muted);
  border-radius: 1px;
  opacity: 0.5;
}
.hr-divider-v::after {
  content: ""; position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 2px; height: 28px;
  background: var(--hr-ink-muted);
  border-radius: 1px;
  opacity: 0.5;
}
.hr-pane-rack    { min-height: 0; }
.hr-pane-details { min-height: 0; overflow: auto; padding: 8px 12px; }

/* ── toolbars ──────────────────────────────────────────────── */

.hr-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border-bottom: 1px solid var(--hr-line);
  background: var(--hr-panel);
  flex: 0 0 auto;
  flex-wrap: wrap;
}
.hr-toolbar button {
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink);
  padding: 2px 10px;
  font: inherit;
  font-size: 0.9rem;
  border-radius: 3px;
  cursor: pointer;
}
.hr-toolbar button:hover { background: var(--hr-line-soft); }
.hr-toolbar button.hr-on {
  background: var(--hr-accent);
  border-color: var(--hr-accent-dk);
  color: var(--hr-surface);
}
/* Top-toolbar 2x2 action grid: + Rack / Rotate / Remove / Fit */
.hr-toolbar-actions {
  display: grid;
  grid-template-columns: auto auto;
  gap: 3px;
}
.hr-toolbar-actions button { padding: 1px 8px; font-size: 0.82rem; }
/* UI24: a greyed, non-interactive menu row (the Undo / Redo flyout rows when
   that action isn't available - nothing to undo yet, or the read-only viewer).
   Spelled out per theme so the data-theme=dark `a` colour rule doesn't win on
   specificity (the same gotcha the danger row documents). */
.ect-nav-menu a.hr-menu-disabled,
html[data-theme="dark"] .ect-nav-menu a.hr-menu-disabled {
  color: var(--hr-ink-muted);
  opacity: 0.5;
  cursor: default;
}
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] .ect-nav-menu a.hr-menu-disabled { color: var(--hr-ink-muted); }
}
.ect-nav-menu a.hr-menu-disabled:hover { background: transparent; }
/* UI24: Undo/Redo flyout rows carry a right-aligned keybinding hint (label
   left, key pill right) - same row layout as the Settings toggle rows. */
.ect-nav-menu #hr-editsub a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.hr-menu-key {
  font-size: 0.72em;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
  color: var(--hr-ink-muted);
  padding: 1px 7px;
  border: 1px solid var(--hr-line);
  border-radius: 4px;
  white-space: nowrap;
}
/* Details-pane heading row: the selection name on the left, action
   buttons (Rotate/Remove/Lock/Edit/Notes/...) on the right of the
   same line. Used for the Data Center Floor pane, the rack pane,
   and the device pane. */
.hr-detail-h-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}
.hr-detail-h-row .hr-h { margin: 0; flex: 0 0 auto; }
.hr-detail-actions {
  margin-left: auto;
  display: flex;
  gap: 4px;
}
.hr-detail-actions button {
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink);
  padding: 2px 8px;
  font: inherit;
  font-size: 0.78rem;
  border-radius: 3px;
  cursor: pointer;
}
.hr-detail-actions button:hover { background: var(--hr-line-soft); }
.hr-detail-actions button:disabled { opacity: 0.45; cursor: not-allowed; }

/* Right-click context menu for rack tiles in the room view. */
.hr-ctx-menu {
  position: fixed;
  background: var(--hr-surface);
  border: 1px solid var(--hr-accent);
  border-radius: 4px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.30);
  z-index: 1500;
  min-width: 140px;
  padding: 4px 0;
}
.hr-ctx-menu button {
  display: block;
  width: 100%;
  border: 0;
  background: transparent;
  text-align: left;
  padding: 6px 14px;
  font: inherit;
  font-size: 0.88rem;
  color: var(--hr-ink);
  cursor: pointer;
}
.hr-ctx-menu button:hover:not(:disabled) { background: var(--hr-line-soft); }
.hr-ctx-menu button:disabled {
  color: var(--hr-ink-muted);
  cursor: default;
  opacity: 0.55;
}
.hr-ctx-menu .hr-ctx-danger { color: var(--hr-err-fg); }
.hr-ctx-color-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 6px 10px;
  border-top: 1px solid var(--hr-line-soft);
  border-bottom: 1px solid var(--hr-line-soft);
}
.hr-ctx-color-row .hr-rack-swatch {
  display: inline-block;
  width: 20px; height: 20px;
  padding: 0;
}
.hr-ctx-color-row .hr-rack-swatch:hover:not(:disabled) { background: inherit; }
.hr-ctx-color-reset {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 20px;
  padding: 0;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--hr-ink-muted);
  border: 1px solid var(--hr-line);
  border-radius: 3px;
  background: transparent;
  cursor: pointer;
}
.hr-ctx-color-reset:hover { color: var(--hr-ink); background: var(--hr-line-soft); }
/* The Data Center Floor title doubles as the select-to-edit control (the
   inline editor opens in the right pane). Reads as clickable; highlights when
   the floor is the active selection. */
.hr-floor-title { cursor: pointer; border-radius: 4px; padding: 1px 4px; margin: 0 -4px; }
.hr-floor-title:hover { color: var(--hr-accent); }
.hr-floor-title-on { color: var(--hr-accent); box-shadow: inset 0 -2px 0 var(--hr-accent); }
.hr-room-notes-btn {
  margin-left: auto;
  border: 1px solid var(--hr-accent-dk);
  background: var(--hr-accent);
  color: var(--hr-surface);
  padding: 2px 10px;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  border-radius: 4px;
  cursor: pointer;
}
.hr-room-notes-btn:hover { filter: brightness(1.08); }
.hr-readout {
  margin-left: auto;
  font-size: 0.85rem;
  color: var(--hr-ink-muted);
  line-height: 1.25;
  text-align: right;
}
.hr-readout-bad { color: var(--hr-err-fg); font-weight: 600; }
/* Each readout piece is atomic - it never breaks mid-value. */
.hr-readout .hr-ro-item { white-space: nowrap; }
/* The room readout is CONTENT-sized (flex 0 1 auto), pre-stacked by JS into two
   width-balanced lines, and right-aligned. Being content-sized (not greedy) is
   what lets the Power/Cooling/Budget bars - which keep flex:1 1 auto - expand to
   fill the rest of the toolbar: in a blank build the bars now stretch the full
   width instead of stopping short with a gap before the readout. Scoped to
   #hr-room-readout so the rack-pane readout keeps its plain right-align. */
#hr-room-readout {
  flex: 0 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  text-align: right;
}
#hr-room-readout .hr-readout-line {
  white-space: nowrap;       /* each stacked line stays on one row (JS already balanced the split) */
  min-width: 0;
}
.hr-cost-equip { color: var(--hr-accent); font-weight: 600; }
.hr-cost-cool  { color: #3aa6e3; font-weight: 600; }
/* E9: recurring electricity opex token (marigold), distinct from the
   capex equipment/cooling colors above. */
.hr-power-cost { color: var(--hr-marigold, #aa8a00); font-weight: 600; }
/* N7 + E10: recurring ISP opex (flat fee + usage transit), beside the power
   opex token. .hr-isp-over flags bursting past a committed cap (top band). */
.hr-isp-cost { color: var(--hr-marigold, #aa8a00); font-weight: 600; }
.hr-isp-over { color: var(--hr-bad, #c0392b); font-weight: 700; }
/* E4: power-cut resilience token. ok = on generator (green); base = on UPS
   battery (marigold, finite); bad = unprotected / generator can't help (red). */
.hr-resil    { color: var(--hr-marigold, #aa8a00); font-weight: 600; }
.hr-resil-ok { color: #2e9e57; font-weight: 600; }
.hr-resil-bad{ color: var(--hr-bad, #c0392b); font-weight: 700; }

/* E5: TCO readout token + details-pane report button. */
.hr-tco-token { color: #2e9e57; font-weight: 600; }
/* E15: PUE (Power Usage Effectiveness) readout token. ok = efficient (green),
   base = fair (marigold), bad = cooling overhead dominates (red). */
.hr-pue-ok  { color: #2e9e57; font-weight: 600; }
.hr-pue     { color: var(--hr-marigold, #aa8a00); font-weight: 600; }
.hr-pue-bad { color: var(--hr-bad, #c0392b); font-weight: 700; }
.hr-tco-report-btn {
  margin-top: 8px; padding: 4px 10px; border: 1px solid var(--hr-line);
  background: var(--hr-surface); color: inherit; border-radius: 4px; cursor: pointer; font-size: 0.85rem;
}
.hr-tco-report-btn:hover { border-color: var(--hr-accent); color: var(--hr-accent); }
/* Two half-width buttons (3D View + TCO Report) sharing one row under the
   floor overview. */
.hr-detail-btn-row { display: flex; gap: 6px; margin-top: 8px; }
.hr-detail-btn-row > button { flex: 1 1 0; margin-top: 0; }

/* E5: TCO report modal - charts + table. */
.hr-tco-horizon { margin: 6px 0; display: flex; align-items: center; gap: 6px; }
.hr-tco-hbtn {
  padding: 3px 11px; border: 1px solid var(--hr-line); background: var(--hr-surface);
  color: inherit; border-radius: 4px; cursor: pointer;
}
.hr-tco-hbtn.hr-on { background: var(--hr-accent); color: var(--hr-surface); border-color: var(--hr-accent); }
.hr-tco-figs { display: flex; flex-wrap: wrap; gap: 14px; margin: 8px 0 10px; font-size: 0.9rem; }
.hr-tco-figs b { color: var(--hr-ink-muted); font-weight: 600; margin-right: 3px; }
.hr-tco-chart { width: 100%; max-width: 760px; height: auto; display: block; margin: 2px 0 4px; }
/* TCO report is a full-screen overlay (like the 3D view). */
.hr-modal-full { align-items: stretch; justify-content: stretch; }
.hr-modal-full .hr-modal-card {
  max-width: none; max-height: none; width: 100%; height: 100%;
  border-radius: 0; min-width: 0; box-shadow: none;
}
.hr-tco-report { max-width: 1120px; margin: 0 auto; }
/* Full-screen TCO close: fixed to the window's upper-right corner. */
.hr-tco-close {
  position: fixed; top: 12px; right: 16px; z-index: 10;
  width: 34px; height: 34px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem; line-height: 1;
  background: var(--hr-surface); color: var(--hr-ink);
  border: 1px solid var(--hr-line); border-radius: 50%;
  cursor: pointer;
}
.hr-tco-close:hover { border-color: var(--hr-accent); color: var(--hr-accent); }
.hr-tco-grid { display: grid; grid-template-columns: 1.5fr 1fr; gap: 28px; align-items: start; }
@media (max-width: 820px) { .hr-tco-grid { grid-template-columns: 1fr; } }
/* SVG chart grid LINES - distinct class from the .hr-tco-grid layout div
   above, whose children must NOT inherit this faint opacity. */
.hr-tco-gridline { stroke: var(--hr-line); stroke-width: 0.5; opacity: 0.55; }
.hr-tco-axlbl { fill: var(--hr-ink-muted); font-size: 9px; }
.hr-tco-axttl { fill: var(--hr-ink-muted); font-size: 10px; }
.hr-tco-capex-area { fill: #3a7c69; opacity: 0.30; }
.hr-tco-opex-area  { fill: #aa8a00; opacity: 0.28; }
.hr-tco-capex-line { stroke: #3a7c69; stroke-width: 1.2; stroke-dasharray: 4 3; fill: none; }
.hr-tco-total-line { stroke: #aa8a00; stroke-width: 2; fill: none; }
.hr-tco-dot { fill: #aa8a00; }
.hr-tco-cross { stroke: var(--hr-bad, #c0392b); stroke-width: 1; stroke-dasharray: 3 3; }
.hr-tco-crosslbl { fill: var(--hr-bad, #c0392b); font-size: 9px; }
.hr-tco-bar { display: flex; height: 26px; border-radius: 4px; overflow: hidden; margin: 10px 0 6px; border: 1px solid var(--hr-line); }
.hr-tco-seg-capex { background: #3a7c69; }
.hr-tco-seg-lease { background: #7d2f5c; }
.hr-tco-seg-power { background: #aa8a00; }
.hr-tco-seg-isp   { background: #3aa6e3; }
.hr-tco-legends { display: flex; flex-wrap: wrap; gap: 12px; font-size: 0.85rem; margin-bottom: 10px; }
.hr-tco-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }
.hr-tco-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.hr-tco-table th, .hr-tco-table td { text-align: right; padding: 3px 8px; border-bottom: 1px solid var(--hr-line); }
.hr-tco-table th:first-child, .hr-tco-table td:first-child { text-align: left; }
.hr-tco-table th { color: var(--hr-ink-muted); }
/* E19: the Power Report shares the hr-tco-* report layout but uses a distinct
   VIOLET/CYAN palette (vs the TCO report's green/gold) so the two don't look
   alike at a glance. */
.hr-pwr-line { stroke: #9b7ede; stroke-width: 2; fill: none; }
.hr-pwr-dot  { fill: #9b7ede; }
.hr-pwr-now  { stroke: #39bdd6; stroke-width: 1; stroke-dasharray: 3 3; }
.hr-pwr-nowlbl { fill: #39bdd6; font-size: 9px; }
.hr-pwr-seg-equip { background: #8a6fd1; }
.hr-pwr-seg-cool  { background: #39bdd6; }
.hr-pwr-seg-head  { background: #49525a; }
/* E10: read-only ISP usage note in the uplink edit pane. */
.hr-field-note { font-size: 0.85em; line-height: 1.35; padding: 4px 2px; }
.hr-note-dim { opacity: 0.72; }
/* Armed-mode prompt sits on its own line beneath the readout, kept
   right-aligned so the two readout lines + the armed prompt read as a
   single right-justified block in the top toolbar. */
.hr-armed {
  flex-basis: 100%;
  text-align: right;
  font-size: 0.82rem;
  color: var(--hr-accent);
}
.hr-armed:empty { display: none; }
.hr-hidden { display: none !important; }
/* Budget chip in the top readout (UI2). Shown only when the loaded
   scenario has lockedConstraints.budgetUsd. Green = under, red = over. */
.hr-budget-chip {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.hr-budget-under {
  background: rgba(0, 200, 120, 0.18);
  color: var(--hr-accent);
  border: 1px solid var(--hr-accent);
}
.hr-budget-over {
  background: rgba(255, 60, 60, 0.22);
  color: var(--hr-err-fg);
  border: 1px solid var(--hr-err-fg);
}

/* Inline headroom bars inside the top toolbar (UI3). Full label /
   track / value rows stacked vertically inside a fixed-width slot
   between the Notes button and the Racks readout. Hidden via the
   `:empty` rule until `lastSummary` is populated. */
.hr-toolbar-bars {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 8px;
  flex: 1 1 auto;                    /* expand to fill the toolbar gap */
  min-width: 0;                      /* let the grid track shrink below intrinsic width */
  font-size: 0.7rem;
  color: var(--hr-ink-muted);
}
.hr-toolbar-bars:empty { display: none; }
.hr-toolbar-bars .hr-headroom-row {
  display: grid;
  grid-template-columns: 52px 1fr auto;
  align-items: center;
  gap: 6px;
}
.hr-toolbar-bars .hr-headroom-label {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
  font-size: 0.66rem;
}
.hr-toolbar-bars .hr-headroom-track {
  height: 6px;
}
.hr-toolbar-bars .hr-headroom-value {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-size: 0.7rem;
}

/* Legacy strip under the toolbar - kept around in case future work
   wants a wider bar group, but currently empty (hidden via :empty). */
.hr-headroom-bars {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 8px 0;
  font-size: 0.72rem;
  color: var(--hr-ink-muted);
}
.hr-headroom-bars:empty { display: none; }
.hr-headroom-row {
  display: grid;
  grid-template-columns: 60px 1fr auto;
  align-items: center;
  gap: 8px;
}
.hr-headroom-label {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.hr-headroom-track {
  height: 6px;
  background: var(--hr-line-soft);
  border-radius: 3px;
  overflow: hidden;
  display: flex;
}
.hr-headroom-fill {
  height: 100%;
  flex: 0 0 auto;
  background: var(--hr-accent);
  transition: width 0.2s ease, background-color 0.15s ease;
}
/* Proportional split segments: equipment (green) + cooling (cyan),
   matching the .hr-cost-equip / .hr-cost-cool readout colors. */
.hr-headroom-fill-equip,
.hr-headroom-fill-cool {
  height: 100%;
  flex: 0 0 auto;
  transition: width 0.2s ease;
}
.hr-headroom-fill-equip { background: var(--hr-accent); }
.hr-headroom-fill-cool  { background: #3aa6e3; }
.hr-headroom-value {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hr-headroom-ok   .hr-headroom-fill { background: rgb(0, 200, 120); }
.hr-headroom-mid  .hr-headroom-fill { background: rgb(220, 180, 40); }
.hr-headroom-high .hr-headroom-fill { background: rgb(230, 130, 30); }
.hr-headroom-over .hr-headroom-fill { background: var(--hr-err-fg); }
.hr-headroom-over .hr-headroom-value { color: var(--hr-err-fg); font-weight: 600; }
.hr-headroom-muted .hr-headroom-fill { background: var(--hr-line); }
.hr-armed {
  font-size: 0.85rem; color: var(--hr-accent);
  font-style: italic;
}
.hr-spacer { flex: 1 1 auto; }
.hr-toolbar-sep {
  width: 1px; height: 18px;
  background: var(--hr-line);
  margin: 0 4px;
  flex: 0 0 auto;
}

/* ── overhead room ────────────────────────────────────────── */

/* Scroll viewport that fills the pane (under the toolbar). The inner
   .hr-room is sized in JS to widthTiles*cellPx × heightTiles*cellPx, and
   centered when it doesn't fill the view. */
.hr-room-view {
  flex: 1 1 auto;
  position: relative;
  margin: 6px;
  background: var(--hr-room-bg);
  border: 1px solid var(--hr-line);
  overflow: auto;
  min-height: 0;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
.hr-room {
  position: relative;
  flex: 0 0 auto;
  /* width/height set inline by sizeHeatCanvas */
}
.hr-room-armed, .hr-room-view.hr-room-armed { cursor: crosshair; }
.hr-room-view.hr-room-panning { cursor: grabbing; }
.hr-heat, .hr-room-grid, .hr-room-walls, .hr-room-cool, .hr-room-racks, .hr-room-aisle {
  position: absolute; inset: 0;
}
.hr-room-walls { z-index: 4; pointer-events: none; }
/* UI7: hot-aisle / cold-aisle containment highlight. Sits above the
   heat + grid but below the racks (z 3); pass-through. */
.hr-room-aisle { z-index: 2; pointer-events: none; }
.hr-aisle-cell {
  position: absolute;
  background: rgba(58, 166, 227, 0.16);
  box-shadow: inset 0 0 0 1px rgba(58, 166, 227, 0.45);
}
/* Cooling renders on two architecturally-stacked layers. Both layers
   are hidden by default; cool mode reveals one layer at a time
   (floor or overhead) based on which mode the Cooling badge is in.
   The cooling EFFECT on the heat field renders regardless of layer
   visibility. */
.hr-room-cool { pointer-events: none; display: none; }
.hr-room-cool-floor    { z-index: 2; }              /* default: under racks (z 3) */
.hr-room-cool-overhead { z-index: 5; }              /* default: above walls (z 4) */
.hr-cool-mode-floor    .hr-room-cool-floor    { display: block; z-index: 6; }
.hr-cool-mode-overhead .hr-room-cool-overhead { display: block; }
/* In cool-mode, the cooling system is the only thing the user can
   interact with - racks and doors go inert so clicks fall through to
   the cool layers and the placement handler. Only the rack STRIP is
   dimmed/inert in the lower pane; the cool-source edit form rendered
   there must stay live + full-opacity. */
.hr-cool-mode .hr-rack-tile { pointer-events: none; }
.hr-cool-mode .hr-door-svg  { pointer-events: none; }
.hr-cool-mode .hr-rack-elev .hr-rack-strip { pointer-events: none; opacity: 0.55; }

/* N1: Connections layer. Hide the heat overlays, dim the racks to a
   backdrop, and surface the #hr-room-conn overlay for uplinks + links.
   Racks stay clickable (they're link endpoints) - the room pointerdown
   handler routes conn-mode clicks; the door goes inert. Only the rack
   STRIP is dimmed/inert in the lower pane; the uplink edit form + the
   per-rack connections doc rendered there must stay live + full-opacity. */
.hr-room-conn { position: absolute; inset: 0; z-index: 6; pointer-events: none; display: none; }
.hr-conn-mode .hr-room-conn { display: block; }
.hr-conn-mode .hr-heat       { display: none; }
.hr-conn-mode .hr-room-aisle { display: none; }
.hr-conn-mode .hr-room-racks { opacity: 0.75; }
.hr-conn-mode .hr-door-svg   { pointer-events: none; }
.hr-conn-mode .hr-rack-elev .hr-rack-strip { pointer-events: none; opacity: 0.55; }
.hr-conn-svg { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
.hr-link {
  stroke: #3aa6e3;
  stroke-width: 2.5;
  stroke-linecap: round;
  pointer-events: stroke;
  cursor: pointer;
}
.hr-link:hover { stroke: var(--hr-accent); }
.hr-link-sel  { stroke: var(--hr-accent); stroke-width: 3.5; }
.hr-link-draft { stroke-dasharray: 5 4; opacity: 0.8; pointer-events: none; }
/* A link whose source rack can't carry its aggregated subtree load goes
   red (matched by its arrowhead marker). */
.hr-link-over { stroke: var(--hr-err-fg, #c0392b); }
.hr-link-incident { stroke-width: 3.8; }
.hr-arrow-ok   { fill: #3aa6e3; }
.hr-arrow-over { fill: var(--hr-err-fg, #c0392b); }
/* Connection ports. Orange = IN (top), purple = OUT (bottom); the ISP
   carries a single upload ring. Filled centers with a contrasting rim so
   they read against the green racks. Grabbable (the OUT port starts a
   link; IN / ISP receive one). */
.hr-port { stroke-width: 2; pointer-events: auto; cursor: crosshair; }
.hr-port-in   { fill: #e08a1e; stroke: #5a3402; }       /* orange IN */
.hr-port-out  { fill: #7d2f9e; stroke: #2e0f3d; }       /* purple OUT */
.hr-port-isp  { fill: none;    stroke: #e7ecc3; stroke-width: 2.5; }   /* ISP upload ring */
.hr-port-active { stroke: #fff; stroke-width: 3; }      /* source OUT during a draw */
.hr-port-target { stroke: #fff; stroke-width: 3; filter: drop-shadow(0 0 3px #fff); }
.hr-port-sel    { stroke: #fff; stroke-width: 3.5; filter: drop-shadow(0 0 3px var(--hr-accent)); }
/* Per-link traffic label ("+added / aggregate"), drawn above the lines
   with a dark outline so it stays legible over any backdrop. */
.hr-link-label {
  font-size: 9px; font-weight: 600; text-anchor: middle; pointer-events: none;
  fill: #cfe8f7; stroke: #08131a; stroke-width: 2.5px; paint-order: stroke;
}
.hr-link-label-over { fill: #ffd2d2; }
.hr-uplink { pointer-events: auto; cursor: grab; }
.hr-uplink > rect {
  fill: #1f4f6b;
  stroke: #3aa6e3;
  stroke-width: 1.5;
}
.hr-uplink:hover > rect { filter: brightness(1.15); }
.hr-uplink-glyph { stroke: #e7ecc3; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.hr-uplink-over > rect { fill: #6b1f1f; stroke: var(--hr-err-fg, #c0392b); }
.hr-cool-sel { filter: drop-shadow(0 0 4px var(--hr-accent)); }
.hr-cool-sel > * { stroke: var(--hr-accent); stroke-width: 1.2; }
.hr-uplink-sel > rect { stroke: var(--hr-accent); stroke-width: 2.5; }
/* Link-making cursor: in the Connections layer a rack is a link endpoint
   (drag its OUT port), so it takes a crosshair rather than the hand. The
   ISP is draggable-to-move (N7), so it keeps the grab hand instead. */
.hr-conn-mode .hr-rack-tile,
.hr-conn-mode .hr-rack-tile:active { cursor: crosshair; }
/* Prospective ISP target highlight during a link draw. */
.hr-uplink-linkend > rect { stroke: #fff; stroke-width: 2.5; }
/* N7: ISP demarc boxes in the room plan view. A persistent overlay above
   the racks (z 5) so the box reads as floor equipment on every layer
   EXCEPT Connections, where the richer #hr-room-conn overlay takes over.
   The container is pass-through; only the boxes themselves take clicks. */
.hr-room-demarc { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.hr-conn-mode .hr-room-demarc { display: none; }
.hr-demarc { position: absolute; pointer-events: auto; cursor: grab; overflow: visible; }
/* N7: while an ISP move is in flight the whole room shows the closed grab
   hand (matches the room-pan cursor), reverting on drop. */
.hr-room-view.hr-uplink-dragging,
.hr-room-view.hr-uplink-dragging * { cursor: grabbing !important; }
.hr-demarc > rect { fill: #1f4f6b; stroke: #3aa6e3; stroke-width: 1.5; }
.hr-demarc:hover > rect { filter: brightness(1.15); }
.hr-demarc-glyph { stroke: #e7ecc3; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.hr-demarc-sel > rect { stroke: var(--hr-accent); stroke-width: 2.5; }
/* Target-tile outline while dragging a cooling/uplink item from the
   palette onto the room. */
.hr-place-preview {
  position: absolute;
  z-index: 7;
  pointer-events: none;
  box-sizing: border-box;
  border: 2px dashed var(--hr-accent);
  background: color-mix(in srgb, var(--hr-accent) 14%, transparent);
  border-radius: 3px;
}
/* Right-pane editable form for a selected diffuser / floor tile / uplink. */
.hr-edit-pane { padding: 10px 12px; }
.hr-edit-pane .hr-field { margin: 6px 0; }
.hr-edit-actions { margin-top: 10px; display: flex; justify-content: flex-end; }
.hr-edit-actions button {
  font: inherit; font-size: 0.85rem; padding: 4px 12px;
  border: 1px solid var(--hr-line); border-radius: 4px;
  background: var(--hr-surface); color: var(--hr-ink); cursor: pointer;
}
/* Active-layer instructions panel at the top of the details pane. */
.hr-layer-panel {
  border-left: 3px solid var(--hr-accent);
  background: color-mix(in srgb, var(--hr-accent) 8%, transparent);
  padding: 6px 10px;
  margin-bottom: 8px;
  border-radius: 0 4px 4px 0;
}
.hr-layer-panel .hr-h2 { margin-top: 0; }
.hr-layer-help { font-size: 0.85rem; color: var(--hr-ink-muted); margin: 2px 0 0; line-height: 1.4; }
/* Connections doc: list of a selected rack/uplink's links (rack pane +
   uplink edit pane). Mirrors the overhead emphasis. */
.hr-conn-doc { margin-top: 8px; }
.hr-conn-count { font-size: 0.85rem; font-weight: 600; margin: 0 0 4px; }
.hr-conn-list { list-style: none; margin: 0 0 4px; padding: 0; }
.hr-conn-row {
  display: flex; align-items: center; gap: 6px;
  padding: 3px 4px; border-radius: 4px; cursor: pointer;
}
.hr-conn-row:hover { background: var(--hr-line-soft, rgba(0,0,0,0.06)); }
.hr-conn-kdot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.hr-conn-kdot-rack   { background: #3aa6e3; }
.hr-conn-kdot-uplink { background: #1f4f6b; box-shadow: inset 0 0 0 1.5px #3aa6e3; }
.hr-conn-name { flex: 1 1 auto; font-size: 0.85rem; }
.hr-conn-dir { font-weight: 600; color: var(--hr-ink-muted); font-size: 0.78rem; }
.hr-conn-del {
  flex: 0 0 auto; font: inherit; line-height: 1; padding: 1px 6px;
  border: 1px solid var(--hr-line); border-radius: 4px;
  background: transparent; color: var(--hr-err-fg, #c0392b); cursor: pointer;
}
.hr-conn-del:hover { background: color-mix(in srgb, var(--hr-err-fg, #c0392b) 16%, transparent); }
/* Capacity / flow readout above the link list. */
.hr-conn-stats {
  font-size: 0.82rem; line-height: 1.5; margin: 0 0 6px;
  padding: 6px 8px; border-radius: 4px;
  background: var(--hr-line-soft, rgba(0,0,0,0.05));
}
.hr-conn-stats.hr-conn-over { background: color-mix(in srgb, var(--hr-err-fg, #c0392b) 14%, transparent); }
.hr-conn-stats b { font-variant-numeric: tabular-nums; }
.hr-conn-warn { color: var(--hr-err-fg, #c0392b); font-weight: 600; margin-top: 2px; }
/* E8: cool-source symbols. Inline SVG, pointer-events:auto so they
   intercept clicks for drag/context-menu. Overhead = point-up, floor
   = point-down. Tinted using a cyan-tinged blue per the data-center
   convention; floor tiles use a slightly cooler cyan-tinged shade. */
.hr-cool {
  position: absolute;
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  overflow: visible;
  filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.35));
}
.hr-cool:hover, .hr-cool:focus { filter: drop-shadow(0 0 4px currentColor); outline: none; }
.hr-cool:active { cursor: grabbing; }
.hr-cool-overhead { color: #3aa6e3; }
.hr-cool-floor    { color: #1bcedf; }
/* E16: returns are warm grilles (drain the hot aisle) vs blue supply (push
   cold to the cold aisle). Louver slats overlay the base shape. */
.hr-cool-return-overhead { color: #e07b39; }
.hr-cool-return-floor    { color: #e2a01b; }
.hr-cool > * {
  fill: currentColor;
  fill-opacity: 0.85;
  stroke: rgba(0, 0, 0, 0.55);
  stroke-width: 0.6;
  stroke-linejoin: round;
}
.hr-cool-louver line {
  fill: none;
  stroke: rgba(0, 0, 0, 0.6);
  stroke-width: 1;
  stroke-linecap: round;
}

/* Walls along the four edges of the room. The south wall is rendered as
   two segments with a door cut between them. Wall thickness scales with
   cellPx via the .hr-wall-* fixed values below (clamped). */
.hr-wall {
  position: absolute;
  background: var(--hr-putnam, #756e65);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.35);
}
html[data-theme="dark"] .hr-wall { background: #4a4640; }
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] .hr-wall { background: #4a4640; }
}
.hr-wall-n { height: 4px; }
.hr-wall-s { height: 4px; }
.hr-wall-e { width: 4px; }
.hr-wall-w { width: 4px; }

/* Door - architectural symbol drawn in SVG (slab + swing arc + hinge dot).
   pointer-events: auto re-enables interactivity (the parent
   .hr-room-walls disables it). Cursor doubles as the drag affordance. */
.hr-door-svg {
  position: absolute;
  color: var(--hr-marigold, #aa8a00);
  pointer-events: auto;
  z-index: 5;
  overflow: visible;
  cursor: grab;
  touch-action: none;
}
.hr-door-svg:active { cursor: grabbing; }
.hr-door-svg:hover, .hr-door-svg:focus { filter: drop-shadow(0 0 3px var(--hr-marigold, #aa8a00)); outline: none; }
.hr-door-svg.hr-door-preview { opacity: 0.55; filter: drop-shadow(0 0 4px var(--hr-accent)); }
.hr-heat { z-index: 1; pointer-events: none; }
.hr-room-grid {
  z-index: 2;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--hr-cell-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--hr-cell-line) 1px, transparent 1px);
}
.hr-room-racks { z-index: 3; }

.hr-rack-tile {
  position: absolute;
  box-sizing: border-box;
  background: var(--hr-rack-fill);
  border: 2px solid var(--hr-rack-bord);
  border-radius: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  user-select: none;
  color: var(--hr-surface);
}
.hr-rack-tile:active { cursor: grabbing; }
.hr-rack-sel {
  outline: 3px solid var(--hr-rack-sel);
  outline-offset: 2px;
  box-shadow:
    0 0 0 2px rgba(255, 255, 255, 0.9),
    0 0 12px 4px var(--hr-rack-sel);
  z-index: 5;
  animation: hr-rack-sel-pulse 1.6s ease-in-out infinite;
}
@keyframes hr-rack-sel-pulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(255,255,255,0.9), 0 0 12px 4px var(--hr-rack-sel); }
  50%      { box-shadow: 0 0 0 2px rgba(255,255,255,0.9), 0 0 18px 8px var(--hr-rack-sel); }
}
.hr-rack-err { border-color: var(--hr-rack-err); background: #6b1f1c; }
/* Multi-rack rubber-band selection rectangle (drawn over the racks). */
.hr-marquee {
  position: absolute;
  z-index: 8;
  pointer-events: none;
  border: 1px dashed var(--hr-rack-sel, var(--hr-accent));
  background: rgba(170, 138, 0, 0.16);
  border-radius: 2px;
}
/* Ghostly landing outline shown while dragging rack(s) (one per moving rack). */
.hr-rack-ghost {
  position: absolute;
  z-index: 6;
  pointer-events: none;
  box-sizing: border-box;
  border: 2px dashed var(--hr-rack-sel, var(--hr-accent));
  background: rgba(170, 138, 0, 0.18);
  border-radius: 2px;
}
.hr-rack-ghost-bad {
  border-color: var(--hr-rack-err, #c0392b);
  background: rgba(192, 57, 43, 0.22);
}
/* Lower-right pane note when several racks are selected (no single elevation). */
.hr-multi-note { padding: 14px 16px; line-height: 1.5; }
.hr-multi-note p { margin: 0 0 10px; }
.hr-rack-label-overlay {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  pointer-events: none;
}
.hr-cold {
  position: absolute;
  background: rgba(64, 156, 255, 0.85);
  pointer-events: none;
}
.hr-cold-N { left: 2px; right: 2px; top: -3px; height: 4px; }
.hr-cold-S { left: 2px; right: 2px; bottom: -3px; height: 4px; }
.hr-cold-W { top: 2px; bottom: 2px; left: -3px; width: 4px; }
.hr-cold-E { top: 2px; bottom: 2px; right: -3px; width: 4px; }
/* E16: hot (exhaust) edge marker - warm, mirrors the blue cold strip. Tells
   the student which edge takes the orange return grilles. */
.hr-hot {
  position: absolute;
  background: rgba(224, 123, 57, 0.9);
  pointer-events: none;
}
.hr-hot-N { left: 2px; right: 2px; top: -3px; height: 4px; }
.hr-hot-S { left: 2px; right: 2px; bottom: -3px; height: 4px; }
.hr-hot-W { top: 2px; bottom: 2px; left: -3px; width: 4px; }
.hr-hot-E { top: 2px; bottom: 2px; right: -3px; width: 4px; }

/* ── rack elevation ───────────────────────────────────────── */

.hr-rack-label { font-weight: 700; }
.hr-rack-elev {
  flex: 1 1 auto;
  overflow: auto;
  padding: 8px;
  background: var(--hr-panel);
  min-height: 0;
  /* Disable text selection: device names + U labels are presentational,
     and click-drag to move equipment should never spawn a text-selection
     range across the strip. */
  user-select: none;
  -webkit-user-select: none;
  /* Block layout (not flex) so the strip's `margin: 0 auto` centers when
     smaller than the pane, and stays left-aligned (scroll right) when
     wider. Flex centering would clip the wide strip equally on both
     sides instead of letting it scroll. */
}
.hr-rack-empty {
  color: var(--hr-ink-muted);
  padding: 12px;
  font-style: italic;
}
.hr-rack-strip {
  /* width is set inline by renderRack (baseW * rackZoom). The pane has
     overflow:auto on both axes so the strip can be scrolled when zoomed
     past fit. */
  margin: 0 auto;
  flex: 0 0 auto;
  position: relative;                       /* anchor for the UI14 cable overlay */
}
/* UI14: cabling overlay drawn over (not inside) the .hr-rack-back mirror, so
   cables aren't flipped. Sits above the device faces, below pointer targets. */
.hr-rack-cables {
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: none;
  z-index: 3;
}
.hr-rack-strip-inner {
  display: grid;
  /* grid-template-rows is set inline per-rack (repeat(rackUnits, <rowH>px))
     so the strip's natural height = rackUnits * rowH. Parent .hr-rack-elev
     has overflow:auto, so when total height exceeds the pane the pane
     scrolls vertically. */
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  position: relative;                       /* anchor for .hr-preview-ghost */
}
.hr-rack-back { transform: scaleX(-1); }
.hr-rack-back .hr-dev, .hr-rack-back .hr-slot { transform: scaleX(-1); }

.hr-slot {
  border-bottom: 1px dashed var(--hr-line-soft);
  display: flex; align-items: center; gap: 6px;
  padding: 0 6px;
  color: var(--hr-ink-muted);
  font-size: 0.65rem;
  cursor: copy;
  background: linear-gradient(to bottom, transparent, rgba(0,0,0,0.02));
  min-width: 0;
  overflow: hidden;
}
.hr-slot-u { opacity: 0.6; min-width: 30px; text-align: right; }
.hr-slot-hi { background: rgba(0, 200, 120, 0.18); }
.hr-slot-bad{ background: rgba(255, 60, 60, 0.20); }
/* Drop-preview overlay (UI4). Positioned absolutely inside the strip
   so it can span the full proposed footprint without disturbing the
   grid's auto-placement of slot/device children. Multi-U previews stay
   visually continuous even where they cover an existing device. */
.hr-preview-ghost {
  position: absolute;
  left: 0; right: 0;
  box-sizing: border-box;                   /* border lives inside top/height */
  pointer-events: none;
  border: 2px dashed currentColor;
  border-radius: 2px;
  background: currentColor;
  background-clip: padding-box;
  opacity: 0.30;
  z-index: 5;
}
.hr-preview-ok  { color: rgb(0, 200, 120); }
.hr-preview-bad { color: rgb(255, 60, 60); }

.hr-dev {
  display: flex; align-items: center; gap: 6px;
  padding: 0 6px;
  color: #fff;
  font-size: 0.72rem;
  cursor: grab;
  border-top: 1px solid rgba(255,255,255,0.18);
  border-bottom: 1px solid rgba(0,0,0,0.30);
  position: relative;
  overflow: hidden;
  min-width: 0;
}
.hr-dev:active { cursor: grabbing; }
/* UI9: procedural SVG face layer sits behind the text overlays. Text
   gets a soft shadow so it stays legible against detailed faces. */
.hr-dev-face {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}
/* UI9b: real vendor front art (images/faces/<id>-front.png) for allow-listed
   devices. Shares the .hr-dev-face box, so the U/name/watts overlay (z-index:1)
   stays on top. object-fit:fill mirrors the procedural SVG's
   preserveAspectRatio="none" - it stretches to the rack-row box and scales with
   ui.cellPx on zoom with no JS. The faint backdrop lets the category color show
   through transparent corners so art + procedural devices read as one system. */
.hr-dev-art {
  object-fit: fill;
  image-rendering: auto;
  background: rgba(0, 0, 0, 0.12);
}
.hr-dev-u,
.hr-dev-name,
.hr-dev-watts,
.hr-dev-lock {
  position: relative;
  z-index: 1;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.55);
}
.hr-dev-u { opacity: 0.85; font-variant-numeric: tabular-nums; min-width: 56px; }
.hr-dev-name { flex: 1 1 auto; font-weight: 600; }
.hr-dev-watts { opacity: 0.85; }
.hr-dev-hi { outline: 2px solid var(--hr-rack-sel); outline-offset: -2px; }
/* The currently-selected device in the rack elevation. Gold ring + white
   inner edge + soft glow so it stands out from its neighbors. */
.hr-dev-sel {
  outline: 2.5px solid var(--hr-rack-sel);
  outline-offset: -2px;
  box-shadow: inset 0 0 0 2px rgba(255,255,255,0.9), 0 0 10px 2px var(--hr-rack-sel);
  z-index: 2;
}
.hr-dev-locked {
  cursor: default;
  border-left: 3px solid var(--hr-marigold, #aa8a00);
}
.hr-dev-locked:active { cursor: default; }
.hr-dev-lock {
  font-size: 0.75em;
  margin-right: 2px;
  filter: drop-shadow(0 0 1px rgba(0,0,0,0.4));
}
.hr-lock-badge {
  font-size: 0.85em;
  color: var(--hr-marigold, #aa8a00);
  margin-left: 6px;
}

/* ── details pane ─────────────────────────────────────────── */

.hr-h { margin: 4px 0 6px; font-size: 1.1rem; color: var(--hr-accent); }
.hr-h2 { margin: 12px 0 4px; font-size: 0.95rem; color: var(--hr-accent); }
.hr-kv { font-size: 0.92rem; padding: 1px 0; }
.hr-kv b { color: var(--hr-ink-muted); font-weight: 600; min-width: 90px; display: inline-block; }

/* Compact wrap-flow for the room-overview stat list. Pairs sit
   inline and wrap as the pane width allows, replacing the older
   one-row-per-stat .hr-kv stack so the panel takes less vertical
   space when several stats are visible. */
.hr-kv-pairs {
  display: flex;
  flex-wrap: wrap;
  column-gap: 14px;
  row-gap: 2px;
  margin: 4px 0 6px;
  font-size: 0.9rem;
}
.hr-kv-pair { white-space: nowrap; }
.hr-kv-pair b { color: var(--hr-ink-muted); font-weight: 600; margin-right: 2px; }
.hr-field { display: flex; align-items: center; gap: 6px; font-size: 0.9rem; margin: 4px 0; }
.hr-field b { color: var(--hr-ink-muted); font-weight: 600; min-width: 110px; }
.hr-field-block { flex-direction: column; align-items: stretch; }
.hr-field-block b { margin-bottom: 2px; }
.hr-field input,
.hr-field select,
.hr-field textarea {
  flex: 1 1 auto;
  font: inherit;
  font-size: 0.9rem;
  background: var(--hr-surface);
  color: var(--hr-ink);
  border: 1px solid var(--hr-line);
  border-radius: 3px;
  padding: 3px 6px;
  min-width: 0;
}
.hr-field textarea { font-family: ui-monospace, "SF Mono", Consolas, monospace; resize: vertical; min-height: 38px; }

/* F22: a scenario-locked room field (Data Center Floor pane) - grey the input
   + label and append a "Scenario Locked" tag to the right of the value. */
.hr-field-locked b { opacity: 0.6; }
.hr-field-locked input:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  background: var(--hr-panel);
}
.hr-field-lock-tag {
  flex: 0 0 auto;
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--hr-warn-fg);
  background: var(--hr-warn-bg);
  border-radius: 3px;
  padding: 1px 6px;
  white-space: nowrap;
}

/* R3: flat description field right under the rack name in the details
   pane, with an edit pencil on the right. View span and edit textarea
   coexist; the pencil hides the view and reveals the textarea. */
.hr-rack-desc {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  padding: 2px 0 6px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--hr-line-soft);
}
.hr-rack-desc-text {
  flex: 1 1 auto;
  font-size: 0.92rem;
  color: var(--hr-ink);
  white-space: pre-wrap;
  word-break: break-word;
  padding: 2px 0;
}
.hr-rack-desc-empty { color: var(--hr-ink-muted); font-style: italic; }
.hr-rack-desc-input {
  flex: 1 1 auto;
  font: inherit;
  font-size: 0.92rem;
  background: var(--hr-surface);
  color: var(--hr-ink);
  border: 1px solid var(--hr-accent);
  border-radius: 3px;
  padding: 3px 6px;
  resize: vertical;
  min-height: 38px;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
}
.hr-rack-desc-pencil {
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  color: var(--hr-ink-muted);
  font-size: 1rem;
  line-height: 1;
  padding: 2px 6px;
  cursor: pointer;
  border-radius: 3px;
}
.hr-rack-desc-pencil:hover { color: var(--hr-ink); background: var(--hr-line-soft); }

/* R3+R4: per-rack Properties (description + color) in the details pane. */
.hr-field-row { flex-wrap: wrap; }
.hr-field-label { color: var(--hr-ink-muted); font-weight: 600; min-width: 110px; font-size: 0.9rem; }
/* E12: Buy / Lease acquisition toggle + the dimmed inactive price field. */
.hr-acq-toggle { display: inline-flex; border: 1px solid var(--hr-line); border-radius: 4px; overflow: hidden; }
.hr-acq-btn {
  border: 0; background: var(--hr-panel); color: var(--hr-ink);
  padding: 4px 14px; font: inherit; font-size: 0.9rem; cursor: pointer;
}
.hr-acq-btn + .hr-acq-btn { border-left: 1px solid var(--hr-line); }
.hr-acq-btn.hr-on { background: var(--hr-accent); color: var(--hr-surface); font-weight: 600; }
.hr-acq-btn:disabled { opacity: 0.5; cursor: default; }
.hr-field-dim { opacity: 0.5; }
/* E12: indented per-option add-on price fields under a count field. */
.hr-subfield { margin-left: 16px; font-size: 0.88rem; opacity: 0.92; }
.hr-rack-swatches { display: flex; gap: 4px; flex-wrap: wrap; flex: 1 1 auto; }
.hr-rack-swatch {
  width: 22px; height: 22px;
  border: 1px solid var(--hr-line);
  border-radius: 3px;
  padding: 0;
  cursor: pointer;
  flex: 0 0 auto;
}
.hr-rack-swatch:hover { transform: scale(1.1); }
.hr-rack-swatch-sel { outline: 2px solid var(--hr-accent); outline-offset: 1px; }
.hr-field-row input[type="color"] {
  flex: 0 0 32px;
  width: 32px; height: 26px;
  padding: 0; border: 1px solid var(--hr-line); border-radius: 3px;
  background: transparent;
  cursor: pointer;
}
.hr-actions { margin-top: 10px; display: flex; gap: 8px; }
.hr-actions button {
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink);
  padding: 4px 12px;
  font: inherit;
  font-size: 0.9rem;
  border-radius: 3px;
  cursor: pointer;
}
.hr-actions button:hover { background: var(--hr-line-soft); }
.hr-findings { margin: 4px 0; padding-left: 20px; font-size: 0.9rem; }
.hr-f-error { color: var(--hr-err-fg); }
.hr-f-warn  { color: var(--hr-warn-fg); }
.hr-findings-empty { color: var(--hr-ink-muted); font-style: italic; list-style: none; margin-left: -16px; }

/* A1: filter chip row above the Issues list, one chip per finding
   code currently in flight. Click toggles that code on/off; the
   trailing ⨯ chip clears all filters. */
.hr-findings-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 4px 0 6px;
}
.hr-findings-chip {
  font: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  padding: 2px 7px;
  border: 1px solid var(--hr-err-fg);
  background: color-mix(in srgb, var(--hr-err-fg) 14%, transparent);
  color: var(--hr-err-fg);
  border-radius: 10px;
  cursor: pointer;
  line-height: 1.2;
}
.hr-findings-chip:hover { filter: brightness(1.1); }
.hr-findings-chip-off {
  background: transparent;
  color: var(--hr-ink-muted);
  border-color: var(--hr-line);
  text-decoration: line-through;
}
.hr-findings-chip-clear {
  border-color: var(--hr-line);
  background: transparent;
  color: var(--hr-ink-muted);
}
.hr-scenario-goal {
  background: var(--hr-warn-bg);
  color: var(--hr-warn-fg);
  border-radius: 4px;
  padding: 6px 10px;
  margin: 2px 0;
}

/* UI5: faculty grade rubric - live acceptance checklist in the details pane.
   Met criteria read green (✓), unmet are muted (✗); the header tallies
   met/total and the whole card gets a green tint + PASS badge when all pass. */
.hr-rubric {
  margin: 8px 0 2px;
  border: 1px solid var(--hr-line);
  border-left: 3px solid var(--hr-ink-muted);
  border-radius: 0 4px 4px 0;
  padding: 6px 10px;
  background: color-mix(in srgb, var(--hr-ink-muted) 6%, transparent);
}
.hr-rubric-pass {
  border-left-color: #2e9e57;
  background: color-mix(in srgb, #2e9e57 10%, transparent);
}
.hr-rubric-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 0.9rem;
  margin-bottom: 4px;
}
.hr-rubric-score {
  font-variant-numeric: tabular-nums;
  color: var(--hr-ink-muted);
  font-weight: 600;
}
.hr-rubric-pass .hr-rubric-score { color: #2e9e57; }
.hr-rubric-badge {
  margin-left: auto;
  background: #2e9e57;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 1px 8px;
  border-radius: 10px;
}
.hr-rubric-list { list-style: none; margin: 0; padding: 0; }
.hr-rubric-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 0.88rem;
  padding: 1px 0;
}
.hr-rubric-mark { flex: 0 0 auto; width: 1em; font-weight: 700; text-align: center; }
.hr-rubric-ok  { color: var(--hr-ink); }
.hr-rubric-ok  .hr-rubric-mark { color: #2e9e57; }
.hr-rubric-no  { color: var(--hr-ink-muted); }
.hr-rubric-no  .hr-rubric-mark { color: var(--hr-err-fg); }
.hr-rubric-label  { flex: 1 1 auto; }
.hr-rubric-detail {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  color: var(--hr-ink-muted);
}
.hr-muted { color: var(--hr-ink-muted); font-size: 0.85rem; }
.hr-err { color: var(--hr-err-fg); margin: 6px 0; font-size: 0.9rem; min-height: 1.1em; }

/* ── palette ──────────────────────────────────────────────── */

.hr-palette {
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 18px;
  z-index: 10;
  display: flex;
  background: transparent;
  transition: width 0.18s ease;
  overflow: visible;
}
.hr-palette:hover, .hr-palette.hr-palette-pinned, .hr-palette.hr-palette-keepopen {
  width: var(--hr-palette-w, 280px);
}
/* While the user is dragging the resize handle, skip the width
   transition so the palette tracks the cursor immediately. */
.hr-palette:has(.hr-palette-resize.hr-divider-active) {
  transition: none;
}
.hr-palette-tab {
  width: 18px;
  background: var(--hr-accent);
  color: var(--hr-surface);
  font-size: 0.72rem;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  text-align: center;
  padding: 8px 0;
  cursor: pointer;
  user-select: none;
  flex: 0 0 auto;
}
.hr-palette-inner {
  flex: 1 1 auto;
  overflow-y: auto;
  background: var(--hr-surface);
  border-right: 1px solid var(--hr-line);
  border-top: 1px solid var(--hr-line);
  border-bottom: 1px solid var(--hr-line);
  padding: 0 0 4px;
  display: flex;
  flex-direction: column;
}
.hr-palette-header {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 10px;
  background: var(--hr-panel);
  border-bottom: 1px solid var(--hr-line);
}
.hr-palette-title {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--hr-ink-muted);
  font-weight: 700;
  flex: 1 1 auto;
}
/* Push-pin toggle: latches the palette open so it doesn't auto-hide. */
.hr-pal-pin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  padding: 0;
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink-muted);
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.hr-pal-pin:hover {
  color: var(--hr-accent);
  border-color: var(--hr-accent);
}
.hr-pal-pin.on {
  background: var(--hr-accent);
  color: var(--hr-surface);
  border-color: var(--hr-accent-dk);
}
.hr-pal-pin.on:hover { filter: brightness(1.08); }
/* Right-edge drag handle for palette width (UI9). Hidden until the
   palette is wide enough to be useful (pinned or hovered). */
.hr-palette-resize {
  position: absolute;
  top: 0; bottom: 0; right: -3px;
  width: 6px;
  cursor: ew-resize;
  background: transparent;
  z-index: 11;
  opacity: 0;
  transition: opacity 0.12s ease, background-color 0.12s ease;
}
.hr-palette:hover .hr-palette-resize,
.hr-palette.hr-palette-pinned .hr-palette-resize {
  opacity: 1;
  background: var(--hr-line);
}
.hr-palette-resize:hover,
.hr-palette-resize.hr-divider-active {
  background: var(--hr-accent);
}
/* Extended-catalog badge - color-only state: white (off) or green (on) */
.hr-extcat-badge {
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink-muted);
  border-radius: 12px;
  padding: 2px 12px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.hr-extcat-badge:hover {
  border-color: var(--hr-accent);
  color: var(--hr-accent);
}
.hr-extcat-badge.on {
  background: var(--hr-accent);
  color: var(--hr-surface);
  border-color: var(--hr-accent-dk);
}
.hr-extcat-badge.on:hover {
  filter: brightness(1.08);
}

/* "Add Custom" action button in the palette header (left of Extended).
   Same pill shape as the Extended badge; it's an action, not a toggle. */
.hr-addcustom-badge {
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink-muted);
  border-radius: 12px;
  padding: 2px 12px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.hr-addcustom-badge:hover { border-color: var(--hr-accent); color: var(--hr-accent); }

/* Cooling badge + popup in the main header (E8 follow-up). The badge
   mirrors the .hr-extcat-badge pill; the popup mirrors the ENE-themed
   .ect-nav-menu surface so it reads as the same menu family. */
/* Cooling badge now lives inside .ect-header-title, just after the
   "ECT Hotrack" text. Make the title a flex row so the two sit side by
   side on the left; the title still grows (flex:1 from iz.css) to push
   the app-title + hamburger to the right. */
.ect-header-title {
  display: flex;
  align-items: center;
  gap: 12px;
}
.hr-cool-ctl {
  position: relative;
  display: flex;
  align-items: center;
}
.hr-cool-badge {
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink-muted);
  border-radius: 12px;
  padding: 3px 12px;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.hr-cool-badge:hover { border-color: var(--hr-accent); color: var(--hr-accent); }
.hr-cool-badge.on {
  background: var(--hr-accent);
  color: var(--hr-surface);
  border-color: var(--hr-accent-dk, var(--hr-accent));
}
.hr-cool-badge.on:hover { filter: brightness(1.08); }

/* Per-layer badge colors. The badge always carries data-layer, so each
   layer reads as a distinct chip (placed after the .on rule to win at
   equal specificity). Racks = medium blue. */
.hr-cool-badge[data-layer="rack"]        { background: #2f6cae; color: #fff; border-color: #27598f; }
.hr-cool-badge[data-layer="connections"] { background: #6a3fb0; color: #fff; border-color: #583394; }
.hr-cool-badge[data-layer="overhead"]    { background: #0e8a8a; color: #fff; border-color: #0b7070; }
.hr-cool-badge[data-layer="floor"]       { background: #9c7d00; color: #fff; border-color: #806600; }
.hr-cool-badge[data-layer]:hover { filter: brightness(1.1); color: #fff; }

/* Header "Scenario Library" dropdown button (right of the hamburger).
   The button mirrors the hamburger's outlined-green look; the popup
   mirrors the ENE-themed light menu surface and right-aligns so it
   stays on-screen at the header's right edge. */
.hr-scenlib-ctl { position: relative; flex-shrink: 0; }
.hr-scenlib-btn {
  background: none;
  border: 2px solid var(--hr-accent, #00694e);
  color: var(--hr-accent, #00694e);
  font: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 12px;
  border-radius: 4px;
  line-height: 1;
  white-space: nowrap;
}
.hr-scenlib-btn:hover { background: var(--hr-accent, #00694e); color: var(--hr-surface, #fff); }
.hr-scenlib-popup {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 200px;
  max-width: 260px;
  overflow: visible;            /* let category flyouts spill out the side */
  background: var(--hr-surface);
  color: var(--hr-ink);
  border: 2px solid var(--hr-accent);
  border-radius: 8px;
  box-shadow: var(--hr-shadow);
  padding: 4px 0;
  z-index: 1000;
}
.hr-scenlib-popup[hidden] { display: none; }
/* Category list rows; hovering one reveals its flyout to the left. */
.hr-scenlib-cat-host { position: relative; }
.hr-scenlib-cat-row {
  display: block;
  padding: 8px 14px;
  text-decoration: none;
  color: var(--hr-accent-dk, var(--hr-accent));
  font-weight: 600;
  font-size: 0.92rem;
  cursor: pointer;
}
html[data-theme="dark"] .hr-scenlib-cat-row { color: var(--hr-accent); }
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] .hr-scenlib-cat-row { color: var(--hr-accent); }
}
.hr-scenlib-cat-row::after { content: " \25C2"; float: left; margin-right: 4px; opacity: 0.7; }
.hr-scenlib-cat-host:hover > .hr-scenlib-cat-row { background: var(--hr-line-soft); }
.hr-scenlib-flyout {
  display: none;
  position: absolute;
  right: calc(100% + 2px);      /* opens to the LEFT (popup hugs the screen's right edge) */
  top: -6px;
  min-width: 240px;
  max-width: 320px;
  max-height: 70vh;
  overflow-y: auto;
  background: var(--hr-surface);
  color: var(--hr-ink);
  border: 2px solid var(--hr-accent);
  border-radius: 8px;
  box-shadow: var(--hr-shadow);
  padding: 4px 0;
}
.hr-scenlib-cat-host:hover > .hr-scenlib-flyout { display: block; }
.hr-scenlib-item {
  display: block;
  padding: 6px 14px;
  text-decoration: none;
  color: var(--hr-ink);
}
.hr-scenlib-item:hover { background: var(--hr-line-soft); }
.hr-scenlib-title { font-weight: 600; color: var(--hr-accent-dk, var(--hr-accent)); font-size: 0.9rem; }
html[data-theme="dark"] .hr-scenlib-title { color: var(--hr-accent); }
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] .hr-scenlib-title { color: var(--hr-accent); }
}
.hr-scenlib-desc { font-size: 0.78rem; color: var(--hr-ink-muted); }
.hr-scenlib-empty { padding: 10px 14px; color: var(--hr-ink-muted); font-style: italic; }

/* Search + sort/filter row under the palette header (UI12). Sticky so
   it stays visible as the catalog scrolls underneath. */
.hr-palette-filter {
  position: sticky;
  top: 36px;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 8px;
  background: var(--hr-panel);
  border-bottom: 1px solid var(--hr-line);
}
.hr-pal-search {
  width: 100%;
  box-sizing: border-box;
  padding: 4px 8px;
  border: 1px solid var(--hr-line);
  border-radius: 4px;
  background: var(--hr-surface);
  color: var(--hr-ink);
  font: inherit;
  font-size: 0.85rem;
}
.hr-pal-search:focus {
  outline: 2px solid var(--hr-accent);
  outline-offset: -1px;
  border-color: var(--hr-accent);
}
.hr-pal-chips {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}
.hr-pal-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink-muted);
  border-radius: 4px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 0.12s, color 0.12s, border-color 0.12s;
}
.hr-pal-chip:hover { color: var(--hr-accent); border-color: var(--hr-accent); }
.hr-pal-chip.on {
  background: var(--hr-accent);
  color: var(--hr-surface);
  border-color: var(--hr-accent-dk);
}
.hr-pal-chip.on::after {
  content: " \25B2";                       /* ▲ ascending marker */
  font-size: 0.65rem;
  margin-left: 2px;
}
.hr-pal-chip.on.desc::after { content: " \25BC"; }   /* ▼ descending */
.hr-pal-vendor {
  flex: 1 1 auto;
  min-width: 80px;
  padding: 2px 4px;
  border: 1px solid var(--hr-line);
  background: var(--hr-surface);
  color: var(--hr-ink);
  border-radius: 4px;
  font: inherit;
  font-size: 0.78rem;
}
.hr-pal-clear {
  border: 1px solid transparent;
  background: transparent;
  color: var(--hr-ink-muted);
  width: 22px; height: 22px;
  padding: 0;
  border-radius: 4px;
  font: inherit;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  visibility: hidden;
}
.hr-pal-clear.on { visibility: visible; }
.hr-pal-clear:hover { color: var(--hr-err-fg); border-color: var(--hr-err-fg); }
.hr-palette-groups {
  flex: 1 1 auto;
}
.hr-palette-group { margin-bottom: 6px; }
.hr-palette-group-title {
  font-size: 0.75rem; text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--hr-ink-muted);
  padding: 4px 10px 2px;
  background: var(--hr-panel);
  border-top: 1px solid var(--hr-line-soft);
  border-bottom: 1px solid var(--hr-line-soft);
}
/* One-line explainer under a group title (e.g. raised-floor delivery note). */
.hr-palette-group-hint {
  font-size: 0.72rem;
  line-height: 1.35;
  color: var(--hr-ink-muted);
  padding: 4px 10px 5px;
  background: var(--hr-panel);
  border-bottom: 1px solid var(--hr-line-soft);
}
.hr-palette-item {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 10px;
  font-size: 0.85rem;
  cursor: grab;
  border-bottom: 1px solid var(--hr-line-soft);
  user-select: none;
}
.hr-palette-item:hover { background: var(--hr-line-soft); }
.hr-palette-item:active { cursor: grabbing; }
.hr-pal-u {
  background: var(--hr-accent);
  color: var(--hr-surface);
  border-radius: 3px;
  padding: 1px 5px;
  font-size: 0.72rem;
  font-weight: 700;
  min-width: 28px;
  text-align: center;
}
.hr-pal-name { flex: 1 1 auto; }
.hr-pal-watts { color: var(--hr-ink-muted); font-size: 0.78rem; }
/* Nameplate cooling capacity carried inline in a cooling item's name. */
.hr-pal-btu {
  color: var(--hr-accent);
  font-size: 0.72rem;
  margin-left: 4px;
  white-space: nowrap;
}
.hr-pal-cust {
  font-size: 0.7rem; color: var(--hr-rack-sel);
  border: 1px solid var(--hr-rack-sel);
  border-radius: 2px;
  padding: 0 3px;
  margin-left: 4px;
}
.hr-pal-vendor {
  font-size: 0.7rem; color: var(--hr-accent);
  border: 1px solid var(--hr-accent);
  border-radius: 2px;
  padding: 0 3px;
  margin-left: 4px;
}
/* E16: hot-aisle return pill + item accent (warm, vs blue supply diffusers). */
.hr-pal-return {
  font-size: 0.7rem; color: #e07b39;
  border: 1px solid #e07b39;
  border-radius: 2px;
  padding: 0 3px;
  margin-left: 4px;
}
.hr-palette-item-return { border-left: 3px solid #e07b39; }

/* UI6: shift-click queue. Banner sits between the filter row and the
   items list; per-item ×N badge marks queued entries. The whole
   palette gets a subtle accent border while a queue is staged so the
   user knows the next rack-slot click will be intercepted. */
.hr-pal-queue {
  border-top: 1px solid var(--hr-accent);
  border-bottom: 1px solid var(--hr-line-soft);
  background: color-mix(in srgb, var(--hr-accent) 10%, var(--hr-surface));
  padding: 6px 10px;
  font-size: 0.82rem;
}
.hr-pal-queue[hidden] { display: none; }
.hr-pal-queue-hd {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px;
  margin-bottom: 2px;
}
.hr-pal-queue-title { font-weight: 700; color: var(--hr-accent); }
.hr-pal-queue-clear {
  background: transparent;
  color: var(--hr-ink-muted);
  border: 1px solid var(--hr-line);
  border-radius: 3px;
  font: inherit;
  font-size: 0.74rem;
  padding: 1px 6px;
  cursor: pointer;
}
.hr-pal-queue-clear:hover { color: var(--hr-err-fg, #c0392b); border-color: var(--hr-err-fg, #c0392b); }
.hr-pal-queue-hint {
  font-size: 0.74rem;
  color: var(--hr-ink-muted);
  margin-bottom: 4px;
}
.hr-pal-queue-list {
  list-style: none;
  margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.hr-pal-queue-row {
  display: flex; align-items: center; gap: 6px;
  padding: 1px 0;
}
.hr-pal-queue-name { flex: 1 1 auto; }
.hr-pal-queue-remove {
  background: transparent;
  color: var(--hr-ink-muted);
  border: 1px solid var(--hr-line);
  border-radius: 3px;
  width: 18px; height: 18px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  font: inherit;
}
.hr-pal-queue-remove:hover { color: var(--hr-ink); }
.hr-palette-queued .hr-palette { /* fall-through to next; box-shadow set on root aside below */ }
.hr-palette.hr-palette-queued { box-shadow: inset 0 0 0 2px var(--hr-accent); }
.hr-palette-item-queued { background: color-mix(in srgb, var(--hr-accent) 12%, transparent); }
.hr-palette-item-active {
  background: color-mix(in srgb, var(--hr-accent) 18%, transparent);
  box-shadow: inset 3px 0 0 var(--hr-accent);
  cursor: copy;
}
.hr-pal-qbadge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--hr-surface);
  background: var(--hr-accent);
  border-radius: 8px;
  padding: 0 5px;
  margin-left: 4px;
}
.hr-palette-empty {
  padding: 16px 12px;
  color: var(--hr-ink-muted);
  font-style: italic;
  font-size: 0.9rem;
}

/* ── ghost (drag) ─────────────────────────────────────────── */

.hr-ghost {
  position: fixed; top: 0; left: 0;
  background: var(--hr-accent);
  color: var(--hr-surface);
  padding: 2px 8px;
  border-radius: 3px;
  font-size: 0.85rem;
  box-shadow: var(--hr-shadow);
  pointer-events: none;
  z-index: 9999;
  white-space: nowrap;
}

/* ── toasts ───────────────────────────────────────────────── */

.hr-toasts {
  position: absolute;
  bottom: 14px; right: 14px;
  display: flex; flex-direction: column;
  gap: 6px;
  pointer-events: none;
  z-index: 100;
}
.hr-toast {
  background: var(--hr-warn-bg);
  color: var(--hr-warn-fg);
  border: 1px solid var(--hr-warn-fg);
  padding: 4px 12px;
  border-radius: 4px;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.18s, transform 0.18s;
  font-size: 0.85rem;
}
.hr-toast-show { opacity: 1; transform: translateY(0); }

/* ── modal ────────────────────────────────────────────────── */

.hr-modal {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.5);
  display: flex; align-items: center; justify-content: center;
  z-index: 200;
}
.hr-modal[hidden] { display: none; }
.hr-modal-card {
  background: var(--hr-surface);
  color: var(--hr-ink);
  padding: 16px 22px;
  border-radius: 6px;
  box-shadow: var(--hr-shadow);
  max-width: 90%;
  max-height: 88vh;
  overflow: auto;
  min-width: 360px;
}
.hr-modal-card h2 { margin-top: 0; color: var(--hr-accent); }
.hr-modal-card h3 { color: var(--hr-accent); margin-top: 12px; }
.hr-modal-card textarea {
  width: 100%;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 0.82rem;
  resize: vertical;
  box-sizing: border-box;
  background: var(--hr-panel);
  color: var(--hr-ink);
  border: 1px solid var(--hr-line);
  border-radius: 3px;
  padding: 6px 8px;
}
.hr-modal-rule {
  border: 0;
  border-top: 1px solid var(--hr-line);
  margin: 18px 0 12px;
}
.hr-modal-actions { margin-top: 14px; display: flex; gap: 8px; justify-content: flex-end; }
.hr-modal-actions button {
  border: 1px solid var(--hr-line);
  background: var(--hr-accent);
  color: var(--hr-surface);
  padding: 6px 14px;
  font: inherit;
  font-size: 0.92rem;
  border-radius: 3px;
  cursor: pointer;
}
.hr-modal-actions button[data-act="modal-close"],
.hr-modal-actions button:last-child {
  background: var(--hr-surface);
  color: var(--hr-ink);
  border-color: var(--hr-line);
}
.hr-modal-actions button:hover { filter: brightness(1.06); }
.hr-modal-logo { float: right; width: 70px; height: auto; }

/* 3D1: full-window 3D view. Fixed overlay that covers the entire window
   (header + three-pane app), with a top bar carrying the title, controls
   hint, and Exit. */
.hr-3d {
  position: fixed; inset: 0; z-index: 9000;
  background: #0a0f12;
  overflow: hidden;
}
.hr-3d-canvas { display: block; width: 100%; height: 100%; touch-action: none; cursor: grab; }
.hr-3d-canvas:active { cursor: grabbing; }
.hr-3d-bar {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; align-items: center; gap: 14px;
  padding: 8px 12px;
  background: linear-gradient(180deg, rgba(0,0,0,0.55), rgba(0,0,0,0));
  color: #fff; font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  pointer-events: none;
}
.hr-3d-title { font-weight: 700; font-size: 1rem; }
.hr-3d-hint { flex: 1 1 auto; font-size: 0.82rem; color: rgba(255,255,255,0.78); }
.hr-3d-exit {
  pointer-events: auto;
  font: inherit; font-size: 0.85rem; font-weight: 600;
  padding: 5px 14px; border-radius: 6px; cursor: pointer;
  color: #fff; background: var(--hr-accent, #00694e);
  border: 1px solid rgba(255,255,255,0.35);
}
.hr-3d-exit:hover { filter: brightness(1.12); }
/* Top-bar toggles (e.g. Heat overlay). Pill that lights up when active. */
.hr-3d-toggle {
  pointer-events: auto;
  font: inherit; font-size: 0.82rem; font-weight: 600;
  padding: 5px 12px; border-radius: 6px; cursor: pointer;
  color: rgba(255,255,255,0.9); background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.30);
}
.hr-3d-toggle:hover { background: rgba(255,255,255,0.18); }
.hr-3d-toggle.on {
  color: #fff; background: var(--hr-accent, #00694e); border-color: rgba(255,255,255,0.5);
}
/* Orbit / Walk / Fly segmented camera-mode control. */
.hr-3d-modes {
  pointer-events: auto; display: inline-flex; border-radius: 6px; overflow: hidden;
  border: 1px solid rgba(255,255,255,0.30);
}
.hr-3d-mode {
  font: inherit; font-size: 0.82rem; font-weight: 600; cursor: pointer;
  padding: 5px 12px; border: 0; border-left: 1px solid rgba(255,255,255,0.22);
  color: rgba(255,255,255,0.9); background: rgba(255,255,255,0.10);
}
.hr-3d-mode:first-child { border-left: 0; }
.hr-3d-mode:hover { background: rgba(255,255,255,0.18); }
.hr-3d-mode.on { color: #fff; background: var(--hr-accent, #00694e); }
/* Hide the 2D scrollbars while the overlay owns the window. */
html.hr-3d-active, html.hr-3d-active body { overflow: hidden; }
/* No-WebGL fallback screen. */
.hr-3d-fallback {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 24px; text-align: center; color: #e8eef0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}
.hr-3d-fallback h2 { margin: 0; font-size: 1.4rem; }
.hr-3d-fallback p { margin: 0; max-width: 460px; line-height: 1.5; color: rgba(232,238,240,0.85); }
.hr-3d-fallback-tip { font-size: 0.9rem; color: rgba(232,238,240,0.6); }
.hr-3d-fallback-btn {
  margin-top: 10px; font: inherit; font-weight: 600; font-size: 0.95rem;
  padding: 8px 18px; border-radius: 6px; cursor: pointer;
  color: #fff; background: var(--hr-accent, #00694e); border: 1px solid rgba(255,255,255,0.35);
}
.hr-3d-fallback-btn:hover { filter: brightness(1.12); }
