/* ===== P6 Tools Hub — Core Styles ===== */
/* Fonts: set by role through --font-heading / --font-ui / --font-data below */

/* ─── Accent amber ───
   Single source of truth for the accent colour. Every amber in the app resolves
   through these tokens, so the accent is identical to the active nav pill in
   whichever theme is showing. Light mode uses amber-600 (#d97706); dark mode
   uses amber-500 (#f59e0b), which stays legible on the dark surfaces.
   --accent-text is the foreground guaranteed readable on --accent. */
:root {
  /* Font roles. Rules name a role, never a face; a skin restyles the whole
     site by redefining these three. Headings, UI text (body, controls,
     badges, labels) and data (numbers, IDs, codes). */
  --font-heading: 'Playfair Display', Georgia, serif;
  --font-ui: 'IBM Plex Mono', 'Courier New', monospace;
  --font-data: 'IBM Plex Mono', monospace;

  --accent: #d97706;
  --accent-rgb: 217, 119, 6;
  --accent-hover: #b45309;
  --accent-text: #ffffff;

  --primary: var(--accent);
  --bs-primary: var(--accent);
  --bs-primary-rgb: var(--accent-rgb);
}

/* ─── Base ─── */
body {
  font-family: var(--font-ui);
  padding-top: 1rem;
  padding-bottom: 2rem;
  background-color: #f5f6fa;
  color: #1f2937;
  transition: background-color 0.3s ease, color 0.3s ease;
}
h1, h2, h3, h4, h5, h6 { font-family: var(--font-heading); }
.container-main { max-width: 1200px; }
a { transition: color 0.2s ease; }

/* ─── Navbar ─── */
.navbar { box-shadow: 0 2px 8px rgba(0,0,0,0.15); transition: background-color 0.3s ease; }
.navbar-brand {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.4rem;
  letter-spacing: 0.5px;
}
/* ─── Primary navigation (left drawer) ───
   Replaces the eight nav pills that used to run across the top of every page.
   The pills were hand-copied into twelve templates and had begun to wrap onto
   three rows on a laptop; the markup now lives once, in layouts.html.

   Everything here resolves through the theme tokens, which both [data-theme]
   blocks define in full — the literals are fallbacks for the moment before the
   inline theme script has run, not a second palette. */
.nav-drawer-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 0.9rem;
  background: transparent;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 0.5rem;
  color: var(--text, #1f2937);
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  transition: border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}
.nav-drawer-toggle:hover { border-color: var(--accent); color: var(--accent); }
.nav-drawer-toggle:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb),0.15);
}

/* Pinned to the navbar band, left of the brand, so it is in the same place on
   every page. It used to sit where the pills had been, and that container is
   different on each template — a flex row here, a plain block there — so the
   control moved as you navigated.

   The band is dark in BOTH themes (#1f2937 light, #111318 dark), so on it the
   toggle takes its colours from the band rather than from --text, which would
   be near-black on near-black in light mode. */
.navbar .nav-drawer-toggle {
  margin-right: 0.85rem;
  color: rgba(255,255,255,0.85);
  border-color: rgba(255,255,255,0.25);
}
.navbar .nav-drawer-toggle:hover {
  background: rgba(255,255,255,0.08);
  border-color: var(--accent);
  color: var(--accent);
}
.navbar .nav-drawer-toggle:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb),0.25);
}

/* Three bars, drawn rather than fetched. The icon set has no hamburger, and
   two rectangles are not worth another sprite. */
.nav-drawer-bars {
  position: relative;
  flex: none;
  width: 1rem;
  height: 2px;
  background: currentColor;
  border-radius: 1px;
}
.nav-drawer-bars::before,
.nav-drawer-bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: currentColor;
  border-radius: 1px;
}
.nav-drawer-bars::before { top: -5px; }
.nav-drawer-bars::after  { top:  5px; }

