@import url("navigation-drawer.css");
/* The dark :root that used to sit here is gone. Every one of its eleven
   declarations was redeclared by the light "Mainframe shell language" block
   further down at the same specificity, so the later one already won and this
   block rendered nothing in either theme - it only kept ten dead colour
   literals alive. Deleting it is a zero-rendering change. */
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  background:
    radial-gradient(circle at 85% -10%, #173242 0, transparent 34%), var(--bg);
  color: var(--ink);
  font:
    14px/1.5 Inter,
    ui-sans-serif,
    system-ui;
}
/* SCOPED. This was a bare `header {}`, and #shell-taskbar is a header, so the
 * page banner's 30px gap and space-between decided the TASKBAR's spacing on
 * every page - a 30px dead strip after every control, and nine controls
 * needing 537px inside a 390px bar on Overwatch. Two other rules already
 * existed to undo this leak: `.drawer > header` at the drawer level, whose
 * comment names "the legacy page rule", and the >=700px override below. The
 * banner already carries class="site-header", and every remaining bare
 * <header> in these pages is inside a drawer. */
.site-header {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-between;
  gap: 30px;
  align-items: end;
  padding: 42px clamp(22px, 5vw, 72px) 28px;
  border-bottom: 1px solid var(--line);
}
h1 {
  font-size: clamp(36px, 6vw, 68px);
  line-height: 0.95;
  letter-spacing: -0.055em;
  margin: 4px 0 16px;
}
h2 {
  font-size: 22px;
  margin: 3px 0 7px;
}
.eyebrow,
.project-id {
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--cyan);
  font-size: 11px;
}
.lede {
  max-width: 680px;
  color: var(--muted);
  font-size: 17px;
  margin: 0;
}
.pulse {
  min-width: 170px;
  text-align: right;
  display: grid;
  justify-items: end;
  gap: 4px;
}
.pulse span {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 20px var(--green);
}
.pulse small {
  color: var(--muted);
}
main {
  padding: 24px clamp(18px, 5vw, 72px) 70px;
}
.cic-dashboard{display:grid;grid-template-columns:minmax(240px,1fr) minmax(300px,2fr) auto;gap:18px;align-items:center;padding:20px;margin:0 0 26px;background:linear-gradient(135deg,#14232c,#0d151b);border:1px solid var(--line);border-radius:14px}.cic-dashboard h2{margin:2px 0}.cic-dashboard p{margin:0;color:var(--muted)}.cic-dashboard button{border:1px solid var(--cyan);background:var(--cyan);color:#051115;border-radius:8px;padding:11px 14px;font:inherit;font-weight:750;cursor:pointer}.landing-runner-status{display:flex;gap:7px;flex-wrap:wrap}.landing-runner-status span{padding:6px 9px;border-radius:99px;background:#17242d;border:1px solid var(--line);color:var(--muted);font-size:12px}.section-title{margin:0 0 4px}
.toolbar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  justify-content: space-between;
  gap: 18px;
  align-items: end;
  padding: 14px 0;
  background: linear-gradient(var(--bg) 76%, transparent);
}
label {
  color: var(--muted);
  font-size: 12px;
}
input {
  display: block;
  margin-top: 6px;
  width: min(420px, 72vw);
  padding: 11px 13px;
  background: #0d141b;
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--ink);
  font: inherit;
}
.filters {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.filters button,
.launches a,
.repo-link {
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  border-radius: 8px;
  padding: 9px 12px;
  text-decoration: none;
  font: inherit;
  cursor: pointer;
}
.filters button.active {
  background: var(--cyan);
  border-color: var(--cyan);
  color: #051115;
  font-weight: 750;
}
.summary {
  display: grid;
  grid-template-columns: repeat(4, minmax(100px, 1fr));
  gap: 10px;
  margin: 15px 0 24px;
}
.metric {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 15px;
}
.metric b {
  display: block;
  font-size: 25px;
}
.metric small {
  color: var(--muted);
}
#content {
  display: grid;
  gap: 14px;
}
/* THE DEFECT THIS FIXES: `linear-gradient(145deg, var(--panel), #0d141a)` mixed
   the light re-skin's --panel with a near-black literal left over from the dark
   design that replaced it - so every card in Projects, Hosted items and
   Repositories painted a charcoal slab on a cream page. Measured worst contrast
   1.07:1, which is unreadable, not merely poor.

   It survived every earlier audit because `background: linear-gradient(...)`
   leaves `background-color: transparent`: a contrast probe that reads
   backgroundColor sails straight past the painted pixels and scores the text
   against the cream page behind the card, which passes.

   These values are copied from .hierarchy-card, the card on this page that was
   already re-skinned - so the three panes JOIN that card rather than losing
   their card. No box-shadow: they have none at rest today. */
.project-card,
.service-card,
.repo-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: .3rem solid var(--cyan);
  border-radius: 0;
  padding: .55rem .65rem .6rem;
}
.project-head {
  display: flex;
  justify-content: space-between;
  gap: 18px;
}
.project-head p,
.repo-card p {
  color: var(--muted);
  margin: 0;
}
.repo-count {
  white-space: nowrap;
  color: var(--muted);
}
.capabilities,
.relations,
.launches {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 14px;
}
/* Two private palettes from the dark design - a teal chip and a brown/sand one
   - replaced by pinned tokens. The distinction between a capability chip and a
   relation chip is kept; only the colours change. Padding, radius and size are
   copied from .ctc-indicator in task-status.css. */