.app-nav-drawer {
  width: 17rem;
  background-color: var(--surface, #ffffff);
  color: var(--text, #1f2937);
  border-right: 1px solid var(--border, #e5e7eb);
}
.app-nav-drawer .offcanvas-header { border-bottom: 1px solid var(--border, #e5e7eb); }
.app-nav-drawer .offcanvas-title {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: 0.5px;
}
.app-nav-drawer .offcanvas-body { padding-top: 0.75rem; }

.nav-drawer-group {
  font-family: var(--font-heading);
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-muted, #6b7280);
  margin: 1.25rem 0 0.4rem;
}
.nav-drawer-group:first-child { margin-top: 0; }

.nav-drawer-link {
  display: block;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.15rem;
  border-radius: 0.5rem;
  border-left: 3px solid transparent;
  color: var(--text, #1f2937);
  text-decoration: none;
  font-family: var(--font-ui);
  font-size: 0.82rem;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.nav-drawer-link:hover { background: rgba(var(--accent-rgb),0.1); color: var(--accent); }
.nav-drawer-link.active {
  background: var(--accent);
  border-left-color: var(--accent-hover);
  color: var(--accent-text);
  font-weight: 500;
}
.nav-drawer-link.active:hover { background: var(--accent-hover); color: var(--accent-text); }

/* ─── Report Sections ─── */
.report-section { margin-bottom: 2rem; }
.section-header {
  cursor: pointer;
  user-select: none;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.15rem;
  padding: 0.85rem 1.25rem;
  transition: background-color 0.2s ease;
}
.section-header:hover {
  filter: brightness(0.96);
}
.section-header[aria-expanded="false"] .collapse-chevron {
  transform: rotate(-90deg);
}
.collapse-chevron {
  transition: transform 0.25s ease;
  display: inline-block;
  font-size: 1.2rem;
}

/* ─── Stat Cards ─── */
.stat-card {
  text-align: center;
  padding: 1.25rem 1rem;
  background: #ffffff;
  border-radius: 0.5rem;
  margin-bottom: 0.5rem;
  border: 1px solid #e5e7eb;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
  transition: all 0.25s ease;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.stat-card:hover {
  box-shadow: 0 6px 20px rgba(var(--accent-rgb),0.2);
  transform: translateY(-2px);
  border-color: var(--accent);
}
/* Force stat cards in rows to match height of tallest sibling */
.row.mb-3 {
  align-items: stretch;
}
.row.mb-3 > [class^="col"] {
  display: flex;
  flex-direction: column;
}
.row.mb-3 > [class^="col"] > .stat-card {
  flex: 1;
}
.stat-value {
  font-size: 2rem;
  font-weight: 700;
  font-family: var(--font-data);
  color: var(--accent);
  line-height: 1.2;
}
.stat-value-sm {
  font-size: 1.15rem;
  font-weight: 600;
}
.stat-label {
  font-size: 0.75rem;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: 0.25rem;
  font-weight: 500;
}

/* ─── Activity Status Active Card ─── */
.stat-card.status-active {
  border-left: 4px solid var(--accent);
  background: rgba(var(--accent-rgb), 0.06);
}
[data-theme="dark"] .stat-card.status-active {
  background: rgba(var(--accent-rgb), 0.1);
}

/* ─── Progress Bar ─── */
.progress-bar-custom {
  height: 1.5rem;
  border-radius: 0.25rem;
  overflow: hidden;
}

/* ─── Tables ─── */
.table {
  font-size: 0.875rem;
  border-collapse: separate;
  border-spacing: 0;
}
.table thead th {
  font-family: var(--font-ui);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: #6b7280;
  border-bottom: 2px solid #e5e7eb;
  padding: 0.6rem 0.75rem;
}
.table tbody td {
  padding: 0.5rem 0.75rem;
  vertical-align: middle;
}
.table-striped > tbody > tr:nth-of-type(odd) > * {
  background-color: rgba(0,0,0,0.02);
}
.table-striped > tbody > tr:hover {
  background-color: rgba(var(--accent-rgb),0.04);
}

/* ─── Cards ─── */
.card {
  border: 1px solid #e5e7eb;
  border-radius: 0.5rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
  transition: box-shadow 0.2s ease, border-color 0.2s ease;
}
.card:hover {
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.card-header {
  font-family: var(--font-heading);
  font-weight: 600;
}

/* ─── DCMA Metric Cards ─── */
.dcma-metric-card {
  position: relative;
  border-radius: 0.5rem;
  border: 1px solid #e5e7eb;
  background: #fff;
  transition: all 0.25s ease;
  overflow: visible;
  cursor: pointer;
  text-decoration: none !important;
}
/* Keep card with active popover above neighbors */
.dcma-metric-card:has(.dcma-popover.active) {
  z-index: 10000;
}
/* Prevent card hover transform from creating a new containing block
   for position:fixed children. Without this, the transform on .dcma-metric-card:hover
   makes the fixed-position popover relative to the card, not the viewport. */
.dcma-metric-card:has(.dcma-popover.active):hover {
  transform: none !important;
}

.dcma-metric-card::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  transition: width 0.2s ease, background-color 0.2s ease;
}
/* Left border colors by status */
.dcma-metric-card.status-pass::before { background: #22c55e; }
.dcma-metric-card.status-warning::before { background: var(--accent); }
.dcma-metric-card.status-fail::before { background: #ef4444; }
.dcma-metric-card.status-na::before { background: #9ca3af; }

.dcma-metric-card:hover {
  box-shadow: 0 6px 20px rgba(var(--accent-rgb),0.25);
  transform: translateY(-2px);
  border-color: var(--accent);
  z-index: 10;
}
.dcma-metric-card:hover::before {
  width: 6px;
}
/* Tooltip-style explanation on hover */
.dcma-metric-card .dcma-tooltip {
  display: none;
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: #1f2937;
  color: #fff;
  padding: 0.5rem 0.75rem;
  border-radius: 0.375rem;
  font-size: 0.75rem;
  white-space: nowrap;
  z-index: 9998;
  margin-bottom: 0.5rem;
  font-family: var(--font-ui);
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
}
.dcma-metric-card .dcma-tooltip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #1f2937;
}
.dcma-metric-card:hover .dcma-tooltip {
  display: block;
}

.dcma-metric-card .dcma-metric-id {
  font-family: var(--font-data);
  font-size: 0.65rem;
  color: #9ca3af;
  letter-spacing: 0.05em;
}
.dcma-metric-card .dcma-metric-name {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 0.75rem;
  line-height: 1.3;
}
.dcma-metric-card .dcma-metric-value {
  font-family: var(--font-data);
  font-weight: 600;
  font-size: 0.95rem;
}
/* Status badges */
.badge-dcma-pass { background: #dcfce7; color: #166534; border: 1px solid #bbf7d0; }
.badge-dcma-warning { background: #fef3c7; color: #92400e; border: 1px solid #fde68a; }
.badge-dcma-fail { background: #fee2e2; color: #991b1b; border: 1px solid #fecaca; }
.badge-dcma-na { background: #f3f4f6; color: #6b7280; border: 1px solid #e5e7eb; }

/* ─── DCMA Cog Button ─── */
.dcma-cog-btn {
  position: absolute;
  top: 5px;
  right: 5px;
  z-index: 5;
  background: none;
  border: none;
  font-size: 1rem;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s ease;
  color: var(--accent);
  padding: 3px 4px;
  border-radius: 4px;
  line-height: 1;
}
.dcma-cog-btn:hover {
  opacity: 1 !important;
  background: rgba(var(--accent-rgb), 0.15);
  color: var(--accent-hover);
}
.dcma-metric-card:hover .dcma-cog-btn {
  opacity: 0.6;
}

/* ─── DCMA Modal Backdrop ─── */
.dcma-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.25);
  z-index: 9998;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.dcma-modal-backdrop.active {
  opacity: 1;
  pointer-events: auto;
}

/* Prevent body scroll when modal is open */
body.dcma-modal-open {
  overflow: hidden;
}

/* ─── DCMA Modal ─── */
.dcma-popover {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.95);
  width: 400px;
  max-width: 95vw;
  max-height: 85vh;
  overflow-y: auto;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 0.6rem;
  box-shadow: 0 12px 40px rgba(0,0,0,0.2);
  z-index: 9999;
  font-family: var(--font-ui);
  font-size: 0.85rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.dcma-popover.active {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}
/* ─── DCMA Modal Header ─── */
.dcma-popover-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid #e5e7eb;
  background: #f9fafb;
  border-radius: 0.6rem 0.6rem 0 0;
}
.dcma-popover-header-title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.9rem;
  color: #1f2937;
  margin: 0;
}
.dcma-popover-close-btn {
  background: none;
  border: none;
  font-size: 1.2rem;
  line-height: 1;
  color: #9ca3af;
  cursor: pointer;
  padding: 0 0.2rem;
  transition: color 0.15s ease;
}
.dcma-popover-close-btn:hover {
  color: #ef4444;
}

.dcma-popover-body {
  padding: 0.85rem 0.9rem;
}
.dcma-popover-body label {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #6b7280;
  font-weight: 600;
  margin-bottom: 0.25rem;
}
.dcma-popover-body input {
  width: 100%;
  padding: 0.4rem 0.6rem;
  font-size: 0.9rem;
  border: 1px solid #d1d5db;
  border-radius: 0.3rem;
  background: #f9fafb;
  margin-bottom: 0.5rem;
}
.dcma-popover-body input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb),0.2);
}

/* Styled up/down spinner arrows */
.dcma-popover-body input::-webkit-inner-spin-button,
.dcma-popover-body input::-webkit-outer-spin-button {
  opacity: 0.6;
  height: 22px;
  cursor: pointer;
}

.dcma-popover-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.dcma-popover-apply {
  background: var(--accent);
  color: var(--accent-text);
  border: none;
  padding: 0.35rem 0.9rem;
  border-radius: 0.3rem;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
}
.dcma-popover-apply:hover {
  background: var(--accent-hover);
}
.dcma-popover-reset {
  background: none;
  border: none;
  color: #9ca3af;
  font-size: 0.75rem;
  cursor: pointer;
  text-decoration: underline;
  padding: 0;
}
.dcma-popover-reset:hover {
  color: #6b7280;
}
.dcma-popover-range {
  font-size: 0.72rem;
  color: #9ca3af;
  margin-top: 0.5rem;
  padding-top: 2px;
  line-height: 1.5;
}

/* ─── DCMA Popover Dark Theme ─── */
[data-theme="dark"] .dcma-popover {
  background: var(--surface, #252830);
  border-color: var(--border, #374151);
  color: var(--text, #e4e6eb);
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
[data-theme="dark"] .dcma-popover-body label {
  color: #9ca3af;
}
[data-theme="dark"] .dcma-popover-body input {
  background: #1a1d23;
  border-color: var(--border, #374151);
  color: var(--text, #e4e6eb);
}
[data-theme="dark"] .dcma-popover-reset {
  color: #6b7280;
}
[data-theme="dark"] .dcma-popover-reset:hover {
  color: #9ca3af;
}

[data-theme="dark"] .dcma-modal-backdrop {
  background: rgba(0, 0, 0, 0.35);
}
[data-theme="dark"] .dcma-popover-header {
  background: #2a2d35;
  border-bottom-color: var(--border, #374151);
}
[data-theme="dark"] .dcma-popover-header-title {
  color: var(--text, #e4e6eb);
}
[data-theme="dark"] .dcma-popover-close-btn {
  color: #6b7280;
}
[data-theme="dark"] .dcma-popover-close-btn:hover {
  color: #f87171;
}

/* ─── Alerts ─── */
.flash-message { margin-top: 1rem; }
.alert {
  border-radius: 0.5rem;
  border-left: 4px solid;
}
.alert-info { border-left-color: var(--accent); }
.alert-danger { border-left-color: #ef4444; }
.alert-success { border-left-color: #22c55e; }
.alert-warning { border-left-color: var(--accent); }

/* ─── Buttons ─── */
.btn {
  border-radius: 0.375rem;
  font-weight: 500;
  transition: all 0.2s ease;
  font-family: var(--font-ui);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
}
.btn-sm { font-size: 0.75rem; padding: 0.3rem 0.7rem; }
.btn:hover { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(0,0,0,0.12); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-text); }
/* Bootstrap compiles its button variants with literal hex, so setting
   --bs-primary above does NOT reach .btn-outline-primary — it keeps #0d6efd and
   puts a blue button directly beneath the amber .btn-primary on the same card.
   Redefining the variant's own custom properties leaves Bootstrap's hover,
   active, focus and disabled machinery intact and swaps only the colour, which
   is what the token layer promises: every accent resolves through --accent, and
   the dark theme redefines those tokens, so this follows the theme for free. */
.btn-outline-primary {
  --bs-btn-color: var(--accent);
  --bs-btn-border-color: var(--accent);
  --bs-btn-hover-color: var(--accent-text);
  --bs-btn-hover-bg: var(--accent);
  --bs-btn-hover-border-color: var(--accent);
  --bs-btn-focus-shadow-rgb: var(--accent-rgb);
  --bs-btn-active-color: var(--accent-text);
  --bs-btn-active-bg: var(--accent-hover);
  --bs-btn-active-border-color: var(--accent-hover);
  --bs-btn-disabled-color: var(--accent);
  --bs-btn-disabled-border-color: var(--accent);
}
.btn-success { background: #16a34a; border-color: #16a34a; }
.btn-outline-light:hover { background: rgba(255,255,255,0.15); }
.btn-accent { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.btn-accent:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-text); }

/* ─── WBS Tree ─── */
.wbs-tree-table { width: 100%; }
.wbs-tree-table td { vertical-align: middle; padding: 0.4rem 0.6rem; }
.wbs-row { transition: background-color 0.15s ease; }
.wbs-row:hover { background-color: rgba(var(--accent-rgb),0.05); }
.wbs-code-cell { white-space: nowrap; }
.wbs-toggle { display: inline-block; width: 1.2em; text-align: center; font-size: 0.85rem; color: var(--accent); }
.wbs-code { font-family: var(--font-data); font-size: 0.8rem; font-weight: 600; }
.wbs-name-cell { width: 100%; }
.wbs-name { font-size: 0.85rem; }
.wbs-bar-cell { display: flex; align-items: center; gap: 0.5rem; justify-content: flex-end; white-space: nowrap; }
.wbs-bar-wrapper {
  width: 140px;
  height: 0.65rem;
  background: #e5e7eb;
  border-radius: 0.25rem;
  overflow: hidden;
  flex-shrink: 0;
}
.wbs-bar-fill {
  height: 100%;
  border-radius: 0.25rem;
  background: var(--accent);
  min-width: 0;
  transition: width 0.3s ease;
}
.wbs-count-badge {
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--accent);
  min-width: 2.5rem;
  text-align: right;
}

/* ─── Density Bars ─── */
.density-bar {
  height: 100%;
  border-radius: 0.25rem;
}
.density-bar-fill {
  height: 100%;
  border-radius: 0.25rem;
  transition: width 0.3s ease;
}

/* ─── Density Code Cards ─── */
.density-code-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(var(--accent-rgb),0.18) !important;
}

/* ─── Forms ─── */
.form-control, .form-select {
  border-radius: 0.375rem;
  border: 1px solid #d1d5db;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
  font-family: var(--font-ui);
  font-size: 0.85rem;
}
.form-control:focus, .form-select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb),0.15);
  outline: none;
}
.col-form-label {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #6b7280;
  font-weight: 600;
}

/* ─── Footer/Badges ─── */
.badge {
  font-family: var(--font-ui);
  font-weight: 500;
  letter-spacing: 0.03em;
  font-size: 0.7rem;
}
.text-muted {
  color: #9ca3af !important;
}

/* ─── Collapse All Button ─── */
#collapseAllBtn {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Suppress scroll-anchoring artifacts during Bootstrap collapse animations.
   Prevents the visible scroll-up jump when a section above the viewport
   collapses (reports.html sections, WBS toggles, Collapse All/Expand All). */
.collapse { overflow-anchor: none; }
.collapse.show { overflow-anchor: none; }

/* Root-level scroll-anchoring suppression: collapsing a section above the
   viewport would otherwise make the browser re-anchor to a sibling node
   below it and scroll the page up. This app has no lazy images/ads, so
   disabling anchoring globally is the correct, robust fix. */
html { overflow-anchor: none; }

/* ─── DCMA Detail Page ─── */
.dcma-detail-header {
  border-left: 4px solid;
  padding-left: 1rem;
}
.dcma-detail-header.pass { border-left-color: #22c55e; }
.dcma-detail-header.warning { border-left-color: var(--accent); }
.dcma-detail-header.fail { border-left-color: #ef4444; }
.dcma-detail-header.na { border-left-color: #9ca3af; }

/* ─── Transitions ─── */
* { transition: background-color 0.2s ease, border-color 0.2s ease; }

/* ═══════════════════════════════════════════ */
/*  DARK MODE OVERRIDES                       */
/* ═══════════════════════════════════════════ */
[data-theme="dark"] {
  --accent: #f59e0b;
  --accent-rgb: 245, 158, 11;
  --accent-hover: #d97706;
  --accent-text: #1f2937;

  --bg: #1a1d23;
  --surface: #252830;
  --text: #e4e6eb;
  --text-muted: #9ca3af;
  --border: #374151;
  --navbar-bg: #111318;

  /* Competing-path colours for the narrative fragnet diagrams. The driving
     path uses --primary; these two distinguish the near-critical paths that
     could take over from it. Chosen to stay apart from the amber accent and
     from each other for anyone with red-green colour blindness. */
  --narr-path-2: #38bdf8;
  --narr-path-3: #c084fc;
}
[data-theme="dark"] body { background-color: var(--bg); color: var(--text); }
[data-theme="dark"] .card { background-color: var(--surface); color: var(--text); border-color: var(--border); }
[data-theme="dark"] .card-header:not(.section-header) { background-color: #2a2d35; border-color: var(--border); }
[data-theme="dark"] .section-header { background-color: var(--surface); }
[data-theme="dark"] .stat-card { background: var(--surface); border-color: var(--border); }
[data-theme="dark"] .stat-value { color: var(--accent); }
[data-theme="dark"] .table { color: var(--text); }
[data-theme="dark"] .table thead th { color: var(--text-muted); border-bottom-color: var(--border); }
[data-theme="dark"] .table-striped > tbody > tr:nth-of-type(odd) > * { background-color: rgba(255,255,255,0.03); }
[data-theme="dark"] .table-striped > tbody > tr:hover {   background-color: rgba(var(--accent-rgb),0.06); }
[data-theme="dark"] .text-muted { color: var(--text-muted) !important; }
[data-theme="dark"] .navbar { background-color: var(--navbar-bg) !important; box-shadow: 0 2px 12px rgba(0,0,0,0.4); }
[data-theme="dark"] .btn-outline-secondary { color: var(--text); border-color: var(--border); }
[data-theme="dark"] .section-header:hover { filter: brightness(1.1); }
[data-theme="dark"] .dcma-metric-card { background: var(--surface); border-color: var(--border); }
[data-theme="dark"] .badge-dcma-pass { background: rgba(34,197,94,0.15); color: #4ade80; border-color: rgba(34,197,94,0.3); }
[data-theme="dark"] .badge-dcma-warning { background: rgba(var(--accent-rgb),0.15); color: var(--accent); border-color: rgba(var(--accent-rgb),0.3); }
[data-theme="dark"] .badge-dcma-fail { background: rgba(239,68,68,0.15); color: #f87171; border-color: rgba(239,68,68,0.3); }
[data-theme="dark"] .badge-dcma-na { background: rgba(156,163,175,0.15); color: #9ca3af; border-color: rgba(156,163,175,0.3); }
[data-theme="dark"] .form-control { background: var(--surface); border-color: var(--border); color: var(--text); }
[data-theme="dark"] .form-control:focus { border-color: var(--accent); }
[data-theme="dark"] .alert-info { background: rgba(var(--accent-rgb),0.1); color: #fcd34d; }
[data-theme="dark"] .alert-danger { background: rgba(239,68,68,0.1); color: #fca5a5; }
[data-theme="dark"] .density-bar { background: var(--border); }
[data-theme="dark"] .wbs-node::before,
[data-theme="dark"] .wbs-node::after { background: var(--border); }
[data-theme="dark"] .card-body { background-color: var(--surface); color: var(--text); }
[data-theme="dark"] .bg-light { background-color: var(--surface) !important; }
[data-theme="dark"] .bg-white { background-color: var(--surface) !important; }
[data-theme="dark"] .list-group-item { background-color: var(--surface); color: var(--text); border-color: var(--border); }
[data-theme="dark"] .dropdown-menu { background-color: var(--surface); border-color: var(--border); }
[data-theme="dark"] .dropdown-item { color: var(--text); }
[data-theme="dark"] .dropdown-item:hover { background-color: rgba(var(--accent-rgb),0.1); }
[data-theme="dark"] .page-link { background-color: var(--surface); border-color: var(--border); color: var(--accent); }
[data-theme="dark"] .modal-content { background-color: var(--surface); border-color: var(--border); }
[data-theme="dark"] .popover { background-color: var(--surface); border-color: var(--border); }
[data-theme="dark"] .popover-body { color: var(--text); }
[data-theme="dark"] .breadcrumb { background-color: var(--surface); }
[data-theme="dark"] .input-group-text { background-color: #2a2d35; color: var(--text); border-color: var(--border); }
[data-theme="dark"] select.form-select { background-color: var(--surface); color: var(--text); }
[data-theme="dark"] hr { border-color: var(--border); }
[data-theme="dark"] .border { border-color: var(--border) !important; }
[data-theme="dark"] .border-top { border-top-color: var(--border) !important; }
[data-theme="dark"] .border-bottom { border-bottom-color: var(--border) !important; }
[data-theme="dark"] .close, [data-theme="dark"] .btn-close { filter: invert(1); }
[data-theme="dark"] code { color: var(--accent); background: rgba(var(--accent-rgb),0.1); }
[data-theme="dark"] pre { background-color: #1a1d23; border-color: var(--border); }
[data-theme="dark"] .dcma-metric-card .dcma-tooltip { background: var(--accent); color: var(--accent-text); }
[data-theme="dark"] .dcma-metric-card .dcma-tooltip::after { border-top-color: var(--accent); }

/* ─── Dark Mode: Bootstrap white-removal overrides ─── */
[data-theme="dark"] .card-header { background-color: #2a2d35; border-color: var(--border); }
[data-theme="dark"] .card-footer { background-color: #2a2d35; border-color: var(--border); color: var(--text); }
[data-theme="dark"] .table > :not(caption) > * > * { background-color: transparent; color: var(--text); box-shadow: none; }
[data-theme="dark"] .table > tbody { background-color: transparent; }
[data-theme="dark"] .progress { background-color: var(--border); }
[data-theme="dark"] .form-check-input { background-color: var(--surface); border-color: var(--border); }
[data-theme="dark"] .form-check-input:checked { background-color: var(--primary); border-color: var(--primary); }
[data-theme="dark"] .form-select { background-color: var(--surface); border-color: var(--border); color: var(--text); }
[data-theme="dark"] .form-label { color: var(--text); }
[data-theme="dark"] .navbar-text { color: rgba(255,255,255,0.7); }
[data-theme="dark"] .badge.bg-secondary { background-color: #4b5563 !important; }
[data-theme="dark"] .badge.bg-info { background-color: #0e7490 !important; color: #cffafe; }
[data-theme="dark"] .badge.bg-light { background-color: var(--surface) !important; color: var(--text); }
[data-theme="dark"] .text-bg-light { background-color: var(--surface) !important; color: var(--text) !important; }
[data-theme="dark"] ::selection { background-color: rgba(var(--accent-rgb),0.3); color: var(--text); }
[data-theme="dark"] ::placeholder { color: var(--text-muted); opacity: 1; }

[data-theme="dark"] .wbs-row:hover { background-color: rgba(var(--accent-rgb),0.08); }
[data-theme="dark"] .wbs-bar-wrapper { background-color: var(--border); }
[data-theme="dark"] .wbs-count-badge { color: var(--accent); }
[data-theme="dark"] .wbs-code { color: var(--text); }
[data-theme="dark"] .wbs-name { color: var(--text); }

/* ─── Light Mode Overrides ─── */
[data-theme="light"] {
  --accent: #d97706;
  --accent-rgb: 217, 119, 6;
  --accent-hover: #b45309;
  --accent-text: #ffffff;

  --bg: #f5f6fa;
  --surface: #ffffff;
  --text: #1f2937;
  --text-muted: #6b7280;
  --border: #e5e7eb;
  --navbar-bg: #1f2937;

  /* Competing-path colours, darkened for contrast against a white surface. */
  --narr-path-2: #0284c7;
  --narr-path-3: #9333ea;
}
[data-theme="light"] body { background-color: var(--bg); color: var(--text); }
/* The band is dark in both themes; without this the light theme left it
   unpainted, white navbar-dark text on a near-white page. */
[data-theme="light"] .navbar { background-color: var(--navbar-bg) !important; }
[data-theme="light"] .card { background-color: var(--surface); color: var(--text); border-color: var(--border); }
[data-theme="light"] .card-header { background-color: #f9fafb; border-color: var(--border); }
[data-theme="light"] .stat-card { background: var(--surface); border-color: var(--border); }

/* ═══════════════════════════════════════════ */
/*  DIFF RESULTS PAGE                         */
/* ═══════════════════════════════════════════ */
/*
 * The diff is 19 columns of dense numbers. It used to render as one enormous
 * page-height table inside .table-responsive, which put the horizontal
 * scrollbar thousands of rows below the fold and scrolled the header away on
 * the first flick of the wheel. Instead the table now scrolls INSIDE a
 * viewport-height box: header rows and the activity id stay pinned, and both
 * scrollbars stay within reach.
 *
 * Rules are neutral grey rather than a themed colour so the same two tokens
 * read correctly on the light and the dark surface.
 */
:root {
  --diff-rule: rgba(128, 128, 128, 0.20);
  --diff-rule-strong: rgba(128, 128, 128, 0.45);
  --diff-head-h: 1.9rem;
}

/* The results table needs more room than the 1200px reading measure. */
.container.diff-results-page { max-width: min(1760px, 97vw); }

/* Basis/comparator strip — one line each, so the table starts higher */
.diff-side { display: flex; align-items: baseline; gap: 0.4rem; min-width: 0; flex-wrap: nowrap; }
.diff-side > strong,
.diff-side > .text-muted { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.diff-side > strong { flex: 0 1 auto; }
.diff-side > .text-muted { flex: 1 1 auto; }
.diff-side-tag {
  flex: none;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1;
  padding: 0.25rem 0.4rem;
  border-radius: 0.25rem;
  background: rgba(var(--accent-rgb), 0.15);
  color: var(--accent);
}

/* Summary cards: the same cards, sized for a header strip rather than a hero */
.stat-card-compact { padding: 0.6rem 0.75rem; margin-bottom: 0; }
.stat-card-compact .stat-value { font-size: 1.5rem; }
.stat-card-compact .stat-label { font-size: 0.68rem; }
.diff-modified-card { border-left: 4px solid #3b82f6; }
.diff-modified-value { color: #3b82f6 !important; }
.diff-shift-card { border-left: 4px solid #f59e0b; }
.diff-shift-value { color: #d97706 !important; }
[data-theme="dark"] .diff-shift-value { color: #fbbf24 !important; }

/* Toolbar above the table */
.diff-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}
.diff-toolbar .diff-search { width: 16rem; max-width: 100%; }
.diff-toolbar .diff-count { margin-left: auto; white-space: nowrap; }

/* ─── The scrolling table box ─── */
.diff-table-wrap {
  max-height: calc(100vh - 15rem);
  min-height: 18rem;
  overflow: auto;
  border: 1px solid var(--border, #374151);
  border-radius: 0.5rem;
  background: var(--surface, #ffffff);
}

.diff-table {
  border-collapse: separate;   /* keeps sticky cells from losing their borders */
  border-spacing: 0;
  font-size: 0.8rem;
  width: max-content;          /* columns take their declared width, never squeeze */
  min-width: 100%;
}
.diff-table th,
.diff-table td {
  white-space: nowrap;
  padding: 0.25rem 0.5rem;
  border-bottom: 1px solid var(--diff-rule);
  vertical-align: middle;
}
/* Bootstrap paints every cell with an opaque --bs-table-bg, which in light mode
   hid the added/deleted row tints entirely. Clear it and let the row show. */
.diff-table > :not(caption) > * > * {
  background-color: transparent;
  box-shadow: none;
}

/* Subtle line between every column, a firmer one between field groups */
.diff-table th + th,
.diff-table td + td { border-left: 1px solid var(--diff-rule); }
.diff-table th.grp,
.diff-table td.grp { border-left: 1px solid var(--diff-rule-strong); }

/* ─── Sticky header: group row, then A/B/Δ row ─── */
.diff-table thead th {
  position: sticky;
  z-index: 3;
  /* !important: the dark-mode blanket rule for .table cells would otherwise
     make the pinned header transparent and let rows scroll through it. */
  background-color: var(--surface, #ffffff) !important;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}
.diff-table thead .diff-group-row th {
  top: 0;
  height: var(--diff-head-h);
  text-align: center;
  font-family: var(--font-heading);
  font-size: 0.85rem;
  color: var(--text, #1f2937);
  border-bottom: 1px solid var(--diff-rule-strong);
}
.diff-table thead .diff-sub-row th {
  top: var(--diff-head-h);
  color: var(--text-muted, #6b7280);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 2px solid var(--diff-rule-strong);
}
.diff-table thead .diff-sub-row th.col-date,
.diff-table thead .diff-sub-row th.col-num,
.diff-table thead .diff-sub-row th.col-delta { text-align: right; }

/* ─── Column widths: set so no header ever wraps ─── */
.diff-table .col-code   { min-width: 8.5rem; font-weight: 600; }
.diff-table .col-name   { min-width: 16rem; max-width: 26rem; overflow: hidden; text-overflow: ellipsis; }
.diff-table .col-wbs    { min-width: 9rem;  max-width: 13rem; overflow: hidden; text-overflow: ellipsis; }
.diff-table .col-change { min-width: 6.5rem; }
.diff-table .col-date   { min-width: 5.75rem; text-align: right; }
.diff-table .col-num    { min-width: 4.25rem; text-align: right; }
.diff-table .col-delta  { min-width: 4.25rem; text-align: right; }
.diff-table td.col-date,
.diff-table td.col-num,
.diff-table td.col-delta { font-variant-numeric: tabular-nums; }

/* Activity id pinned to the left edge so a row keeps its identity when the
   numbers scroll sideways. Header corner sits above it. */
.diff-table .col-code { position: sticky; left: 0; z-index: 2; }
.diff-table thead .col-code { z-index: 4; }
.diff-table tbody td.col-code {
  background-color: var(--surface, #ffffff) !important;
  border-right: 1px solid var(--diff-rule-strong);
}

/* The name keeps its ellipsis while the renamed marker stays visible beside it.
   The cells stay table-cells — display:flex here would drop them out of the
   table layout and unalign every column to their right. */
.diff-table td.col-name,
.diff-table td.col-wbs { overflow: hidden; }
.diff-table td.col-name > span:first-child,
.diff-table td.col-wbs > span:first-child {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}
/* Leave room for the marker when there is one */
.diff-table td.has-flag > span:first-child { max-width: calc(100% - 5.5rem); }

/* Change badge and the renamed/moved markers */
.diff-table .diff-badge { font-size: 0.65rem; font-weight: 600; letter-spacing: 0.03em; }
.diff-flag {
  margin-left: 0.35rem;
  padding: 0.05rem 0.3rem;
  border-radius: 0.2rem;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted, #6b7280);
  border: 1px solid var(--diff-rule-strong);
}

.diff-table tbody tr:hover td { background-color: rgba(var(--accent-rgb), 0.07); }
.diff-table tbody tr:hover td.col-code {
  background-color: rgba(var(--accent-rgb), 0.07) !important;
}

/* ═══════════════════════════════════════════ */
/*  DIFF TABLE ROW COLORS                     */
/* ═══════════════════════════════════════════ */

/* ADDED rows: green tint */
.diff-table tr.ADDED {
  background-color: rgba(34, 197, 94, 0.08) !important;
}
.diff-table tr.ADDED:hover {
  background-color: rgba(34, 197, 94, 0.15) !important;
}

/* DELETED rows: red tint */
.diff-table tr.DELETED {
  background-color: rgba(239, 68, 68, 0.08) !important;
}
.diff-table tr.DELETED:hover {
  background-color: rgba(239, 68, 68, 0.15) !important;
}

/* MODIFIED rows: neutral, so the coloured rows stand out against them */
.diff-table tr.MODIFIED {
  /* no tint by design */
}

/* DATE_SHIFT rows: amber tint, matching their badge */
.diff-table tr.DATE_SHIFT {
  background-color: rgba(245, 158, 11, 0.08) !important;
}
.diff-table tr.DATE_SHIFT:hover {
  background-color: rgba(245, 158, 11, 0.15) !important;
}

/* The pinned activity-id cell is opaque, so it cannot inherit the row tint —
   it re-paints it as an overlay on top of its own solid background. */
.diff-table tr.ADDED td.col-code {
  background-image: linear-gradient(rgba(34, 197, 94, 0.08), rgba(34, 197, 94, 0.08));
}
.diff-table tr.DELETED td.col-code {
  background-image: linear-gradient(rgba(239, 68, 68, 0.08), rgba(239, 68, 68, 0.08));
}
.diff-table tr.DATE_SHIFT td.col-code {
  background-image: linear-gradient(rgba(245, 158, 11, 0.08), rgba(245, 158, 11, 0.08));
}
[data-theme="dark"] .diff-table tr.ADDED td.col-code {
  background-image: linear-gradient(rgba(34, 197, 94, 0.12), rgba(34, 197, 94, 0.12));
}
[data-theme="dark"] .diff-table tr.DELETED td.col-code {
  background-image: linear-gradient(rgba(239, 68, 68, 0.12), rgba(239, 68, 68, 0.12));
}
[data-theme="dark"] .diff-table tr.DATE_SHIFT td.col-code {
  background-image: linear-gradient(rgba(245, 158, 11, 0.12), rgba(245, 158, 11, 0.12));
}

/* Delta Cell Colors */
.delta-worse {
  color: #ef4444 !important;
  font-weight: 600;
}
.delta-better {
  color: #22c55e !important;
  font-weight: 600;
}

/* Diff Summary Card Accents */
.diff-added-card {
  border-left: 4px solid #22c55e;
}
.diff-added-value {
  color: #22c55e !important;
}
.diff-deleted-card {
  border-left: 4px solid #ef4444;
}
.diff-deleted-value {
  color: #ef4444 !important;
}

/* Diff Filter Button Active Colors */
#diff-filter-group button.active[data-filter="ADDED"],
#diff-filter-group button[data-filter="ADDED"]:hover {
  background-color: #22c55e !important;
  border-color: #22c55e !important;
  color: white !important;
}
#diff-filter-group button.active[data-filter="DELETED"],
#diff-filter-group button[data-filter="DELETED"]:hover {
  background-color: #ef4444 !important;
  border-color: #ef4444 !important;
  color: white !important;
}
#diff-filter-group button.active[data-filter="MODIFIED"],
#diff-filter-group button[data-filter="MODIFIED"]:hover {
  background-color: #3b82f6 !important;
  border-color: #3b82f6 !important;
  color: white !important;
}
#diff-filter-group button.active[data-filter="DATE_SHIFT"],
#diff-filter-group button[data-filter="DATE_SHIFT"]:hover {
  background-color: #f59e0b !important;
  border-color: #f59e0b !important;
  color: #1f2937 !important;
}

/* ═══════════════════════════════════════════ */
/*  DARK MODE: DIFF OVERRIDES                 */
/* ═══════════════════════════════════════════ */
[data-theme="dark"] .diff-table tr.ADDED {
  background-color: rgba(34, 197, 94, 0.12) !important;
}
[data-theme="dark"] .diff-table tr.ADDED:hover {
  background-color: rgba(34, 197, 94, 0.2) !important;
}
[data-theme="dark"] .diff-table tr.DELETED {
  background-color: rgba(239, 68, 68, 0.12) !important;
}
[data-theme="dark"] .diff-table tr.DELETED:hover {
  background-color: rgba(239, 68, 68, 0.2) !important;
}
[data-theme="dark"] .diff-table tr.DATE_SHIFT {
  background-color: rgba(245, 158, 11, 0.12) !important;
}
[data-theme="dark"] .diff-table tr.DATE_SHIFT:hover {
  background-color: rgba(245, 158, 11, 0.2) !important;
}
[data-theme="dark"] .delta-worse {
  color: #f87171 !important;
}
[data-theme="dark"] .delta-better {
  color: #4ade80 !important;
}

/* ═══════════════════════════════════════════ */
/*  SVG ICON SYSTEM (replaces all emoji)       */
/* ═══════════════════════════════════════════ */
/*
 * Icons are individual SVG files under /icons/, painted with CSS `mask` rather
 * than rendered as <img>. The mask takes only the SVG's alpha channel and fills
 * it with `currentColor`, which means:
 *
 *   - every icon inherits the surrounding text colour, so light/dark themes need
 *     ZERO per-icon overrides (an <img> would be stuck at its authored colour);
 *   - size follows font-size via the 1em box, so icons scale with their context;
 *   - swapping an icon is a pure file replacement — drop a new .svg over the old
 *     filename and nothing in the CSS, templates or JS changes.
 *
 * Because only alpha is used, source SVGs must be SOLID SHAPES (filled paths).
 * Stroke-only / multi-colour icons will mask to a hollow or blank silhouette;
 * pick the "solid" or "filled" variant when sourcing a replacement.
 */
.icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  background-color: currentColor;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-size: contain;
          mask-size: contain;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  flex-shrink: 0;
}

/* Optional size modifiers for places that need more than the inherited 1em. */
.icon-lg { width: 1.35em; height: 1.35em; }

.icon-sun       { -webkit-mask-image: url('/icons/sun.svg');       mask-image: url('/icons/sun.svg'); }
.icon-moon      { -webkit-mask-image: url('/icons/moon.svg');      mask-image: url('/icons/moon.svg'); }
.icon-trash     { -webkit-mask-image: url('/icons/trash.svg');     mask-image: url('/icons/trash.svg'); }
.icon-eye       { -webkit-mask-image: url('/icons/eye.svg');       mask-image: url('/icons/eye.svg'); }
.icon-globe     { -webkit-mask-image: url('/icons/globe.svg');     mask-image: url('/icons/globe.svg'); }
.icon-refresh   { -webkit-mask-image: url('/icons/refresh.svg');   mask-image: url('/icons/refresh.svg'); }
.icon-clipboard { -webkit-mask-image: url('/icons/clipboard.svg'); mask-image: url('/icons/clipboard.svg'); }
.icon-warning   { -webkit-mask-image: url('/icons/warning.svg');   mask-image: url('/icons/warning.svg'); }
.icon-gear      { -webkit-mask-image: url('/icons/gear.svg');      mask-image: url('/icons/gear.svg'); }
.icon-wrench    { -webkit-mask-image: url('/icons/wrench.svg');    mask-image: url('/icons/wrench.svg'); }

/* ═══════════════════════════════════════════════════════════════════════
   Schedule Narrative (/narrative)

   The fragnet diagrams are server-rendered inline SVG, so there is no graph
   library on this page and nothing to configure. The SVG carries its own
   colours as var(--token, fallback), which is why there are no per-theme
   rules for it here — it follows the theme tokens automatically.
   ═══════════════════════════════════════════════════════════════════════ */

/* A wide fragnet scrolls inside its own box rather than widening the page. */
.narr-diagram {
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0.5rem 0;
  max-width: 100%;
}
.narr-diagram svg { display: block; }

/* Loading profile: month, hours, bar. Fixed columns so the bars line up. */
.narr-load { margin-bottom: 0; }
.narr-load td { border: none; padding: 0.15rem 0.5rem; vertical-align: middle; }
.narr-load-month {
  font-family: var(--font-data);
  font-size: 0.78rem;
  white-space: nowrap;
  width: 5.5rem;
}
.narr-load-hours {
  font-family: var(--font-data);
  font-size: 0.78rem;
  white-space: nowrap;
  width: 5rem;
}
.narr-load-bar { width: auto; }
.narr-load-bar .progress { height: 0.65rem; }

/* The loading bars get their OWN fill colour rather than reusing
   .density-bar. That class is painted var(--border) in dark mode, which is
   exactly the colour the .progress track is also painted — so the bar was
   invisible against its own track and every month looked like one uniform
   grey block carrying no information. The density bars escape that by setting
   an inline background from DensityColor; these have no per-value colour to
   set, so they need a real one here. */
.narr-load-fill {
  background-color: var(--accent, #f59e0b);
  border-radius: 0.25rem;
}
/* A month with a little work still has to be visible, not a hairline. */
.narr-load-fill[style*="width:0"] { min-width: 1px; }

/* The monospace rendition of a diagram: never on screen, always on paper.
   Measured on the reference schedule, the fragnets run 1496 to 2144 px wide.
   Scaled to fit a portrait page their labels land between 3.7 and 5.3 px,
   which is a grey smudge rather than a diagram — so print swaps the SVG for
   this, which wraps to the page and stays readable. */
.narr-print-diagram { display: none; }

/* Print: the narrative is meant to be saved as a PDF and sent on, so the
   chrome goes and the cards stop breaking across pages mid-table. */
@media print {
  /* The theme's custom properties still apply on paper, and in dark mode
     --text is near-white — so everything that sets `color: var(--text)` printed
     as light grey on white. Setting `body { color: #000 }` could never fix that,
     because the elements override it. Redefining the tokens fixes every element
     at once, including the inline SVG diagrams, which paint from the same ones. */
  :root,
  :root[data-theme="dark"],
  :root[data-theme="light"] {
    --bg: #ffffff;
    --surface: #ffffff;
    --text: #000000;
    --text-muted: #333333;
    --border: #999999;
    --primary: #1a1a1a;
  }

  /* Bootstrap's own muted utilities carry their own colour and ignore the
     tokens above. */
  .text-muted,
  .text-secondary,
  small,
  .small {
    color: #333333 !important;
  }

  .d-print-none { display: none !important; }
  body { padding: 0; background: #ffffff; color: #000000; }

  /* Fills and strokes must survive a printer that drops backgrounds. */
  svg, .narr-histogram, .narr-diagram {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* On screen the profile keeps its natural width and scrolls, which is the
     only way a day-grain chart stays readable. Paper cannot scroll, so there
     it fits the page instead of being guillotined at the margin. */
  .narr-histogram { overflow: visible; }
  .narr-histogram svg { max-width: 100%; height: auto; }

  /* A collapsed section must still print: the paper copy is the whole
     narrative, not whatever happened to be open on screen. */
  .narr-section.narr-collapsed .narr-section-body { display: block !important; }
  .narr-section-toggle {
    color: #000000 !important;
    border-bottom-color: #999999 !important;
  }
  .narr-chevron { display: none !important; }
  .container-main { max-width: none; }
  .card {
    break-inside: avoid;
    page-break-inside: avoid;
    border: 1px solid #cccccc;
    box-shadow: none;
  }
  .table-responsive { overflow: visible !important; }

  .narr-print-diagram {
    display: block;
    font-family: var(--font-data);
    font-size: 7.4pt;
    line-height: 1.25;
    white-space: pre;
    margin: 0 0 0.5rem;
    color: #000000;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* Bars have to survive a printer that drops backgrounds. */
  .narr-load-bar .progress { border: 1px solid #999999; height: 0.5rem; }
  .narr-load-fill { background-color: #666666 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  a[href]::after { content: ''; }
}

/* ── Narrative diagrams: dragging ──────────────────────────────────────────
   Boxes can be dragged; the server re-routes the arrows on drop. The cursor
   advertises that, and the arrows dim while a box is moving because they are
   about to be wrong — showing them stretch would promise a route that is not
   the one the router will choose. */
.narr-diagram .fg-node {
  cursor: grab;
}

.narr-diagram.narr-diagram-dragging .fg-node {
  cursor: grabbing;
}

.narr-diagram.narr-diagram-dragging .fg-line,
.narr-diagram.narr-diagram-dragging .fg-elabel {
  opacity: 0.25;
}

/* The round trip is milliseconds, so this is a hint that something happened
   rather than a spinner anyone will sit and watch. */
.narr-diagram-busy {
  opacity: 0.6;
  transition: opacity 0.12s ease;
}

.narr-diagram .fg-node rect {
  transition: filter 0.12s ease;
}

.narr-diagram .fg-node:hover rect {
  filter: brightness(1.08);
}

@media print {
  .narr-diagram-note { display: none !important; }
}

/* ── One diagram on its own ────────────────────────────────────────────────
   The diagram keeps its natural size and the canvas scrolls around it, which
   is what gives a wide diagram real scrollbars and real browser zoom. Letting
   it shrink to fit would make zooming re-fit it instead of enlarging it. */
.fragnet-page {
  padding-top: 0;
  padding-bottom: 0;
}

.fragnet-canvas {
  overflow: auto;
  padding: 1rem;
  background: var(--bg);
}

.fragnet-canvas .narr-diagram svg {
  max-width: none;
  height: auto;
}

/* A loading profile is a quantity over time, so time runs along the bottom.
   It was a stack of horizontal bars, which hid the shape that matters: where
   the work piles up and how steeply it falls away. */
.narr-histogram {
  overflow-x: auto;
  padding: 0.25rem 0;
}

.narr-histogram svg {
  display: block;
}

/* ── Narrative section headings ───────────────────────────────────────────
   A heading has to be findable when scanning six sections of prose, and each
   section has to be closable so a reader can get past the ones they have
   already read. The whole heading is the control, not a small chevron beside
   it. */
.narr-section-heading {
  margin: 0 0 0.6rem;
}

.narr-section-toggle {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0 0 0.45rem;
  background: none;
  border: 0;
  border-bottom: 2px solid var(--primary);
  font-family: var(--font-heading);
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.narr-section-toggle:hover .narr-chevron,
.narr-section-toggle:focus-visible .narr-chevron {
  opacity: 1;
}

.narr-section-toggle:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
}

/* A triangle drawn in CSS: an icon file would need the masked-SVG system and
   this is one shape that only ever points two ways. */
.narr-chevron {
  flex: 0 0 auto;
  width: 0;
  height: 0;
  border-left: 6px solid currentColor;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  opacity: 0.55;
  transform: rotate(90deg);
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.narr-section.narr-collapsed .narr-chevron {
  transform: rotate(0deg);
}

.narr-section.narr-collapsed .narr-section-body {
  display: none;
}

.narr-section.narr-collapsed .narr-section-toggle {
  border-bottom-color: var(--border);
}

/* The narrative sits above the evidence it is drawn from. Prose wants a
   comfortable measure, which the evidence tables do not. */
.narr-section .narr-prose p,
.narr-section .narr-section-body > p {
  max-width: 68ch;
  line-height: 1.6;
}

.narr-placeholder {
  font-style: italic;
}

/* Producing the narrative. The work takes about a minute, so this reports
   which section is in hand rather than showing an indeterminate spinner. */
.narr-splash {
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.9rem 1rem;
  margin-bottom: 1.25rem;
  background: var(--surface);
}

.narr-splash-bar {
  background: var(--primary);
  transition: width 0.3s ease;
}

/* A section still waiting its turn, so the page does not look stalled. */
.narr-section.narr-pending .narr-section-toggle {
  opacity: 0.5;
}

.narr-section.narr-writing .narr-section-toggle::after {
  content: ' — writing…';
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--text-muted);
}

/* ─── ScopeControl branding: sign-in mark and attribution footer ───
   Shared by both looks. The tile matches Doc's sign-in page: an 80px tile in
   the page's surface colour (near-black in dark mode), Doc's light mark in
   light mode and its dark mark in dark mode. */
.scope-logo-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  margin-bottom: 1rem;
  border-radius: 12px;
  background: var(--surface, #ffffff);
  border: 1px solid var(--border, #e5e7eb);
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
}
.scope-logo-tile img { width: 48px; height: 48px; }
.scope-logo-tile .scope-mark-on-dark { display: none; }
[data-theme="dark"] .scope-logo-tile .scope-mark-on-light { display: none; }
[data-theme="dark"] .scope-logo-tile .scope-mark-on-dark { display: block; }
[data-theme="dark"] .scope-logo-tile { box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.5); }

.site-footer {
  margin-top: 2.5rem;
  padding: 1rem 0 0;
  text-align: center;
  font-size: 0.8rem;
  color: var(--text-muted, #6b7280);
}
.site-footer a { color: var(--accent); font-weight: 600; text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }
@media print { .site-footer { margin-top: 1rem; } }