.capabilities span,
.relation {
  padding: .12rem .42rem;
  border-radius: 1rem;
  border: 1px solid var(--line);
  background: var(--panel2);
  color: var(--ink);
  font-size: .67rem;
}
.relation {
  background: var(--accent-subtle);
  color: var(--cyan);
}
.launches a:hover,
.repo-link:hover {
  border-color: var(--cyan);
}
.service-grid,
.repo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}
.service-top,
.repo-top {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}
.status {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.online {
  color: var(--green);
}
.offline {
  color: var(--red);
}
.unknown {
  color: var(--amber);
}
.service-card h2,
.repo-card h2 {
  font-size: 18px;
}
/* .service-card a now joins the compact-control list below - same job as
   .launches a and .repo-link, so one treatment rather than three. */
.repo-meta {
  color: var(--muted);
  font-size: 12px;
}
.unused {
  opacity: 0.68;
}
.selectable {
  cursor: pointer;
  transition:
    border-color 0.16s ease,
    transform 0.16s ease,
    box-shadow 0.16s ease;
}
/* The .selectable:hover that was here is fully overridden by the re-skinned
   rule further down; it was dead and carried two more dark-theme literals. */
.selectable:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 3px;
}
.drawer-open {
  overflow: hidden;
}
.drawer-backdrop {
  position: fixed;
  z-index: 20;
  inset: 0;
  background: #02070bcc;
  backdrop-filter: blur(3px);
}
.detail-panel {
  position: fixed;
  z-index: 21;
  top: 0;
  width: min(480px, 94vw);
  height: 100dvh;
  overflow: auto;
  padding: clamp(24px, 5vw, 46px);
  /* The dark gradient, border and shadow that were here are overridden by the
     light re-skin further down, so they painted nothing and only kept four dark
     literals alive. Zero-rendering removal, same class as the dead :root. */
  visibility: hidden;
  transition:
    transform 0.22s ease,
    visibility 0.22s;
}
.detail-panel-right {
  right: 0;
  border-width: 0 0 0 1px;
  box-shadow: -22px 0 70px #000b;
  transform: translateX(105%);
}
.detail-panel.open {
  transform: none;
  visibility: visible;
}
.detail-close {
  position: sticky;
  top: 0;
  float: right;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: #111820;
  color: var(--ink);
  font-family: inherit;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
}
.detail-close:hover,
.detail-close:focus-visible {
  border-color: var(--cyan);
  outline: none;
}
.detail-panel h2 {
  clear: both;
  margin: 12px 0;
  font-size: clamp(28px, 5vw, 40px);
  line-height: 1.08;
}
.detail-summary {
  color: var(--muted);
  font-size: 16px;
}
.detail-meta {
  display: grid;
  gap: 7px;
  margin: 24px 0;
}
.detail-meta p {
  margin: 0;
  padding: 10px 12px;
  border-left: 3px solid var(--cyan);
  background: #101a22;
  color: #c6d2d9;
}
.detail-panel .launches {
  margin-top: 24px;
}
.detail-panel .launches a {
  flex: 1 1 180px;
  text-align: center;
}
.detail-panel .launches a:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 2px;
}
.edge-tab {
  position: fixed;
  z-index: 18;
  top: 38%;
  min-height: 48px;
  border: 1px solid var(--line);
  background: #111820;
  color: var(--ink);
  font: 700 12px/1 system-ui;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.edge-tab-left {
  left: 0;
  border-radius: 0 9px 9px 0;
  padding: 12px 9px;
  writing-mode: vertical-rl;
}
.edge-tab span {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  min-height: 22px;
  margin-top: 7px;
  border-radius: 99px;
  background: var(--cyan);
  color: #051115;
}
.edge-tab:focus-visible,
.task-manager-panel button:focus-visible,
.task-manager-panel input:focus-visible,
.task-manager-panel textarea:focus-visible,
.task-manager-panel select:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 2px;
}
.task-manager-panel {
  position: fixed;
  z-index: 19;
  top: 0;
  bottom: 0;
  left: 0;
  width: min(620px, 96vw);
  display: grid;
  grid-template-rows: auto auto auto minmax(0, 1fr);
  gap: 13px;
  padding: 18px;
  /* Same: overridden by the light re-skin, so this painted nothing. */
  transform: translateX(-105%);
  visibility: hidden;
  transition:
    transform 0.22s ease,
    visibility 0.22s;
  overflow: hidden;
}
.task-manager-panel.open {
  transform: none;
  visibility: visible;
}
.task-manager-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding: 0;
  border: 0;
}
.task-manager-header h2 {
  margin: 0;
}
.task-manager-header .eyebrow {
  margin: 0 0 4px;
}
.task-freshness {
  margin: 5px 0 0;
  color: var(--muted);
  font-size: 12px;
}
.task-manager-close {
  width: 42px;
  height: 42px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--panel);
  color: var(--ink);
  font-size: 25px;
  cursor: pointer;
}
.runner-strip {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #0c141b;
}
.runner-strip div {
  display: grid;
}
.runner-strip small {
  color: var(--muted);
}
.runner-strip button,
.task-composer button {
  border: 1px solid #347b85;
  border-radius: 7px;
  background: #123039;
  color: #c8f5f6;
  padding: 8px 10px;
  cursor: pointer;
}
.runner-pulse {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 12px currentColor;
}
.runner-pulse.online {
  background: var(--green);
  color: var(--green);
}
.runner-pulse.offline {
  background: var(--red);
  color: var(--red);
}
.task-composer {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 13px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #0d151c;
}
.task-composer label,
.task-composer fieldset {
  margin: 0;
}
.task-composer input,
.task-composer textarea,
.task-composer select {
  width: 100%;
  margin-top: 5px;
  background: #080e13;
}
.task-composer select {
  min-height: 74px;
  padding: 7px;
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--ink);
}
.task-composer fieldset {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.task-composer fieldset input {
  display: inline;
  width: auto;
  margin: 0;
}
.routing-options {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.task-composer > label:last-of-type,
.composer-actions {
  grid-column: 1/-1;
}
.composer-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.composer-actions span {
  color: var(--muted);
  font-size: 12px;
}
.task-board {
  min-height: 0;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
}
.task-board-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.task-board-heading h3 {
  margin: 0;
}
.task-board-heading span {
  color: var(--muted);
}
.task-rows {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
  min-width: 0;
  padding: 8px 0 18px;
}
.task-group {
  min-width: 0;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: #0b1218;
}
.task-group > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2px 8px;
  border: 0;
}
.task-group h4 {
  margin: 0;
  text-transform: capitalize;
}
.task-group > header span {
  color: var(--muted);
}
.task-card {
  margin-top: 5px;
  min-width: 0;
  border: 1px solid #2b3c49;
  border-radius: 9px;
  background: #121d25;
}
.task-row > summary {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 3px 8px;
  padding: 8px 10px;
  cursor: pointer;
  list-style: none;
}
.task-row > summary::-webkit-details-marker { display: none; }
.task-row > summary::before { content: "▸"; grid-row: 1 / 3; }
.task-row[open] > summary::before { content: "▾"; }
.task-row > summary strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.task-row > summary:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.task-row-preview { grid-column: 2 / -1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: 12px; }
.task-row-details { display: grid; gap: 8px; padding: 4px 10px 10px; overflow-wrap: anywhere; }
.task-row-details > p { white-space: pre-wrap; }
.task-row .task-cancel { justify-self: start; }
.task-card-top {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.task-card p {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
}
.task-card dl {
  display: grid;
  gap: 3px;
  margin: 0;
}
.task-card dl div {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.task-card dt {
  color: var(--muted);
}
.task-card dd {
  margin: 0;
  text-align: right;
}
.task-state {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--amber);
}
.task-state-completed {
  color: var(--green);
}
.task-state-failed,
.task-state-blocked {
  color: var(--red);
}
.task-state-running {
  color: var(--cyan);
}
.task-checkins {
  display: grid;
  gap: 3px;
  padding-top: 6px;
  border-top: 1px solid var(--line);
  /* was #b7c6cf, a dark-theme grey-blue that measured 1.58:1 once this panel
     turned light. --muted is the pinned equivalent and flips with the chrome. */
  color: var(--muted);
}
.task-empty {
  color: var(--muted);
  font-size: 12px;
}
@media (max-width: 700px) {
  .cic-dashboard{grid-template-columns:1fr;align-items:start}
  .site-header {
    align-items: start;
    flex-direction: column;
  }
  .pulse {
    text-align: left;
    justify-items: start;
  }
  .toolbar {
    align-items: start;
    flex-direction: column;
  }
  .summary {
    grid-template-columns: repeat(2, 1fr);
  }
  .detail-panel {
    width: 100%;
    padding: 22px;
  }
  .task-manager-panel {
    width: 100%;
    padding: 13px;
  }
  .task-composer {
    grid-template-columns: 1fr;
  }
  .task-composer > label:last-of-type,
  .composer-actions {
    grid-column: auto;
  }
  .runner-strip {
    grid-template-columns: auto 1fr;
  }
  .runner-strip button {
    grid-column: 1/-1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .selectable,
  .detail-panel,
  .task-manager-panel {
    transition: none;
  }
}
@media (prefers-reduced-transparency: reduce) {
  .drawer-backdrop {
    backdrop-filter: none;
  }
  .detail-panel {
    background: #111820;
  }
}


/* Canonical product ownership is a tree; the existing cards remain available
   as flat diagnostic views for operational filtering. */
.hierarchy-tree,
.hierarchy-tree ol {
  list-style: none;
  margin: 0;
  padding: 0;
}
.hierarchy-tree ol {
  margin-left: 1.15rem;
  padding-left: 1.15rem;
  border-left: 2px solid var(--line, #c9d5e2);
}
.hierarchy-node { margin: 0 0 0.8rem; }
.hierarchy-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.75rem;
  padding: 1rem;
  border: 1px solid var(--line, #c9d5e2);
  border-radius: 0.75rem;
  background: var(--panel, #fff);
}
.hierarchy-card h2,
.hierarchy-card h3,
.hierarchy-card h4,
.hierarchy-card h5,
.hierarchy-card h6 { margin: 0.15rem 0 0.35rem; }

/* The compact type scale the re-skin never ported to these three panes.
   Values copied verbatim from the Hierarchy card rules above, so the cards
   read at the same density as the rest of the page instead of at the dark
   design’s 22px/18px/11px/12px. */
.project-card h2, .service-card h2, .repo-card h2 { font-size: .82rem; line-height: 1.1; }
.project-id { font-size: .54rem; font-weight: 900; letter-spacing: .13em; }
.repo-meta { font-size: .58rem; }
/* SCOPED deliberately. An unscoped `.status` rule would leak into
   cic/topology/bridge/, which loads ../styles.css and emits <div class="status">. */
.project-card .status, .service-card .status, .repo-card .status { font-size: .48rem; }
.owned-resources { grid-column: 1 / -1; margin: 0; font-size: 0.82rem; opacity: 0.78; }
@media (max-width: 700px) {
  .hierarchy-card { grid-template-columns: 1fr; }
  .hierarchy-tree ol { margin-left: 0.45rem; padding-left: 0.65rem; }
}

/* Mainframe shell language: compact paper/blue controls, translucent chrome,
   and a registry-driven mind-map in place of dashboard-sized cards. */
:root {
  color-scheme: light;
  /* Was a literal copy of the old tan, so changing --of-paper in the shared
   * palette did not reach this page at all. */
  --bg: var(--of-paper);
  --panel: rgba(255, 255, 255, 0.72);
  --panel2: #e9eef9;
  --ink: #111a2d;
  --muted: #536078;
  --line: #8193bc;
  --cyan: #002eac;
  --green: #16803d;
  /* #ad5b00 measured 4.45:1 on --panel2, a hair under AA, which is what the
     queued / in_progress / cancelled task states render on. Darkened until it
     clears 4.5:1 there - measured, not eyeballed. */
  --amber: #9a5200;
  --red: #b62d35;
  --chrome: rgba(0, 46, 172, 0.92);
  /* Global semantic theme contract. Modules consume these tokens and own no palette. */
  /* Was rgba(247, 243, 234, 0.96): a THIRD literal copy of the retired tan,
   * after the base token and the shared semantic layer. Each one had to be
   * found separately because nothing connected them. Derived now. */
  --surface-overlay: color-mix(in srgb, var(--of-paper) 96%, transparent);
  --surface-subtle: rgba(255, 255, 255, 0.55);
  --control-surface: rgba(255, 255, 255, 0.72);
  --field-surface: #fff;
  --overlay-scrim: rgba(4, 16, 46, 0.48);
  --line-strong: #536b9f;
  --accent: var(--cyan);
  --accent-subtle: rgba(0, 46, 172, 0.1);
  --link: var(--cyan);
  --status-info: var(--cyan);
  --shadow-drawer: 1.1rem 0 3rem rgba(4, 16, 46, 0.28);
}

/* ---------- dark theme, scoped to the shell chrome ---------------------------
   THE DEFECT, measured not guessed: the shared dark blocks in shell-tokens.css
   carry `[data-theme="dark"]` (specificity 0,1,1), so the SURFACE tokens
   (--surface-overlay, --control-surface, --field-surface) win over this file's
   plain `:root` and go dark. But --ink and --muted are re-pinned here as
   literals in a plain :root and never flip. Result: the drawers and the login
   splash painted a dark panel with light-theme ink. Every text element on the
   splash failed - 8 of 8, the worst at 1.02:1, which is invisible.

   SCOPED DELIBERATELY, and this is the load-bearing part. Re-aliasing at :root
   also turns the Control Center body dark, and its cards are not dark-ready -
   they went light-on-light. Before this change the page body was coherently
   LIGHT in dark mode; only the chrome was broken. So the fix repairs exactly
   what was broken and does not half-repaint a page that was fine. A full dark
   theme for the CIC page body is real work, now visible and named, not silently
   half-done here.

   It owns no new colour: it re-aliases onto the shared --of-* tokens, which
   already carry correct dark values. Both switches are emitted because both are
   in use on this surface (OPEN_QUESTIONS: the shell used the media query, the
   apps use [data-theme]). */
.drawer,
.right-drawer-tabs,
#identity-splash {
  --chrome-ink: var(--ink);
  --chrome-muted: var(--muted);
  --chrome-line: var(--line);
  --chrome-accent: var(--accent);
}
:root[data-theme="dark"] :is(.drawer, .right-drawer-tabs, #identity-splash),
:root[data-theme="dark"] #identity-splash {
  --ink: var(--of-ink);
  --muted: var(--of-ink-soft);
  --line: var(--of-rule);
  --line-strong: var(--of-rule);
  --cyan: var(--of-primary-soft);
  --accent: var(--of-primary-soft);
  --panel: var(--surface-subtle);
  --panel2: var(--of-paper-soft);
  color: var(--of-ink);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) :is(.drawer, .right-drawer-tabs, #identity-splash) {
    --ink: var(--of-ink);
    --muted: var(--of-ink-soft);
    --line: var(--of-rule);
    --line-strong: var(--of-rule);
    --cyan: var(--of-primary-soft);
    --accent: var(--of-primary-soft);
    --panel: var(--surface-subtle);
    --panel2: var(--of-paper-soft);
    color: var(--of-ink);
  }
}

body {
  min-width: 18rem;
  background:
    linear-gradient(rgba(0, 46, 172, .035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 46, 172, .035) 1px, transparent 1px),
    var(--bg);
  background-size: 2rem 2rem;
  font-family: "Arial Rounded MT Bold", "Trebuchet MS", Arial, sans-serif;
}
.site-header {
  position: sticky;
  top: 0;
  z-index: 8;
  align-items: center;
  padding: .55rem clamp(1rem, 3vw, 2.4rem);
  border-bottom: 1px solid rgba(255,255,255,.5);
  background: var(--chrome);
  color: #fff;
  box-shadow: 0 .25rem 1.2rem rgba(14, 29, 63, .18);
  backdrop-filter: blur(14px) saturate(125%);
}
.site-header h1 { margin: .05rem 0; font-size: clamp(1.25rem, 2.4vw, 1.8rem); line-height: 1.05; letter-spacing: -.025em; }
.site-header .eyebrow { margin: 0; color: #c8d8ff; font-size: .58rem; }
.site-header .lede { max-width: 48rem; color: #e7edff; font-size: .72rem; }
.site-header .pulse { min-width: 10rem; gap: .1rem; font-size: .68rem; }
.site-header .pulse span { width: .48rem; height: .48rem; }
.site-header .pulse small { color: #d3ddf7; font-size: .56rem; }
main { padding: 1rem clamp(1rem, 3vw, 2.4rem) 4.5rem; }
.cic-dashboard {
  grid-template-columns: minmax(12rem, .8fr) minmax(18rem, 1.5fr) auto;
  gap: .75rem;
  margin: 0 0 .9rem;
  padding: .7rem .85rem;
  border-radius: .25rem;
  background: rgba(255,255,255,.62);
  box-shadow: 0 .35rem 1.1rem rgba(27, 48, 91, .08);
  backdrop-filter: blur(12px);
}
.cic-dashboard h2, .section-title { font-size: .95rem; }
.cic-dashboard .eyebrow { margin: 0; font-size: .56rem; }
.cic-dashboard p { font-size: .67rem; }
.cic-dashboard button, .filters button, .launches a, .repo-link, .service-card a {
  min-height: 2rem;
  padding: .3rem .65rem;
  border-radius: .2rem;
  font-size: .65rem;
  font-weight: 900;
  letter-spacing: .045em;
  text-transform: uppercase;
}
.landing-runner-status { gap: .25rem; }
.landing-runner-status span { padding: .25rem .45rem; border-radius: .2rem; background: var(--panel2); font-size: .6rem; }
.toolbar { top: 4.15rem; gap: .7rem; padding: .45rem 0; background: rgba(247,243,234,.9); backdrop-filter: blur(10px); }
.toolbar label { font-size: .6rem; font-weight: 900; letter-spacing: .05em; text-transform: uppercase; }
input { width: min(25rem, 72vw); margin-top: .2rem; padding: .42rem .6rem; border-radius: .2rem; background: rgba(255,255,255,.75); font-size: .72rem; }
.filters { gap: .25rem; }
.filters button { color: var(--cyan); background: rgba(255,255,255,.65); }
.filters button.active { color: var(--bar-fg); }
.summary { grid-template-columns: repeat(4, minmax(5rem, 1fr)); gap: .35rem; margin: .55rem 0 .8rem; }
.metric { padding: .45rem .65rem; border-radius: .2rem; background: rgba(255,255,255,.58); }
.metric b { display: inline; margin-right: .3rem; color: var(--cyan); font-size: 1rem; }
.metric small { font-size: .58rem; }

.mindmap-viewport { --rail: 1px; --bus: 2px; --gutter: 1rem; --anchor: 1.5rem; overflow: hidden; padding: 1rem; border: 1px solid rgba(129,147,188,.58); background: rgba(255,255,255,.38); box-shadow: inset 0 0 2rem rgba(0,46,172,.035); }
.mindmap-viewport:focus-visible { outline: 3px solid var(--cyan); outline-offset: 2px; }
.module-grid, .branch-children { list-style: none; margin: 0; padding: 0; }
.topology-root { position: relative; display: flex; justify-content: center; padding-bottom: 2.25rem; }
.topology-root::after { content: ""; position: absolute; left: 50%; bottom: 1.25rem; height: 1rem; border-left: var(--rail) solid var(--line); }
/* A branch card has a readable floor. `--module-count` describes the data, not
 * the number of columns the viewport can sustain: using it as both collapsed an
 * eleven-branch tree into 75px cards on ordinary landscape tablets. */
.module-grid { position: relative; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: var(--gutter); }
.module-grid::before { content: ""; position: absolute; top: -1.25rem; left: var(--rail-inset); right: var(--rail-inset); border-top: var(--bus) solid var(--line); }
.hierarchy-branch { position: relative; min-width: 0; }
.module-grid > .hierarchy-branch::before { content: ""; position: absolute; left: 50%; top: -1.25rem; height: 1.25rem; border-left: var(--rail) solid var(--line); }
.branch-children { position: relative; display: grid; gap: .55rem; margin: .65rem 0 0 1.25rem; padding-left: .8rem; }
.branch-children > .hierarchy-branch::before { content: ""; position: absolute; left: -.8rem; top: var(--anchor); width: .8rem; border-top: var(--rail) solid var(--line); }
.branch-children > .hierarchy-branch::after { content: ""; position: absolute; left: -.8rem; top: -.55rem; bottom: -.55rem; border-left: var(--rail) solid var(--line); }
.branch-children > .hierarchy-branch:last-child::after { bottom: auto; height: calc(var(--anchor) + .55rem); }
.hierarchy-branch:has(> .branch-children) > .hierarchy-card::after { content: ""; position: absolute; left: 1.25rem; top: 100%; height: .65rem; border-left: var(--rail) solid var(--line); }
.hierarchy-card {
  position: relative;
  display: flex;
  align-items: stretch;
  width: 100%;
  max-width: 15rem;
  min-height: 4.5rem;
  padding: 0;
  border: 1px solid var(--line);
  border-left: .3rem solid var(--cyan);
  border-radius: 0;
  background: rgba(255,255,255,.8);
  box-shadow: 0 .3rem .85rem rgba(18, 42, 86, .08);
}
.hierarchy-card-body { min-width: 0; flex: 1 1 auto; padding: .55rem .65rem .6rem; }
.hierarchy-launch {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  gap: .2rem;
  min-width: 3.15rem;
  padding: .45rem;
  border-left: 1px solid var(--line);
  background: rgba(233,238,249,.82);
  color: var(--cyan);
  font-size: .55rem;
  font-weight: 900;
  letter-spacing: .04em;
  text-decoration: none;
  text-transform: uppercase;
}
.hierarchy-launch:hover, .hierarchy-launch:focus-visible { background: var(--cyan); color: #fff; outline: 2px solid var(--ink); outline-offset: -2px; }
.topology-root .hierarchy-card { width: min(15rem, 100%); }
.node-kicker { display: flex; justify-content: space-between; align-items: center; gap: .35rem; }
.node-kicker small { color: var(--cyan); font-size: .54rem; font-weight: 900; letter-spacing: .13em; text-transform: uppercase; }
.node-status { display: inline-flex; align-items: center; gap: .2rem; color: var(--muted); font-size: .48rem; text-transform: uppercase; }
.node-status::before { content: ""; width: .38rem; height: .38rem; border-radius: 50%; background: currentColor; }
.hierarchy-card h2, .hierarchy-card h3, .hierarchy-card h4, .hierarchy-card h5, .hierarchy-card h6 { margin: .18rem 0; color: var(--ink); font-size: .82rem; line-height: 1.1; }
.hierarchy-card p { display: -webkit-box; overflow: hidden; margin: 0; color: var(--muted); font-size: .58rem; line-height: 1.3; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.selectable:hover { border-color: var(--cyan); transform: translateY(-1px); box-shadow: 0 .45rem 1rem rgba(0,46,172,.14); }
.edge-tab { min-height: 2rem; background: rgba(0,46,172,.9); border-color: #7391dd; color: #fff; backdrop-filter: blur(10px); }
.edge-tab-left { padding: .5rem .35rem; border-radius: 0 .2rem .2rem 0; }
.edge-tab span { min-width: 1.15rem; min-height: 1.15rem; background: #fff; color: var(--cyan); }
.detail-panel, .task-manager-panel { background: rgba(247,243,234,.94); border-color: var(--line); box-shadow: 0 0 3rem rgba(4,16,46,.28); backdrop-filter: blur(18px) saturate(115%); }
.detail-close, .task-manager-close { color: var(--ink); background: rgba(255,255,255,.72); }
.detail-meta p, .runner-strip, .task-composer, .task-group { background: rgba(233,238,249,.72); color: var(--ink); }
.task-card { background: rgba(255,255,255,.72); }
.task-composer input, .task-composer textarea, .task-composer select { background: #fff; color: var(--ink); }

@media (max-width: 1000px) {
  .mindmap-viewport { overflow: hidden; }
  .topology-root { justify-content: flex-start; padding-bottom: .65rem; }
  .topology-root::after, .module-grid::before, .module-grid > .hierarchy-branch::before { display: none; }
  .module-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .7rem; }
  .module-grid > .hierarchy-branch { min-width: 0; }
}
@media (max-width: 700px) {
  .site-header { position: relative; align-items: flex-start; padding: .65rem 1rem; }
  .site-header .pulse { display: none; }
  .cic-dashboard { grid-template-columns: 1fr; }
  .toolbar { top: 0; }
  .summary { grid-template-columns: repeat(2, 1fr); }
  .mindmap-viewport { padding: .5rem; }
  .module-grid { grid-template-columns: 1fr; }
  .module-grid > .hierarchy-branch { padding-left: .8rem; }
  .module-grid > .hierarchy-branch::before { display: block; left: 0; top: var(--anchor); width: .8rem; height: 0; border-top: var(--rail) solid var(--line); border-left: 0; }
  .module-grid { position: relative; padding-left: .35rem; }
  .module-grid::after { content: ""; position: absolute; left: .35rem; top: var(--anchor); bottom: var(--anchor); border-left: var(--rail) solid var(--line); }
  .branch-children { margin-left: .75rem; padding-left: .55rem; }
  .branch-children > .hierarchy-branch::before { left: -.55rem; width: .55rem; }
  .hierarchy-card { width: 100%; min-height: 0; }
}
@media (pointer: coarse) {
  .cic-dashboard button, .filters button, .launches a, .repo-link, .hierarchy-launch { min-height: var(--control-min-h); }
}
@media (prefers-reduced-transparency: reduce) {
  .site-header, .cic-dashboard, .toolbar, .detail-panel, .task-manager-panel { backdrop-filter: none; }
  .site-header { background: #002eac; }
  .cic-dashboard, .hierarchy-card, .detail-panel, .task-manager-panel { background: var(--of-paper); }
}

/* =====================================================================
   Canonical shell STRUCTURE: drawers, tab rail, page offsets, preferences
   and architecture views. The taskbar's LOOK is not here: it is
   shell-bar-skin.css (role classes .shell-bar / .shell-bar__slot /
   .shell-bar__end) driven by the --bar-* tokens in shell-tokens.css.
   This block consumes those tokens plus the semantic surface tokens and
   defines no palette and no theme block: light/dark follow the tokens.
   ===================================================================== */
.shell-compat-trigger { position: fixed; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); pointer-events: none; }

/* Drawers hang from the bar (JSLC model): left = navigation (modal, scrim),
   right = context and preferences (non-modal, page stays usable). */
body.drawer-locked { overflow: hidden; }
#scrim { position: fixed; inset: 0; z-index: 104; background: var(--overlay-scrim); backdrop-filter: blur(3px); }
#scrim[hidden] { display: none; }
.drawer {
  position: fixed;
  z-index: 110;
  top: var(--bar-height, var(--shell-bar-height, 2.5rem));
  bottom: 0;
  width: min(23rem, calc(100% - 2.6rem)); /* 100% of the viewport minus its scrollbar; 100vw would overflow */
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--surface-overlay);
  color: var(--ink);
  box-shadow: var(--shadow-drawer);
  backdrop-filter: blur(15px);
  animation: drawer-slide .16s ease-out;
}
.drawer[hidden] { display: none; }
.drawer-left { left: 0; border-left: 0; --drawer-slide: -1rem; }
/* A right drawer stops ABOVE the module's event rail rather than covering its
   right end. Zero wherever no rail publishes a reserve, so this is inert in
   every other module. Measured 2026-09-19 with Lenses open: 820x1180 hid the
   `Weather` category outright (categories do not scroll), 1440x900 hid two
   event cards. Specificity (0,1,0) matching `.drawer`, and later in the file,
   so it wins without `!important`. */
.drawer-right { right: var(--tab-width, 1.45rem); border-right: 0; --drawer-slide: 1rem; bottom: var(--ow-event-rail-reserve, 0px); }
body.rail-rolled-up .drawer-right { right: 0; }
.drawer > header {
  display: flex;
  flex-direction: row; /* the legacy page rule turns every <header> into a column below 700px */
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  min-height: var(--control-min-h);
  margin: 0;
  padding: .55rem .65rem;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: var(--surface-overlay);
}
.drawer > header h2 { margin: 0; color: var(--accent); font-size: .95rem; letter-spacing: .05em; text-transform: uppercase; }
.drawer .close {
  flex: 0 0 auto;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--line);
  border-radius: .2rem;
  background: var(--control-surface);
  color: var(--ink);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}
.drawer .close:hover, .drawer .close:focus-visible { border-color: var(--accent); color: var(--accent); outline: none; }
.drawer-content { overflow: auto; display: grid; align-content: start; gap: .6rem; padding: .65rem; }
.drawer-content section:not(.nav-module) { padding: .55rem; border: 1px solid var(--line); background: var(--surface-subtle); }
.drawer-content h2, .drawer-content h3, .drawer-content h4 { margin: 0 0 .35rem; color: var(--ink); font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; }
.drawer-content .context-module h3 { font-size: .9rem; letter-spacing: -.01em; text-transform: none; }
.drawer-content p, .drawer-content small { margin: .2rem 0; color: var(--muted); font-size: .62rem; line-height: 1.35; }
.drawer-content .eyebrow { margin: 0; font-size: .54rem; }
#context-module-slot[hidden] { display: none; }
#context-module-slot { display: grid; gap: .6rem; }
.context-list { display: grid; gap: .2rem; }
.context-list button, .mechanism-chip, .drawer-link {
  width: 100%;
  padding: .4rem .5rem;
  border: 1px solid transparent;
  border-radius: .2rem;
  background: transparent;
  color: var(--ink);
  text-align: left;
  font-family: inherit;
  font-size: .68rem;
  font-weight: 700;
  line-height: 1.2;
  cursor: pointer;
}
.context-list button:hover, .context-list button.active, .context-list button[aria-current="page"], .mechanism-chip:hover,
.drawer-link:hover { border-color: var(--line); background: var(--accent-subtle); color: var(--accent); }
.drawer-link { border-color: var(--line); background: var(--control-surface); text-transform: uppercase; letter-spacing: .05em; font-size: .62rem; font-weight: 900; }
/* Navigation tree presentation lives in navigation-drawer.css. */

/* Right tab rail (JSLC quick-drawer tabs). The Sidebar toggle rolls it up. */
.right-drawer-tabs {
  position: fixed;
  top: var(--bar-height, var(--shell-bar-height, 2.5rem));
  right: 0;
  z-index: 116;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: var(--tab-width, 1.45rem);
  overflow: hidden;
  opacity: 1;
  transform: translateY(0) scaleY(1);
  transform-origin: top right;
  box-shadow: var(--shadow-drawer);
  transition: opacity .16s ease, transform .2s ease;
}
.right-drawer-tabs.rolled-up { opacity: 0; transform: translateY(-.45rem) scaleY(.92); pointer-events: none; box-shadow: none; }
.drawer-tab {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 6rem;
  margin: 0;
  padding: 0;
  border: 0;
  border-bottom: var(--bar-control-divider-strong, 1px solid var(--line));
  background: var(--bar-bg-solid, var(--accent));
  color: var(--bar-fg, var(--field-surface));
  cursor: pointer;
  font-family: var(--bar-font-family, inherit);
  font-size: .6rem;
  font-weight: var(--bar-font-weight, 400);
  line-height: 1.05;
  letter-spacing: var(--bar-letter-spacing, .055em);
  text-transform: var(--bar-text-transform, uppercase);
}
.drawer-tab-label { display: block; white-space: nowrap; transform: rotate(90deg); pointer-events: none; }
.drawer-tab:hover, .drawer-tab:focus-visible { background: var(--bar-control-bg-hover, var(--accent-subtle)); outline: none; }
.drawer-tab[aria-expanded="true"] { background: var(--bar-control-bg-active, var(--accent-subtle)); }

/* THE RAIL'S TWO PAGES (owner 2026-09-18; context-shell.js renderRailInto).
 * `More` and the page label are the rail's first two children and exist only
 * when the active context contributes slots. The rail's width NEVER depends on
 * the page - a map must not jump sideways because a list changed. On a coarse
 * pointer the whole rail is 44px on BOTH pages, reserved in layout through
 * `--tab-width` like every other width of it, never an invisible hitbox. */
@media (pointer: coarse) {
  :root { --tab-width: 2.75rem; }
  .drawer-tab { font-size: .68rem; }
}
.right-drawer-tabs { max-height: calc(100dvh - var(--bar-height, var(--shell-bar-height, 2.5rem))); overflow-x: hidden; overflow-y: auto; scrollbar-width: none; }
/* A SHORT PHONE RUNS OUT OF RAIL. The tabs are 6rem tall, so seven of them need
 * ~724px; at 360x640 the rail gets 600px and the last two sit off-screen at rest.
 * It scrolls - `overflow-y: auto` above - but a 23px-wide vertical scroller has no
 * visible affordance, so "scrollable" and "discoverable" are not the same thing.
 * Adding `More` for rail page 2 took page one from six tabs to seven and tipped it
 * over. Shrink the tab at short heights rather than hide a scroll: seven tabs at
 * 4.5rem plus More fit inside 600px, and 4.5rem is still well above the 44px touch
 * floor. Measured at 360x640: needed 724px, available 600px. */
@media (max-height: 44rem) {
  .drawer-tab { min-height: 4.5rem; }
}
.right-drawer-tabs::-webkit-scrollbar { display: none; }
.drawer-tab.rail-more {
  position: sticky; top: 0; z-index: 2;
  min-height: 4rem; flex: 0 0 auto;
  border-bottom: 0;
  font-weight: 700;
  background: color-mix(in srgb, var(--bar-bg-solid, var(--accent)) 82%, black);
}
.drawer-tab.rail-more:hover, .drawer-tab.rail-more:focus-visible { background: color-mix(in srgb, var(--bar-bg-solid, var(--accent)) 66%, black); }
.drawer-tab.rail-more:focus-visible { outline: var(--bar-control-outline, 2px solid var(--bar-fg)); outline-offset: var(--bar-control-outline-offset, -3px); }
.drawer-tab.rail-more .drawer-tab-label::before { content: "\21C4\00A0"; }
.drawer-tab.rail-more.has-open { box-shadow: inset 3px 0 0 var(--bar-warn-fg); }
.rail-page-label {
  position: sticky; top: 4rem; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto; width: 100%; min-height: 5.25rem;
  border-bottom: 2px solid color-mix(in srgb, var(--bar-fg) 55%, transparent);
  background: color-mix(in srgb, var(--bar-bg-solid, var(--accent)) 82%, black);
  color: var(--bar-fg);
  font-family: var(--bar-font-family, inherit);
  font-size: .56rem; line-height: 1.05; letter-spacing: .04em;
  text-transform: var(--bar-text-transform, uppercase);
  user-select: none;
}
@media (pointer: coarse) { .rail-page-label { font-size: .62rem; } }
/* Page 2 is the module's: its tabs take the module-panel ink with a warm inner
 * edge. Colour is the THIRD signal, after the tab words and the page label. */
.right-drawer-tabs[data-rail-page="module"] .rail-slot-tab {
  background: color-mix(in srgb, var(--bar-bg-solid, var(--accent)) 30%, black);
  box-shadow: inset 3px 0 0 var(--bar-warn-fg);
}
.right-drawer-tabs[data-rail-page="module"] .rail-slot-tab:hover,
.right-drawer-tabs[data-rail-page="module"] .rail-slot-tab:focus-visible,
.right-drawer-tabs[data-rail-page="module"] .rail-slot-tab[aria-expanded="true"] {
  background: color-mix(in srgb, var(--bar-bg-solid, var(--accent)) 55%, black);
}
#rail-page-status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* The one module drawer: the borrowed panel fills it, in the drawer's own flow. */
.module-drawer .drawer-content > [data-rail-slot-mounted] { position: static; inset: auto; width: auto; max-width: none; max-height: none; margin: 0; }
/* On a phone a full-height drawer would hide the very thing the borrowed panel
 * adjusts. The module drawer is a bottom SHEET there, capped so the module's
 * page stays visible above it; still non-modal, still closed by x and Escape. */
@media (max-width: 41.99rem) {
  .drawer.module-drawer { top: auto; bottom: var(--ow-event-rail-reserve, 0px);
    max-height: min(55dvh, 26rem); border-bottom: 0; --drawer-slide: 0; }
}

/* Page layout under the bar: the old left aside is gone, content spans the page. */
.site-header { top: var(--bar-height, var(--shell-bar-height, 2.5rem)); margin-left: 0; }
main { margin-left: 0; }
.toolbar { top: calc(var(--bar-height, var(--shell-bar-height, 2.5rem)) + 1.65rem); }

/* Preferences drawer: one select per module slot + reset. */
.preference-grid { display: grid; gap: .55rem; margin-top: .5rem; }
.preference-grid label { display: grid; gap: .2rem; color: var(--muted); font-size: .58rem; font-weight: 900; letter-spacing: .06em; text-transform: uppercase; }
.preference-grid select { width: 100%; padding: .45rem .55rem; border: 1px solid var(--line); border-radius: .2rem; background: var(--field-surface); color: var(--ink); font-family: inherit; font-size: .72rem; }
.preference-actions { display: grid; gap: .35rem; margin-top: .3rem; }
.preference-actions button { min-height: 2rem; padding: .3rem .65rem; border: 1px solid var(--line); border-radius: .2rem; background: var(--control-surface); color: var(--accent); font-family: inherit; font-size: .62rem; font-weight: 900; letter-spacing: .045em; text-transform: uppercase; cursor: pointer; }
.preference-actions button:hover { background: var(--accent); color: var(--field-surface); }
.preference-actions span { color: var(--muted); font-size: .6rem; }

.architecture-svg { display: block; width: 100%; height: auto; margin: .8rem 0; color: var(--accent); }
.architecture-svg .diagram-lines path { fill: none; stroke: currentColor; stroke-width: 2; marker-end: url(#arrow); }
.architecture-svg .diagram-box rect { fill: var(--panel2); stroke: var(--line); stroke-width: 2; }
.architecture-svg .diagram-box text { fill: var(--ink); text-anchor: middle; font-size: 14px; }
.architecture-svg .diagram-box text:first-of-type { font-size: 16px; font-weight: 900; }
.architecture-ascii { display: none; max-width: 100%; min-width: 0; overflow: auto; padding: .7rem; border: 1px solid var(--line); background: var(--panel2); color: var(--ink); font: .65rem/1.5 ui-monospace, monospace; }
.architecture-view { width: 100%; max-width: 64rem; min-width: 0; padding: 1.2rem; border: 1px solid var(--line); background: var(--surface-subtle); }
.architecture-view dl, .architecture-view dl div, .architecture-view dd { min-width: 0; }
.architecture-view dl div { display: grid; grid-template-columns: 8rem 1fr; gap: .7rem; padding: .45rem 0; border-top: 1px solid var(--line); }
.architecture-view dt { font-weight: 900; } .architecture-view dd { margin: 0; }

@media (max-width: 800px) {
  .drawer { width: calc(100% - var(--tab-width, 1.45rem)); }
  .drawer-left { width: 100%; }
  .architecture-svg { display: none; }
  .architecture-ascii { display: block; }
}
@keyframes drawer-slide { from { opacity: 0; transform: translateX(var(--drawer-slide, 1rem)); } }
@media (prefers-reduced-motion: reduce) {
  .drawer, .right-drawer-tabs { animation: none; transition: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .drawer, #scrim { backdrop-filter: none; }
}

/* ---------- admin console: navigation detail, key matrix, identity splash ----
   Tokens only. tools/test-shell.js rejects hex/rgb/hsl literals in the shared
   modules, and this file is one of them. ------------------------------------ */
.nav-keys { margin: .45rem 0 .2rem; padding: .45rem .55rem; border: 1px dashed var(--line); }
.nav-keys .eyebrow { margin: 0 0 .35rem; }
.key-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .18rem; }
.key-row label { display: flex; align-items: center; gap: .4rem; cursor: pointer; }
/* The drawer stretches inputs to fill their row, which turns a checkbox into a
   371px-wide hit area with the glyph stranded at its right edge and the text
   pushed off. Measured, not guessed. Checkboxes opt out. */
.key-row input[type="checkbox"] { flex: 0 0 auto; width: auto; min-width: 0; margin: 0; }
.key-row small { opacity: .7; text-transform: uppercase; letter-spacing: .05em; font-size: .68rem; }
/* Read-only form of a key when nobody is signed in: the word, not a colour. */
.key-row .key-state { min-width: 2.1rem; font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; opacity: .8; }
.key-row.off > span:not(.key-state) { opacity: .55; text-decoration: line-through; }

.admin-matrix { width: 100%; border-collapse: collapse; font-size: .8rem; }
.admin-matrix th, .admin-matrix td { border: 1px solid var(--line); padding: .3rem .38rem; text-align: left; vertical-align: top; }
.admin-matrix thead th { text-transform: uppercase; letter-spacing: .05em; font-size: .7rem; }
.admin-cell strong { display: block; }
.admin-cell small { display: block; opacity: .78; overflow-wrap: anywhere; }
.admin-cell.absent { opacity: .72; }
#admin-viewer-level button[disabled] { opacity: .45; cursor: not-allowed; }
.view-gate-note { font-size: .74rem; opacity: .85; border-left: 2px solid var(--line); padding-left: .5rem; margin: .5rem 0; }

/* ---------- login splash ------------------------------------------------------
   PORTED from the Mainframe sign-in popup on the live site (#welcome-login /
   #welcome-entry-paths), which the owner named. Same structure, same class
   names, same options. The only changes are the ones asked for: every colour is
   a shell token instead of a literal (the live rules hard-code #a12828 for the
   status line and #fff on the guest button), and the contrast work is kept.

   The splash sits at the BOTTOM and never blocks: no scrim, no body lock, the
   page keeps its own scroll, and "Continue as guest" is the first control, in
   the same place the live page puts #bypass-login. Body padding keeps it off
   the last rows. */
/* The identity popup is the SAME CONTAINER as the Mainframe's #player-drawer:
   `drawer drawer-right`, so it inherits `width: min(23rem, ...)` and the
   `--tab-width` right offset from the drawer rules above. It was a full-width
   bottom splash, which made every faithful element render as a 1280px band -
   the markup was right and the container made it a slab. Only stacking
   overrides live here; the geometry is the shared drawer's. */
.identity-drawer .drawer-content { display: grid; gap: .5rem; align-content: start; overflow-y: auto; }
/* One field per row: the two-up grid is a settings-page layout and is wrong in a
   368px column. */
.identity-drawer .ui-field-grid { grid-template-columns: 1fr; }
.identity-drawer .social-login { flex-wrap: wrap; }
.identity-drawer .social-login button { flex: 1 1 8rem; justify-content: center; }
.identity-drawer .account-actions { flex-wrap: wrap; }
.identity-drawer .account-actions button { flex: 1 1 auto; }
.identity-drawer .guest-actions { flex-wrap: wrap; }
.identity-drawer .guest-actions button { flex: 1 1 auto; }
.identity-drawer .credential-form input { width: 100%; }

.welcome-entry-paths { display: flex; flex-direction: column; gap: 0; margin-top: .4rem; }
.auth-entry-card {
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--of-primary) 48%, var(--of-rule));
  border-radius: .25rem;
  background: transparent;
}
.guest-entry { display: grid; gap: .35rem; padding: .5rem .6rem; }
.guest-actions { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.guest-actions button { font: inherit; padding: .4rem .7rem; border: 1px solid var(--line); background: var(--control-surface); color: var(--ink); cursor: pointer; }
/* Live rule, with #fff replaced by the on-chrome foreground token. */
.guest-actions .guest-continue { min-height: var(--control-min-h); background: var(--of-primary); border-color: var(--of-primary); color: var(--bar-fg); font-weight: 900; }
.guest-actions button[disabled] { opacity: .5; cursor: not-allowed; }
.handle-editor { display: grid; gap: .2rem; }
/* `display: grid` beats the `hidden` attribute; without this the editor the
   live page keeps collapsed is always open. */
.handle-editor[hidden] { display: none; }
.handle-editor input { font: inherit; padding: .3rem .45rem; border: 1px solid var(--line); background: var(--field-surface); color: var(--ink); }

.identity-card { display: grid; gap: .55rem; margin: 0; padding: 0; border: 0; background: transparent; }
.identity-card > summary {
  min-height: var(--control-min-h);
  display: flex;
  align-items: center;
  padding: .4rem .6rem;
  border: 0;
  border-top: 1px solid var(--of-rule);
  border-radius: 0;
  color: var(--accent);
  cursor: pointer;
  font-size: .68rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .05em;
  list-style-position: inside;
}
.identity-card > .credential-form { padding: .6rem; border: 0; border-top: 1px solid var(--of-rule); }
.credential-form { display: grid; gap: var(--ui-gap); }
.credential-form label { display: grid; gap: .25rem; color: var(--ink); font-size: .68rem; font-weight: 900; text-transform: uppercase; }
.credential-form input { min-width: 0; height: var(--ui-control-height); font: inherit; padding: .3rem .5rem; border: 1px solid var(--line); background: var(--field-surface); color: var(--ink); }
.credential-form input:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.credential-form input[disabled] { opacity: .55; }

.login-brand { grid-column: 1 / -1; display: grid; gap: .2rem; padding-bottom: .35rem; border-bottom: 1px solid var(--of-rule); }
.login-brand strong { display: grid; justify-items: start; direction: ltr; unicode-bidi: isolate; text-align: left; font-size: 1rem; color: var(--ink); }
.login-brand small { color: var(--muted); font-size: .63rem; font-weight: 750; letter-spacing: .08em; }

.ui-field-grid { display: grid; gap: var(--ui-gap); grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.login-field { display: grid; gap: .22rem; }
.login-field label { color: var(--muted); font-size: .66rem; font-weight: 850; text-transform: uppercase; }
.login-field input { width: 100%; min-height: var(--control-min-h); }
.ui-validation { color: var(--muted); font-size: .66rem; }

.account-actions { display: flex; flex-wrap: wrap; gap: .4rem; }
.account-actions button { font: inherit; padding: .4rem .7rem; border: 1px solid var(--line); background: var(--control-surface); color: var(--ink); cursor: pointer; }
.account-actions .primary-button { background: var(--of-primary); border-color: var(--of-primary); color: var(--bar-fg); font-weight: 900; }
.account-actions button[disabled] { opacity: .5; cursor: not-allowed; }

/* Live rule ports #a12828 -> --of-bad. The success tone was already a token. */
.login-status { grid-column: 1 / -1; min-height: 1.1rem; margin: 0; color: var(--of-bad); font-size: .72rem; line-height: 1.4; }
.login-status.neutral { color: var(--ink); }
.login-status.success { color: var(--of-good); }
.auth-callback-status { margin: 0; color: var(--muted); font-size: .7rem; }

.platform-login-block { grid-column: 1 / -1; display: grid; gap: .4rem; padding-top: var(--ui-section-space); border-top: 1px solid var(--of-rule); }
.platform-login-label { color: var(--muted); font-size: .66rem; font-weight: 900; text-transform: uppercase; letter-spacing: .05em; }
.social-login { display: flex; flex-wrap: wrap; gap: .35rem; }
.social-login button { display: inline-flex; align-items: center; gap: .3rem; font: inherit; padding: .35rem .6rem; border: 1px solid var(--line); background: var(--control-surface); color: var(--ink); cursor: pointer; }
.social-login button[disabled] { opacity: .55; cursor: not-allowed; }
.provider-soon { font-size: .6rem; font-weight: 900; letter-spacing: .08em; color: var(--muted); }
.provider-permission-note { margin: 0; color: var(--muted); font-size: .68rem; }

/* Signed in: the credential fields and the account-creation options collapse,
   the Sign out action and the status line stay. */
.credential-form.is-admin :is(.ui-field-grid, .login-brand, .platform-login-block) { display: none; }
.credential-form.is-admin .account-actions button:not(.primary-button) { display: none; }
/* Removed: `#identity-button.is-admin { font-weight: 700 }` styled a BAR control
 * by id and forked --bar-font-weight, so the signed-in control rendered at 700
 * beside neighbours at 400. The skin owns bar typography; a page stylesheet
 * reaching in by id is the bespoke convention this pass exists to remove. */

.view-gate-note {
  margin: .45rem 0 0;
  padding-left: .55rem;
  border-left: 2px solid var(--accent);
  color: var(--ink);
  font-size: .74rem;
  line-height: 1.4;
}


/* ---------- the navbar -------------------------------------------------------
   Owner, 2026-09-02, in two steps.

   FIRST: "that left side sidebar should be navbar. when sidebar/navbar are
   deployed they should float over main window contents (unless no module is
   active)." The navigation drawer stopped being a 23rem MODAL panel - it had
   appeared with a scrim and locked page scroll - and became non-modal, so it
   floats over the content instead of blocking it.

   THEN: "the navigation button on the left side of screen should be in the #1
   spot on the right side, no buttons on left side." The narrow LEFT rail this
   file briefly carried is gone - removed, not hidden - and the navigation toggle
   is the first tab of the one right-hand rail. The left EDGE carries no chrome.
   The PANEL still slides from the left, because that is a panel edge and not a
   button, and Request B's float behaviour is unretracted. */
.drawer-left { left: 0; }

/* FLOAT is the default and needs no rule: .drawer is position:fixed, so with the
   drawer non-modal the page simply carries on underneath.
   DISPLACE is the exception the owner named - no module surface is mounted, so
   there is nothing worth floating over and the content moves aside instead. */
body.nav-open:not(.module-active) main,
body.nav-open:not(.module-active) > .site-header {
  margin-left: min(23rem, calc(100% - 2.6rem));
  transition: margin-left .16s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  body.nav-open:not(.module-active) main,
  body.nav-open:not(.module-active) > .site-header { transition: none; }
}
/* Below the narrow breakpoint the panel is nearly full width, so displacing
   would push the content off-screen. Float at every width there. */
@media (width <= 50rem) {
  body.nav-open:not(.module-active) main,
  body.nav-open:not(.module-active) > .site-header { margin-left: 0; }
}

/* The pill alternative to the key checkbox (context-shell.js KEY_CONTROL).
   Same state and the same per-module scope; a 28px target instead of 13px, and
   the state is a word, so it is never carried by colour alone. */
.key-row-pill { list-style: none; }
.key-pill {
  display: flex;
  align-items: center;
  gap: .45rem;
  width: 100%;
  padding: .18rem .3rem;
  border: 1px solid transparent;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.key-pill:hover, .key-pill:focus-visible { border-color: var(--line); background: var(--accent-subtle); outline: none; }
.key-pill-state {
  flex: 0 0 auto;
  min-width: 2.4rem;
  padding: .1rem .3rem;
  border: 1px solid var(--line);
  text-align: center;
  font-size: .66rem;
  text-transform: uppercase;
  letter-spacing: .05em;
}
.key-pill[aria-checked="true"] .key-pill-state { background: var(--accent-subtle); border-color: var(--accent); }
.key-pill[aria-checked="false"] > span:not(.key-pill-state) { opacity: .6; text-decoration: line-through; }

/* ---------- Config rocker, key matrix and version grid -----------------------
   Tokens only; tools/test-shell.js rejects colour literals in this file. */
.nav-config-switch { margin-left: auto; margin-right: .5rem; }
.nav-config-switch[hidden] { display: none; }
.rocker {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .2rem .4rem;
  border: 1px solid var(--line);
  background: var(--control-surface);
  color: var(--ink);
  font: inherit;
  font-size: .68rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .05em;
  cursor: pointer;
}
.rocker:hover, .rocker:focus-visible { background: var(--accent-subtle); outline: none; }
.rocker-track {
  position: relative;
  display: inline-block;
  width: 2rem;
  height: 1rem;
  border: 1px solid var(--line);
  background: var(--field-surface);
}
.rocker-thumb {
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
  background: var(--line);
  transition: transform .14s ease-out, background .14s ease-out;
}
.rocker[aria-checked="true"] .rocker-thumb { transform: translateX(100%); background: var(--accent); }
@media (prefers-reduced-motion: reduce) { .rocker-thumb { transition: none; } }

.key-group { margin: .5rem 0 .2rem; font-size: .66rem; font-weight: 900; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.key-rule { margin: .6rem 0 0; border: 0; border-top: 1px solid var(--line); }
.key-head, .key-row { display: grid; grid-template-columns: 1fr repeat(3, 2.6rem); align-items: center; gap: .2rem; }
.key-head { padding: .1rem .2rem; font-size: .6rem; font-weight: 900; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.key-head span:not(:first-child), .key-row .key-box { justify-self: center; }
.key-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .1rem; }
.key-row { padding: .1rem .2rem; }
.key-row:hover { background: var(--accent-subtle); }
.key-name { display: flex; flex-direction: column; line-height: 1.15; }
.key-name small { opacity: .7; font-size: .62rem; text-transform: uppercase; letter-spacing: .05em; }
.key-box { display: inline-flex; align-items: center; justify-content: center; margin: 0; cursor: pointer; }
.key-box input[type="checkbox"] { width: auto; min-width: 0; margin: 0; }

.admin-matrix thead th small { display: block; font-weight: 400; opacity: .75; letter-spacing: 0; text-transform: none; }
.version-app { font-weight: 700; }
.version-select { font: inherit; font-size: .72rem; max-width: 100%; margin-top: .15rem; padding: .12rem .2rem; border: 1px solid var(--line); background: var(--field-surface); color: var(--ink); }
.version-single { display: block; margin-top: .15rem; opacity: .75; }
.version-cell { white-space: nowrap; }
.version-box { display: inline-flex; flex-direction: column; align-items: center; gap: .05rem; margin: 0 .12rem; cursor: pointer; }
.version-box input[type="checkbox"] { width: auto; min-width: 0; margin: 0; }
.version-box small { font-size: .58rem; text-transform: uppercase; letter-spacing: .03em; opacity: .8; }
.version-box.absent { opacity: .4; cursor: default; }

.account-panel { display: grid; gap: .25rem; padding: .5rem .6rem; border-bottom: 1px solid var(--line); }
.account-panel p { margin: 0; }
.account-session-actions { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.account-session-actions [hidden] { display: none; }
.primary-link { display: inline-flex; align-items: center; min-height: 2.2rem; padding: .35rem .7rem; border: 1px solid var(--of-primary); background: var(--of-primary); color: var(--bar-fg); font: inherit; font-weight: 900; cursor: pointer; }
.secondary-button { display: inline-flex; align-items: center; min-height: 2.2rem; padding: .35rem .7rem; border: 1px solid var(--line); background: var(--control-surface); color: var(--ink); font: inherit; cursor: pointer; }
.secondary-button:hover, .secondary-button:focus-visible { background: var(--accent-subtle); }
.secondary-button[disabled] { opacity: .5; cursor: not-allowed; }
.account-state { padding: .2rem .4rem; border: 1px solid var(--of-rule); color: var(--muted); font-size: .66rem; font-weight: 900; text-transform: uppercase; }

/* ---------- navigation tree: modules disclose their nodes --------------------
   Tokens only. The module name IS the disclosure button, so its own node is
   listed as the first entry inside the box and nothing becomes unreachable. */

.slot-locked { display: block; margin-top: .1rem; color: var(--muted); font-size: .62rem; text-transform: none; letter-spacing: normal; font-weight: 400; }
.slot-refusal { grid-column: 1 / -1; margin: .2rem 0 0; padding-left: .5rem; border-left: 2px solid var(--accent); color: var(--ink); font-size: .7rem; }
.slot-refusal[hidden] { display: none; }

/* ---------- login drawer density ---------------------------------------------
   Two owner complaints, both measured: the drawer rendered 858px tall inside a
   368px column, and its primary buttons occupied 18-19% of the row with the rest
   empty. Controls now fill their row and the vertical rhythm is tightened to the
   content. Nothing is restructured - this is spacing and width only. */
.identity-drawer .drawer-content { gap: .35rem; padding-block: .4rem; }
.identity-drawer .guest-entry { gap: .3rem; padding: .4rem .5rem; }
.identity-drawer .identity-card { gap: .3rem; }
.identity-drawer .identity-card > .credential-form { padding: .45rem .5rem; gap: .3rem; }
.identity-drawer .account-panel { gap: .2rem; padding: .4rem .5rem; }
.identity-drawer .login-brand { padding-bottom: .2rem; }
.identity-drawer .platform-login-block { gap: .25rem; padding-top: .35rem; }
.identity-drawer .ui-field-grid { gap: .3rem; }
/* Fill the width. A button using a fifth of the row with four fifths empty is
   the horizontal waste that was called out. */
.identity-drawer .account-session-actions { display: grid; grid-template-columns: 1fr; gap: .3rem; }
.identity-drawer .account-session-actions button { width: 100%; justify-content: center; }
.identity-drawer .guest-actions { display: grid; grid-template-columns: 1fr 1fr; gap: .3rem; }
.identity-drawer .guest-actions button { width: 100%; justify-content: center; }
.identity-drawer .account-actions { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: .3rem; }
.identity-drawer .account-actions button { width: 100%; justify-content: center; padding: .36rem .2rem; }
.identity-drawer .social-login { display: grid; grid-template-columns: 1fr 1fr; gap: .3rem; }
.identity-drawer .social-login button { flex: 0 0 auto; width: 100%; justify-content: center; }
.identity-drawer .login-status:empty { display: none; }

/* The <=700px block turns .site-header position:relative, but the sticky
 * offset `top: var(--bar-height)` set later still applied, so a relative
 * element was pushed down by the bar height it no longer needed to clear:
 * a 40px dead strip between the taskbar and the banner at 390px, measured
 * with elementFromPoint returning BODY. This must come after that rule to
 * win on equal specificity. */
@media (max-width: 700px) {
  .site-header { top: 0; }
}

/* RESERVE THE RAIL. The right tab rail is fixed at right:0 and 1.45rem wide, and
 * nothing on the content side accounted for it, so the page ran underneath it -
 * measured at 390px as a 7px overlap of the last content column on harness,
 * workflows and mailboxes identically. Appended last so it wins over both `main`
 * padding rules without raising specificity, and expressed as an addition to the
 * existing clamp so the responsive padding is unchanged apart from the reserve. */
main,
/* A page that gives its <main> a class - .wf-main, the harness equivalent -
 * out-specifies the bare element selector, so the reserve was skipped on
 * exactly the newest pages. `main[class]` is (0,1,1) and beats a single class
 * without naming any page, so a page added later is covered by construction. */
main[class] {
  padding-right: calc(clamp(1rem, 3vw, 2.4rem) + var(--tab-width, 1.45rem));
}
body.rail-rolled-up main,
body.rail-rolled-up main[class] {
  /* Rolled up, the rail is not occupying that column, so give the space back. */
  padding-right: clamp(1rem, 3vw, 2.4rem);
}

/* Task Manager predates the shared bar and rail. Keep its fixed panel below the
 * bar and out of the tab column; otherwise its close control is covered and a
 * phone composer accepts input behind the fixed rail. */
.task-manager-panel {
  top: var(--bar-height, var(--shell-bar-height, 2.5rem));
  width: min(620px, calc(100% - var(--tab-width, 1.45rem)));
}
body.rail-rolled-up .task-manager-panel { width: min(620px, 100%); }

/* LOCAL-ONLY SERVICES on a published copy.
   These are real services that simply cannot be reached from this origin — they
   live on the LAN. Rendering them as a disabled-looking label rather than a link
   is the honest form: an <a> that cannot resolve is worse than no <a>, because
   the reader blames the site rather than the network. Deliberately quiet, not
   an error state — nothing is broken. */
.link-local-only,
.hierarchy-launch.is-local-only {
  color: var(--of-ink-soft, var(--muted));
  opacity: .72;
  font-style: italic;
  cursor: help;
  text-decoration: none;
}

/* Navigation stays clear of the right rail at phone and tablet widths. */
#navigation-drawer { width: min(23rem, calc(100% - var(--tab-width, 1.45rem) - env(safe-area-inset-right, 0px) - env(safe-area-inset-left, 0px))); }
