:root{
  --bg: hsl(210 30% 8%);
  --surface: hsla(32 50% 88% / .04);
  --surface-hover: hsla(32 50% 88% / .08);
  --border: hsla(32 50% 88% / .1);
  --text: hsla(32 50% 88% / .9);
  --text-dim: hsla(32 50% 88% / .72);
  --text-bright: hsl(32 50% 97%);
  --pea-cream: hsl(48 64% 70%);
  --pea-cream-dim: hsla(48 64% 70% / .8);
  --pea-green: hsl(88 64% 70%);
  --pea-amber: hsl(36 88% 70%);
  --pea-amber-dim: hsla(36 88% 70% / .85);
  --pea-yellow: hsl(52 92% 72%);
  --pea-yellow-dim: hsla(52 92% 72% / .85);
  --accent: #f39a4c;
  --link: var(--accent);
  --link-hover: var(--pea-cream);
  --focus-ring: rgba(243, 154, 76, .15);
  --muted: var(--text-dim);
  --ink: var(--text-bright);

  --hovercard-bg: hsl(210 30% 12%);
  --hovercard-border: hsla(32 50% 88% / .16);

  /* Shared status palette — used by rail dots (.bullet, .review-dot)
     AND by chip count badges (.run-status-chip .chip-count) so the
     "Due soon", "Overdue", "Not set", "Current" hue is identical
     wherever the user sees it. Picked to be bright enough to read on
     the dark rail background while still passing white-text contrast
     for the small chip-count digits. */
  --status-due-soon: hsl(28 90% 47%);
  --status-overdue:  hsl(4 72% 48%);
  --status-not-set:  hsl(260 50% 55%);
  --status-current:  hsl(140 45% 40%);
  /* Active-chip variants — one notch darker so the count reads
     against the cream-dim active chip without losing the hue. */
  --status-due-soon-active: hsl(28 90% 37%);
  --status-overdue-active:  hsl(4 78% 38%);
  --status-not-set-active:  hsl(260 50% 42%);
  --status-current-active:  hsl(140 50% 30%);

  --font-ui: system-ui, sans-serif;
  --size-sm: 13px; --size-md: 15px; --size-lg: 17px;
  --sp-xs: 8px; --sp-sm: 12px; --sp-md: 16px; --sp-lg: 24px; --sp-xl: 32px; --sp-xxl: 48px;
  --radius-sm: 4px; --radius-md: 6px; --radius-lg: 8px;
  --topbar-h: 72px; --rail-w: 310px;

  /* micro-adjust for dot alignment if needed */
  --status-dot-nudge: 0px;
}

*{ box-sizing: border-box; margin:0; }
html, body{ height: 100%; }
.ui{
  background:var(--bg);
  color:var(--text);
  font: var(--size-md)/1.5 var(--font-ui);
  height: 100vh;
  overflow:hidden;
  display:flex;
  flex-direction:column;
}

/* ====================== Topbar ====================== */
.topbar{
  position: sticky; top: 0; z-index: 1000;
  height: var(--topbar-h);
  flex: 0 0 var(--topbar-h);
  min-height: var(--topbar-h);
  display:flex; align-items:center; gap:var(--sp-sm);
  padding: 0 var(--sp-md);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border-bottom:1px solid var(--border);
}
.brand{
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--sp-sm); color:var(--text-bright);
  width:var(--rail-w); flex-shrink:0;
  /* Cancel the topbar's left padding so the brand box starts at the
     same x-coordinate as the rail below it. Keeps the toggle aligned
     with the rail's right divider in expanded mode and the rail icons
     in collapsed mode. */
  margin-left: calc(-1 * var(--sp-md));
  transition: width .18s ease;
}
.brand-logo{ height:32px; width:auto; object-fit:contain; }
.menu-toggle-dots{ width:40px; height:40px; object-fit:contain; display:block; }
/* Strip the icon-btn chrome (border, background, padding) on the toggle
   while it's showing the threep mark — the peas read as a logo, not a
   button, until the user hovers and the sidecar icon swaps in. */
body:has(.rail.collapsed) #menuToggle{
  padding:0; border-color:transparent; background:transparent;
}
body:has(.rail.collapsed) #menuToggle:hover{
  padding:4px; border-color:var(--border); background:var(--surface);
}

/* Sidecar toggle face — two SVGs share the slot; the visible one
   depends on rail state + hover. Stack them so the swap is instant
   and the button's box doesn't reflow. */
#menuToggle{ position:relative; }
#menuToggle .menu-toggle-sidecar,
#menuToggle .menu-toggle-dots{ display:block; }
/* Default (rail expanded): show the sidecar icon. */
#menuToggle .menu-toggle-dots{ display:none; }

/* Icons-only collapsed rail: drop the wordmark so the toggle slot
   sits centered in the narrow column. The brand width tracks
   --rail-w via the transition, so the toggle stays aligned to the
   rail's right edge through the animation. The toggle face flips
   to the three-dot threep mark, swapping back to the sidecar icon
   on hover/focus — same affordance as OpenAI's collapsed sidebar. */
body:has(.rail.collapsed) .brand-logo{ display:none; }
/* Brand width must shrink with the rail so the toggle slot lines up
   over the rail's icon column. (--rail-w isn't repointed by
   .rail.collapsed — that rule sets width:56px directly — so target
   the brand explicitly here.) */
body:has(.rail.collapsed) .brand{ width:56px; justify-content:center; }
body:has(.rail.collapsed) #menuToggle .menu-toggle-sidecar{ display:none; }
body:has(.rail.collapsed) #menuToggle .menu-toggle-dots{ display:block; }
body:has(.rail.collapsed) #menuToggle:hover .menu-toggle-sidecar,
body:has(.rail.collapsed) #menuToggle:focus-visible .menu-toggle-sidecar{ display:block; }
body:has(.rail.collapsed) #menuToggle:hover .menu-toggle-dots,
body:has(.rail.collapsed) #menuToggle:focus-visible .menu-toggle-dots{ display:none; }
button.ghost{
  padding:8px 12px; border:1px solid var(--border); border-radius:var(--radius-md);
  background:transparent; color:var(--text); cursor:pointer;
}
button.ghost:hover{ background:var(--surface); }

/* Health indicator (right side) */
.topbar #health { margin-left: auto; }

#health{
  display: inline-flex; align-items: center; gap: 12px;
  line-height: 1;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .3px;
  white-space: nowrap;
  transition: color .2s ease, opacity .2s ease;
}
#healthLabel { color: #fff !important; }

/* State text colors */
#health.ok{       color: var(--pea-green);  animation: none; }
#health.checking{ color: var(--pea-cream);  animation: none; }
#health.warn{     color: #e39a9a;           animation: none; }

/* Pulse the label text */
#health.ok #healthLabel{       animation: none; }
#health.checking #healthLabel{ animation: none; }

/* Animations */
@keyframes pulseReady { 0%,100%{opacity:1} 50%{opacity:.6} }
@keyframes peaBounce  { 0%,80%,100%{transform:translateY(0) scale(1);opacity:.55} 40%{transform:translateY(-9px) scale(1.15);opacity:1} }

/* Three-pea thinking animation */
.thinking-peas[hidden]{ display:none !important; }
.thinking-peas{
  display:inline-flex; align-items:center; gap:5px;
  padding: 3px 0;
}
.thinking-peas span{
  display:inline-block;
  width:7px; height:7px; border-radius:50%;
  animation: peaBounce 1.2s ease-in-out infinite;
}
.thinking-peas span:nth-child(1){
  background: #F0C47D;            /* logo gold pea */
  box-shadow: 0 0 6px rgba(240,196,125,.55);
  animation-delay: 0s;
}
.thinking-peas span:nth-child(2){
  background: #91D3B3;            /* logo mint pea */
  box-shadow: 0 0 6px rgba(145,211,179,.55);
  animation-delay: 0.2s;
}
.thinking-peas span:nth-child(3){
  background: #F8F9F9;            /* logo white pea */
  box-shadow: 0 0 6px rgba(248,249,249,.30);
  animation-delay: 0.4s;
}

/* ====================== Icons / Buttons ====================== */
.icon-btn{
  position:relative;
  display:inline-flex; align-items:center; justify-content:center;
  padding:4px;
  border:0;
  background:transparent;
  color:var(--ink);
  cursor:pointer;
}
.icon-btn:hover{ opacity:.85; }

/* --- Normalize all icon/action buttons --- */
.icon-btn,
button.icon-btn,
button.copy-btn,
#historyBtn,
#copyBtn {
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.icon-btn:hover,
button.icon-btn:hover,
button.copy-btn:hover,
#historyBtn:hover,
#copyBtn:hover {
  background: var(--surface-hover);
  border-color: var(--border);
  /* no color change here for dark */
}

/* Answer-card copy button is glyph-only — drop the boxed look so it
   reads as an icon next to the mode badge, not another button. */
#copyBtn{
  background: transparent;
  border-color: transparent;
  opacity: .75;
}
#copyBtn:hover{
  background: transparent;
  border-color: transparent;
  opacity: 1;
}
#copyBtn.copied{
  color: var(--status-ok, #16a34a);
  opacity: 1;
}

/* Light theme only: brighten icons/labels on hover */
html.light .icon-btn:hover,
html.light button.icon-btn:hover,
html.light button.copy-btn:hover,
html.light #historyBtn:hover,
html.light #copyBtn:hover {
  color: var(--text-bright);
}

/* ====================== Layout ====================== */
.shell{ display:flex; flex: 1 1 auto; overflow:hidden; min-height:0; }

/* Rail */
.rail{
  width:var(--rail-w);
  border-right:1px solid var(--border);
  display:flex; flex-direction:column;
  transition: width .18s ease, padding .18s ease;
  height: 100%;
  overflow:hidden;
  min-height: 0;
}
.rail-scroll{
  flex:1 1 auto; min-height:0;
  overflow-y:auto;
  /* Tightened from --sp-sm (12px) so additional nav sections fit
     without forcing the rail to scroll. Inner-section spacing (and
     the policies/assessments/runs containers) stay as before. */
  display:flex; flex-direction:column; gap:4px;
  padding:var(--sp-md) var(--sp-md) var(--sp-sm) 0;
  scrollbar-gutter:stable;
}
/* Icons-only collapsed state — narrow rail showing just the section
   icons (Home / Controls / Policies / Assessments / Scheduled Runs /
   Model Information / Knowledge Base / Settings). Mirrors the
   OpenAI/VS Code sidecar pattern. Click the sidecar toggle in the
   topbar to flip between this and the full rail. */
.rail.collapsed{ width:56px; }
.rail.collapsed .rail-scroll{
  padding: var(--sp-md) 0 var(--sp-sm) 0;
  overflow-x:hidden;
  scrollbar-gutter:auto;
}
.rail.collapsed .rail-section.settings{
  padding:8px 0;
}

/* Center each row's icon and hide the trailing label text. font-size:0
   collapses the bare text nodes ("Home", "Policies", …) without
   affecting the SVGs (their width/height are explicit attributes). */
.rail.collapsed .rail-nav-link,
.rail.collapsed .policies-header{
  justify-content:center;
  margin:0;
  padding:6px 0;
  font-size:0;
  gap:0;
}
.rail.collapsed .policies-header > h3{ gap:0; font-size:0; }

/* Hide everything inside the section header except the icon stack. */
.rail.collapsed .policies-header .section-controls,
.rail.collapsed .policies-header .policies-toggle,
.rail.collapsed .policies-header::before{ display:none; }

/* Panes and large content blocks always stay collapsed in icons-only
   mode — there isn't room for filter inputs, chip rows, lists, etc. */
.rail.collapsed [id$="Pane"],
.rail.collapsed .runs-pane,
.rail.collapsed .scheduler-pill-row,
.rail.collapsed .rail-group-label,
.rail.collapsed .rail-section.recents,
.rail.collapsed .runs-admin-row{ display:none !important; }

/* Tighten section gaps so the icon column reads as a clean stack. */
.rail.collapsed .rail-section{ gap:0; }
.rail.collapsed .rail-nav-links{ gap:4px; padding-top:0; }
.rail-section{ display:flex; flex-direction:column; gap:var(--sp-sm); }
.rail-section h3{
  color:var(--text-bright); font-size:14px; font-weight:500;
  display:flex; align-items:center; gap:8px; white-space:nowrap;
}
.rail-h3-icon{
  flex-shrink:0; opacity:.7; width:18px; height:18px;
}

/* Badges (dark mode baseline) */
.count-badge,
.badge{
  color: #000;
}

/* Small spinner next to "Manage policies" — kept for fallback */
.mini-spinner{
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-left: 8px;
  border-radius: 50%;
  border: 2px solid var(--border);
  border-top-color: var(--pea-cream);
  box-shadow: 0 0 6px hsl(48 64% 70% / .25);
  animation: spin 0.9s linear infinite;
  vertical-align: -1px;
}
.mini-spinner[hidden]{ display:none !important; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Mini three-pea animation — rail section headers */
@keyframes peaBounceMini { 0%,80%,100%{transform:translateY(0) scale(1);opacity:.5} 40%{transform:translateY(-5px) scale(1.2);opacity:1} }
.mini-peas[hidden]{ visibility:hidden !important; display:inline-flex !important; }
.mini-peas{
  display:inline-flex; align-items:center; gap:4px;
  margin-left:4px; vertical-align:middle;
  pointer-events:none;
}
.mini-peas span{
  display:inline-block;
  width:6px; height:6px; border-radius:50%;
  animation: peaBounceMini 1.2s ease-in-out infinite;
}
.mini-peas span:nth-child(1){
  background: #F0C47D;
  box-shadow: 0 0 5px rgba(240,196,125,.6);
  animation-delay: 0s;
}
.mini-peas span:nth-child(2){
  background: #91D3B3;
  box-shadow: 0 0 5px rgba(145,211,179,.6);
  animation-delay: 0.2s;
}
.mini-peas span:nth-child(3){
  background: #F8F9F9;
  box-shadow: 0 0 5px rgba(248,249,249,.35);
  outline: 1px solid rgba(0,0,0,.35);
  animation-delay: 0.4s;
}

/* Policies pane: filter + bounded list scroller */
.policies .filter-row,
.assessments .filter-row,
.scheduled-runs .filter-row{
  display:flex; gap:8px; align-items:center;
}
.policies #policyFilter,
.assessments #assessmentFilter,
.scheduled-runs #runsFilter{
  flex:0 1 auto;
  width:160px;             /* short field — most policy/assessment names
                              fit a substring lookup in well under 160px */
  padding:10px 12px;
  border:1px solid var(--border);
  border-radius:var(--radius-md);
  background:var(--surface);
  color:var(--text);
}
.policies #policyFilter:focus,
.assessments #assessmentFilter:focus,
.scheduled-runs #runsFilter:focus{
  outline:none; border-color:var(--pea-cream-dim);
}
.policies #policyFilter::placeholder,
.assessments #assessmentFilter::placeholder,
.scheduled-runs #runsFilter::placeholder{ color: var(--text-dim); }
/* Search + sort group. The old border-top divider was retired once the
   admin row moved up into the kebab menu — there's nothing above the
   filter to visually separate from anymore. Bumped gap (12px) gives
   the input some breathing room above the chips. */
.runs-filter-group{
  margin-top:6px; padding:6px 0 8px;
  display:flex; flex-direction:column; gap:12px;
}
.runs-filter-row{ margin:0; }

/* Status chips: quick toggle filters above the runs list */
.runs-status-chips{
  display:flex; flex-wrap:wrap; gap:4px;
  margin:0;
}
.run-status-chip{
  background:transparent; color:var(--text-dim);
  border:1px solid var(--border);
  border-radius:999px;
  padding:2px 9px;
  font-size:11px; font-weight:600;
  cursor:pointer;
  transition: background .15s, color .15s, border-color .15s;
}

/* Documents / Assessments / Scheduled Runs: tighter filter+chip layout.
   The default spacing (above) was overkill for these rail panes — three
   cumulative gaps (rail-section gap, runs-filter-group margin/padding,
   gap between filter row and chips) produced a ~30px void above each
   list. */
.rail-section.policies,
.rail-section.assessments,
.rail-section.scheduled-runs{ gap:4px; }
.policies .runs-filter-group,
.assessments .runs-filter-group,
.scheduled-runs .runs-filter-group{
  margin-top:0; padding:0 0 4px;
  gap:8px;
}
.policies #policyFilter,
.assessments #assessmentFilter,
.scheduled-runs #runsFilter{ padding:6px 10px; font-size:12px; }
.policies .run-status-chip,
.assessments .run-status-chip,
.scheduled-runs .run-status-chip{
  padding:1px 7px;
  font-size:10px;
}
.run-status-chip:hover{ color:var(--text); border-color:var(--pea-cream-dim); }
.run-status-chip.active{
  background:var(--pea-cream-dim); color:#000;
  border-color:var(--pea-cream-dim);
}

/* "Show all (N more)" button — matches policiesMore / assessmentsMore.
   Inherits .btn-ghost.sm sizing so it reads the same across sections. */

/* Run hover card: subtitle line shown when both schedule_name and
   assessment_name are present (the schedule name is the title, the
   assessment is the secondary). */
.run-hover-card .run-card-sub{
  font-size:11px; color:var(--text-dim);
  margin:-4px 0 6px 22px;
  line-height:1.3;
}
.run-hover-card .meta .v .assessment-status-pill{
  display:inline-block; padding:2px 8px; border-radius:999px;
  font-size:11px; font-weight:600; line-height:1;
}
/* Type identification: each card type gets a 4px left accent stripe
   and a distinct title-icon color. Picked for *lightness* contrast so
   color-blind operators can still tell them apart. */
.policy-hover-card{
  border-left: 4px solid #2563eb;   /* cobalt — Policy */
}
.policy-hover-card .title > .ico{
  color: #2563eb;
}

.run-hover-card{
  background: hsl(192 26% 12%);
  border-color: hsl(192 30% 24%);
  border-left: 4px solid #f59e0b;   /* amber — Run */
}
.run-hover-card .actions{
  background: hsl(192 26% 12%);
}
.run-hover-card .title > .ico{
  color: #f59e0b;
}

.assessment-hover-card{
  background: hsl(265 22% 13%);
  border-color: hsl(265 28% 26%);
  border-left: 4px solid #d946ef;   /* magenta — Assessment */
}
.assessment-hover-card .actions{
  background: hsl(265 22% 13%);
}
.assessment-hover-card .title > .ico{
  color: #d946ef;
}
.assessment-hover-card .meta .v .assessment-status-pill{
  display:inline-block; padding:2px 8px; border-radius:999px;
  font-size:11px; font-weight:600; line-height:1;
}
.assessment-hover-card .run-card-sub{
  font-size:11px; color:var(--text-dim);
  margin:-4px 0 6px 22px;
  line-height:1.3;
}
/* Cursor affordance: pinned cards can be right-click-dragged. */
.policy-hover-card.is-pinned,
.run-hover-card.is-pinned{
  cursor: grab;
}
.policy-hover-card.is-dragging,
.run-hover-card.is-dragging{
  cursor: grabbing;
  user-select: none;
}

/* bounded scroller for long lists */
.policies #policies{
  max-height: 40vh;              /* tuned to leave room for uploader */
  overflow:auto; padding-right:2px;
  margin-top:6px;
}

.kv{ color:var(--text-dim); font-size:var(--size-sm); display:flex; flex-direction:column; gap:4px; }
.kv div{ display:flex; gap:8px; }
.kv b{ color:var(--text); font-weight:500; }

.file-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* Vertical guide line down the left side of the expanded section, matching
     the "Recents"-style sidebar pattern. The list is offset right by
     padding-left so item content sits a few px clear of the line; the line
     itself is drawn via border-left. */
  margin: 0 0 0 8px;
  padding: 0 0 0 8px;
  border-left: 1px solid var(--border);
}
.file-list li {
  display: flex;
  align-items: flex-start;
  box-sizing: border-box;
  /* Tighter gap (was 8px) so icon → bullet → name reads as a tight
     leading group without big spaces between them. */
  gap: 4px;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  transition: background 0.12s ease;
}
.file-list .bullet{
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: transparent;
  transition: box-shadow .18s ease, transform .18s ease, opacity .18s ease;
}
.file-list .doc-icon-wrap{
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  margin-top: 1px;
}
/* Status dot rides at the icon's upper-right corner, vertically half-over
   the document name's top edge — reads as a notification badge on the
   icon rather than a separate column. */
.file-list .doc-icon-wrap > .bullet{
  position: absolute;
  top: -3px;
  right: -5px;
  margin: 0;
  z-index: 1;
}
.file-list .doc-icon{
  color: var(--text-dim);
  opacity: .7;
}
.file-list li:hover .doc-icon{ opacity: .9; }
/* Document rows are clickable: left-click opens the policy in the main
   content pane (matches the hover card's "view" action). Cursor scoped
   to the documents list since assessment/run rows already have a button
   child handling their own click affordance. */
.policies #policies li{ cursor: pointer; }
.file-list .bullet.amber   { background: var(--status-due-soon); }
.file-list .bullet.red     { background: var(--status-overdue); }
.file-list .bullet.missing { background: var(--status-not-set); }
.file-list .bullet.green   { background: var(--status-current); }
.file-list li:hover .bullet{
  box-shadow: 0 0 0 3px hsl(0 0% 60% / .15), 0 0 10px hsl(0 0% 60% / .12);
  transform: translateY(-0.5px);
}
.file-list li:hover {
  background: var(--surface);
}
.file-list .fname-col {
  display: flex; flex-direction: column; flex: 1; min-width: 0;
}
.file-list .fname {
  color: var(--text-bright);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.3;
  white-space: normal;
}
.file-list .tag {
  font-size: var(--size-sm);
  opacity: 0.7;
}

/* subtle group feel for items + clearer hover */
.file-list li{ transition: background .12s ease; }
.file-list li:hover .fname{ color:var(--text); }

/* Policy hover card (shows metadata on mouseover) */
.policy-hover-card{
  position: fixed;
  z-index: 3000;
  width: 420px;
  max-width: 520px;
  max-height: calc(100vh - 16px);
  overflow: auto;
  scrollbar-gutter: stable;
  padding: 10px 12px;
  padding-bottom: 14px; /* prevent bottom-row buttons from clipping against the scroll container */
  border: 1px solid var(--hovercard-border);
  border-radius: var(--radius-md);
  background: hsl(210 30% 12%);
  box-shadow: 0 14px 36px rgba(0,0,0,.35);
}
.policy-hover-card[hidden]{ display:none !important; }
/* Pin button — top-right corner of hover card */
.policy-hover-card .pin-btn{
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: 50%;
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  transition: color .15s ease, background .15s ease, transform .15s ease;
  flex-shrink: 0;
}
.policy-hover-card .pin-btn:hover{
  color: var(--text);
  background: var(--surface-hover);
  border-color: var(--border);
}
.policy-hover-card .pin-btn.active{
  color: #e03e3e;
  background: rgba(224,62,62,.12);
  border-color: rgba(224,62,62,.30);
  transform: rotate(-45deg);     /* tilted = "pushed in" */
}
.policy-hover-card:not([hidden]){ animation: hoverCardIn .16s ease-out both; }
@keyframes hoverCardIn {
  from { opacity: 0; transform: translateY(4px) scale(.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce){ .policy-hover-card:not([hidden]){ animation:none; } }
.policy-hover-card .title{
  display:flex;
  align-items:flex-start;
  gap:8px;
  font-size: 13px;
  font-weight: 650;
  color: var(--text-bright);
  margin-bottom: 6px;
  line-height: 1.25;
  padding-right: 28px; /* clear the absolute pin button */
}
.policy-hover-card .title span{
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
  overflow: hidden;
}
.policy-hover-card .rename-btn{
  flex-shrink:0;
  width:22px; height:22px; border-radius:4px;
  border:0; background:transparent; color:var(--text-dim);
  display:inline-flex; align-items:center; justify-content:center;
  cursor:pointer; opacity:0; transition:opacity .15s;
}
.policy-hover-card .title:hover .rename-btn{ opacity:1; }
.policy-hover-card .rename-btn:hover{ color:var(--pea-cream); background:rgba(255,255,255,.06); }
.policy-hover-card .rename-input{
  flex:1; font-size:13px; font-weight:650;
  background:var(--surface); color:var(--text-bright);
  border:1px solid var(--pea-cream-dim); border-radius:4px;
  padding:2px 6px; outline:none;
}
.policy-hover-card .ico{
  opacity: .9;
  color: var(--pea-cream);
  flex: 0 0 auto;
}
.policy-hover-card .meta{
  display: grid;
  grid-template-columns: 88px 1fr;
  gap: 4px 10px;
  font-size: 12px;
  color: var(--text-dim);
}
.policy-hover-card .meta .k{
  opacity: .9;
  display:flex;
  align-items:center;
  gap:6px;
}
.policy-hover-card .meta .k span{ display:inline-block; }
.policy-hover-card .meta .k .ico{ color: var(--text-dim); }
.policy-hover-card .meta .v{ color: var(--text); }
.policy-hover-card .preview{
  margin-top: 4px;
  padding-top: 8px;
}
.policy-hover-card .preview-h{
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-dim);
  margin-bottom: 6px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.policy-hover-card .preview-h .ai-spark{
  color: var(--accent);
  flex-shrink: 0;
  width: 16px;
  height: 16px;
}
.policy-hover-card .preview-b{
  font-size: 12px;
  color: var(--text);
  line-height: 1.35;
  white-space: pre-line;
  max-height: 5.4em;
  overflow: hidden;
}

/* ---- Review date row (inside hover card) ---- */
.policy-hover-card .review-row{
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 0;
  margin-bottom: 0;
}
.policy-hover-card .review-label{
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
  flex-shrink: 0;
}
.policy-hover-card .review-status-label{
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.policy-hover-card .review-date-input{
  font-size: 11px;
  padding: 2px 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  flex-shrink: 0;
}
.policy-hover-card .review-date-input:hover{ border-color: var(--pea-cream-dim); }
.policy-hover-card .review-date-input:focus{ outline: none; border-color: var(--pea-cream); }
.policy-hover-card .review-date-input::-webkit-calendar-picker-indicator{ filter:invert(0.7); cursor:pointer; opacity:0.8; }
.policy-hover-card .review-date-input::-webkit-calendar-picker-indicator:hover{ opacity:1; }

/* ---- Review dot (policy list + hover card) ---- */
.review-dot{
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--text-dim);
}
.review-dot.green   { background: var(--status-current); }
.review-dot.amber   { background: var(--status-due-soon); }
.review-dot.red     { background: var(--status-overdue); }
.review-dot.missing { background: var(--status-not-set); }
.review-dot.sm      { width: 7px; height: 7px; }

/* Unified rail pills for Policies + Assessments section headers */
.rail-pill{
  display:inline-block; vertical-align:top;
  font-size:11px; font-weight:800; line-height:1;
  padding:3px 7px; border-radius:999px;
  cursor:default; white-space:nowrap;
  border: 1px solid transparent;
  box-shadow: 0 1px 0 hsl(0 0% 100% / .08);
}
.rail-pill[hidden]{ display:none !important; }
.rail-pill.warn    { background:hsl(28 90% 52%);   color:#fff; border-color:hsl(28 80% 42%/.70); }
.rail-pill.crit    { background:hsl(4 85% 55%);    color:#fff; border-color:hsl(4 75% 45%/.70); }
.rail-pill.missing { background:hsl(260 50% 58%);  color:#fff; border-color:hsl(260 45% 48%/.70); }

.policy-hover-card .actions{
  display:flex;
  justify-content:center;
  flex-wrap: nowrap;
  gap: 10px;
  margin-top:10px;
  padding: 12px 12px 6px;
  position: sticky;
  bottom: 0;
  background: hsl(210 30% 12%);
  border-top: 1px solid var(--border);
}
.policy-hover-card .actions button{
  padding: 7px 14px;
  font-size: 13px;
  border-radius: var(--radius-sm);
}
.policy-hover-card .actions button span{ white-space: nowrap; }
.policy-hover-card .actions button .ico{
  color: currentColor;
  opacity: .9;
}
.policy-hover-card .actions button.primary{
  display:inline-flex;
  align-items:center;
  gap:6px;
  border: 1px solid hsl(48 64% 70% / .38);
  background: linear-gradient(90deg, hsl(48 64% 70% / .22), hsl(88 64% 70% / .16));
  color: var(--text-bright);
}
.policy-hover-card .actions button.primary:hover{
  background: linear-gradient(90deg, hsl(48 64% 70% / .28), hsl(88 64% 70% / .20));
}
.policy-hover-card .actions button.primary:active{
  transform: translateY(0.5px);
}
.policy-hover-card .actions button.ghost{
  display:inline-flex;
  align-items:center;
  gap:6px;
}
.policy-hover-card .actions button:disabled{
  opacity: .55;
  cursor: not-allowed;
}
.policy-hover-card .actions button.ghost{
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
}
.policy-hover-card .actions button.ghost:hover{
  background: var(--surface-hover);
}
.policy-hover-card .actions button.danger{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid hsl(0 80% 60% / .35);
  color: hsl(0 80% 75%);
  background: transparent;
  cursor: pointer;
}
.policy-hover-card .actions button.danger:hover{
  background: hsl(0 80% 60% / .10);
}

/* collapsed state for policies section */
/* Pane is animated via grid-template-rows (see "Rail pane animation"
   block below), so the default [hidden] -> display:none would kill the
   transition. The grid trick handles visibility via 0fr/1fr instead. */
/* (intentionally no display:none on #policiesPane[hidden]) */

.upload-row{
  display:flex; align-items:center; gap:10px; margin-top:8px;
}
.upload-row input{
  flex:1; padding:6px; border:1px solid var(--border); border-radius:var(--radius-sm);
  background:transparent; color:var(--text);
}
.upload-row input:focus{ outline:none; border-color:var(--pea-cream-dim); }
.upload-row button{
  padding:6px 10px; border:1px solid var(--pea-cream-dim); border-radius:var(--radius-sm);
  color:var(--pea-cream); background:transparent; cursor:pointer;
}
.upload-row button:hover{ background:var(--surface); }

.upload-row .icon-btn.pick{
  border:1px solid var(--pea-cream-dim);
  border-radius:var(--radius-sm);
  padding:6px;                       /* larger hit area */
}

.upload-row .icon-btn.pick:hover{ background:var(--surface); }
.policies .upload-row .icon-btn.pick { color: var(--pea-cream); }
.policies .upload-row .icon-btn.pick:hover { color: var(--pea-cream); }
.upload-row #fileName{
  flex:1; color:var(--text-dim); font-size:var(--size-sm); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

/* Upload pipeline status (Manage Policies) */
.upload-status{
  position: relative;
  margin-top: 8px;
  padding: 8px 34px 8px 26px; /* room for status dot + close button */
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text-dim);
  font-size: 12.5px;
  line-height: 1.25;
  transition: opacity .4s ease;
}
.upload-status.fade-out{
  opacity: 0;
}
.upload-status::before{
  content: "";
  position: absolute;
  left: 10px;
  top: 50%;
  width: 9px;
  height: 9px;
  transform: translateY(-50%);
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 6px currentColor;
}
.upload-status-close{
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  background: transparent;
  color: currentColor;
  opacity: .75;
  cursor: pointer;
}
.upload-status-close:hover{ opacity: 1; }
.upload-status-close:focus-visible{
  outline: 2px solid var(--pea-cream-dim);
  outline-offset: 2px;
  border-radius: 4px;
}
.upload-status[data-state="uploaded"]{ color: #2151F5; }
.upload-status[data-state="converting"]{ color: var(--pea-cream); }
.upload-status[data-state="converted"]{ color: var(--pea-cream); }
.upload-status[data-state="ingesting"]{ color: var(--pea-cream); }
.upload-status[data-state="done"]{ color: var(--pea-green); }
.upload-status[data-state="error"]{ color: #e39a9a; border-color: hsl(0 80% 60% / .35); background: hsl(0 80% 60% / .06); }
.upload-status[data-state="uploaded"]::before,
.upload-status[data-state="converting"]::before,
.upload-status[data-state="converted"]::before,
.upload-status[data-state="ingesting"]::before{
  animation: dotPulse 1.5s ease-in-out infinite;
}
.upload-index-meta{
  margin-top: 6px;
  font-size: 12px;
  color: var(--text-dim);
}

/* ====================== Main ====================== */
.main{ flex:1; height: 100%; overflow:auto; min-height:0; scrollbar-gutter: stable; }
.main-inner{ max-width:960px; margin:0 auto; padding: var(--sp-lg) var(--sp-xl); }

/* ====================== Split view ======================
   Workbench layout: detail panels (Documents/Assessments/Schedules/
   Coverage/Editor) shrink to leave a fixed-width column on the right
   where the askbar + welcome + answer naturally render. Lets the user
   ask questions while keeping a doc/assessment/run visible alongside.
   Toggled per-session via the split-view button in each panel header
   (state persisted in localStorage). */
:root { --ask-dock-w: 380px; --panel-gap: 16px; }
/* The body.split-view panel right-offset is set in the "Detail panel
   card framing" block at the END of the file so it wins over each
   panel's individual base rule. */
body.split-view .main-inner{
  max-width: var(--ask-dock-w);
  margin-left: auto;
  margin-right: 0;
  padding-left: var(--sp-md);
  padding-right: var(--sp-md);
}
/* Card framing for the right-column ask area when split is on — matches
   the panel styling so the two read as side-by-side cards. */
/* main-inner's top padding is set by the split-view scroll-container
   block below (var(--panel-gap)). The askbar sits at that padding,
   visually aligned with the left panel's top. */
/* In normal view the .main-scroll wrapper is layout-transparent — its
   children participate in main-inner's normal flow as if the wrapper
   weren't there. Split-view rules below upgrade it to a real flex
   scroll container. */
.main-scroll{ display: contents; }
/* Contain the right column inside the viewport. main-inner becomes a
   flex column where the askbar stays fixed at the top and the wrapper
   below it (.main-scroll) owns the scroll for the cards. The askbar is
   completely outside the scroll context, so scrolled content can't bleed
   under it visually — cleaner than the previous sticky approach. */
body.split-view .main{
  overflow: hidden;
}
body.split-view .main-inner{
  height: 100%;
  display: flex;
  flex-direction: column;
  padding-top: var(--panel-gap);
  padding-bottom: 0;
}
body.split-view .askbar{
  flex: 0 0 auto;            /* fixed natural size, no shrink/grow */
  margin-bottom: var(--panel-gap);
}
body.split-view .main-scroll{
  display: flex;             /* override .main-scroll display:contents */
  flex-direction: column;
  gap: var(--panel-gap);
  flex: 1 1 auto;
  min-height: 0;             /* required for flex-child overflow to work */
  overflow: hidden;          /* contain cards; each scrolls internally */
  padding-bottom: var(--panel-gap);
}
/* Answer card fills the remaining space below the askbar and scrolls
   INSIDE — matches the doc panel on the left where the card has a fixed
   bottom edge and content scrolls within it, instead of bleeding off
   the page. */
body.split-view #answer.card{
  /* Size to content but cap at the column height. The card itself owns
     the scroll so EVERYTHING inside (title, body, and the gap-panel
     sibling) scrolls together — otherwise the gap-panel could grow
     past the card's bottom edge while the body alone scrolled. */
  flex: 0 1 auto;
  max-height: 100%;
  min-height: 0;
  display: block;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
body.split-view #answer.card::-webkit-scrollbar{ width:6px; height:6px; }
body.split-view #answer.card::-webkit-scrollbar-track{ background:transparent; }
body.split-view #answer.card::-webkit-scrollbar-thumb{ background-color:var(--border); border-radius:6px; }
body.split-view #answer.card::-webkit-scrollbar-thumb:hover,
body.split-view #answer.card::-webkit-scrollbar-thumb:active{ background-color:#B3A99E; }
/* Trim the answer body's text by 1px in the narrow column so a long
   answer doesn't overwhelm the docked panel. Wide mode keeps the full
   --size-md inherited from <body>. */
body.split-view #answer.card .body{ font-size: 14px; }
/* Same idea for the Sources / Sources-&-context cards beneath the
   answer — at 380px the title + metadata + Show button can't fit on
   one row at full size, so it wraps awkwardly. Shrink the chrome so
   the card reads as a tight footer rather than a stack of wrapped
   lines. */
body.split-view #sourcesWrap .card-title,
body.split-view #contextWrap .card-title{
  font-size: 13px;
  margin-bottom: 8px;
}
body.split-view #sourcesWrap .card-title .small,
body.split-view #contextWrap .card-title .small{
  font-size: 11px;
  max-width: none;
  white-space: normal;
}
body.split-view #sourcesWrap .list,
body.split-view #contextWrap .list{ font-size: 12px; }
/* My display:flex above wins over the UA [hidden]→display:none for the
   answer card. Explicit override so hidden cards actually disappear
   instead of rendering as an empty remnant card. */
body.split-view .card[hidden]{
  display: none !important;
}
body.split-view .askbar{
  /* Original .askbar has no background — give it the same .card surface
     so it reads as a card alongside the answer card below. */
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px;
}
/* The askbar's send/clear/history + mode-selector are absolute-positioned
   at bottom:8px / left:8px / right:8px of .askbar. With the new 12px
   outer padding they end up overlapping the textarea's left/right/bottom
   borders. Offset them by the padding amount so they float cleanly
   inside the textarea like in the non-split layout. */
body.split-view .askbar-actions{
  bottom: calc(8px + 12px);
  right: calc(8px + 12px);
}
body.split-view .askbar-left{
  bottom: calc(8px + 12px);
  left: calc(8px + 12px);
}
/* Right-column cards keep the default .card background (--surface) so
   they retain the white-on-gray contrast in light mode and the
   subtle-with-border look in dark mode. Shadow removed — the left doc
   panel keeps its shadow as the visually dominant element. */

/* In split mode the right column is narrow — the Suggested-questions
   row is dead weight there (the answer card needs the vertical real
   estate). Hide both the toggle row and any expanded chip list. */
body.split-view #suggestionsWrap{ display:none !important; }

/* Resize handle for the split-view ask column. Sits in the gap between
   the panel and the right column (which is var(--panel-gap) wide). The
   handle is centered on that gap so it's grabbable on either side. */
.dock-resize{
  position: fixed;
  top: calc(var(--topbar-h) + var(--panel-gap));
  bottom: var(--panel-gap);
  /* Centered in the gap between the panel (right edge at ask-dock-w +
     2*panel-gap) and the right column (left edge at ask-dock-w from the
     right). Gap width = 2*panel-gap; handle width = 8px. */
  right: calc(var(--ask-dock-w) + var(--panel-gap) - 4px);
  width: 8px;
  z-index: 1002;
  cursor: col-resize;
  background: transparent;
  transition: background .15s ease;
}
.dock-resize:hover,
.dock-resize.dragging{
  background: hsl(45 90% 60% / .25);
}
body:not(.split-view) .dock-resize{ display:none; }

/* Card framing for the detail panels was moved to the END of the file
   so it wins over each panel's individual base rule (which sets
   top/right/bottom/left to full-bleed values). See the "Detail panel
   card framing" block at the bottom. */
/* Split-view toggle button: appears in each panel's header next to the
   close X. Two icons inside are swapped via the body.split-view class
   so the button reflects the action it'll take when clicked (collapse
   to full screen vs. expand to split). */
.split-view-toggle{
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; padding:0;
  background:transparent; border:none; border-radius:var(--radius-sm);
  color:var(--text-dim); cursor:pointer;
  transition:color .15s ease, background .15s ease;
}
.split-view-toggle:hover{ color:var(--text); background:var(--surface-hover); }
.split-view-toggle .ico-split{ display:inline; }
.split-view-toggle .ico-full{ display:none; }
body.split-view .split-view-toggle .ico-split{ display:none; }
body.split-view .split-view-toggle .ico-full{ display:inline; }
.welcome{ color:var(--text-dim); text-align:center; margin: var(--sp-xxl) auto; max-width:640px; }

/* First-run welcome hint */
.welcome-hint { margin-bottom: var(--sp-md); }
.welcome-hint .welcome-note { margin-bottom: var(--sp-sm); font-size: var(--size-sm); }
.welcome-hint .welcome-chips { margin-top: 0; margin-bottom: var(--sp-xs); }
.welcome-hint .welcome-mode-note { font-size: 11px; opacity: .55; }

/* Ask bar */
.askbar{ position:relative; display:block; margin-bottom:var(--sp-lg); }
.askbar:focus-within{
  border-radius: var(--radius-lg);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.askbar.thinking{
  opacity: 0.45;
  pointer-events: none;
  transition: opacity .2s ease;
}
.askbar textarea{
  width:100%; box-sizing:border-box;
  padding:16px 16px 52px 20px;
  border:1px solid var(--border); border-radius:var(--radius-lg);
  background:var(--surface); color:var(--text); font-size:15px; min-height:96px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.08);
  resize:none; vertical-align:top; line-height:1.5; font-family:inherit;
  overflow-y:hidden;
}
.askbar textarea:focus{ outline:none; border-color:var(--pea-cream-dim); }
/* Mode selector anchored to bottom-left */
.askbar-left{
  position:absolute; left:8px; bottom:8px;
  display:flex; align-items:center; gap:4px;
}
.askbar-left #assessmentToggle{
  display:inline-flex; align-items:center; gap:4px;
  padding:5px 10px; font-size:12px; font-weight:500; cursor:pointer;
  border:1px solid var(--border); border-radius:999px;
  background:transparent; color:var(--text-dim);
  transition:background .15s, border-color .15s, color .15s;
}
.askbar-left #assessmentToggle svg{
  transition: transform .2s ease;
  flex-shrink:0;
}
.askbar-left #assessmentToggle:hover{
  border-color:var(--pea-cream-dim); color:var(--pea-cream);
}
.askbar-left #assessmentToggle.active{
  background:hsl(48 64% 70% / .14);
  border-color:var(--pea-cream); color:var(--pea-cream);
}
.askbar-left #assessmentToggle.active svg{
  transform: rotate(180deg);
}
/* Buttons anchored to bottom-right of the textarea */
.askbar-actions{
  position:absolute; right:8px; bottom:8px;
  display:flex; align-items:center; gap:6px;
}
.askbar-actions .icon-btn{
  width:34px; height:34px; border-radius:var(--radius-md);
  color:var(--text-dim); border:0; background:transparent;
  display:inline-flex; align-items:center; justify-content:center;
}
.askbar-actions .icon-btn:hover{ color:var(--text); background:rgba(255,255,255,.06); }
/* Ask / Send button — accent rounded square */
.askbar-actions #askBtn{
  width:34px; height:34px; border-radius:var(--radius-md);
  background:var(--pea-cream); border:0; color:#000; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center;
  transition:background .15s ease;
}
.askbar-actions #askBtn:hover{ filter:brightness(1.12); }
.askbar-actions #askBtn:disabled{ opacity:.45; cursor:default; }
/* Clear "X" — neutral */
.askbar-actions #clearBtn { color: var(--text-dim); }
.askbar-actions #clearBtn:hover { color: var(--text); }

/* Suggested question chips */
.chips{
  display:flex;
  flex-wrap:wrap;
  gap:8px;
  margin-top: -10px;
  margin-bottom: var(--sp-lg);
}
.chips[hidden]{ display:none !important; }
.suggestions-wrap{
  margin-top: 10px;
  margin-bottom: var(--sp-lg);
}
.suggestions-wrap .chips{
  margin-top: 8px;
  margin-bottom: 0;
}
.suggestions-head{
  display:flex;
  align-items:center;
  justify-content:flex-end;
  gap:10px;
}
.suggestions-head .muted{
  font-size: 11px;
  font-weight: 400;
  opacity: .6;
}
.suggestions-wrap .btn-ghost.sm{ margin-top: 0; }
.suggestions-wrap.collapsed .chips{ display:none !important; }
.chip{
  display:inline-flex;
  align-items:center;
  gap:8px;
  padding: 6px 10px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, transform .12s ease, box-shadow .12s ease;
}
.chip:hover{
  background: var(--surface-hover);
  border-color: var(--pea-cream-dim);
  box-shadow: 0 0 0 3px var(--focus-ring);
  transform: translateY(-0.5px);
}
.chip:active{ transform: translateY(0); }

/* Pinned dropdown */
.dropdown{
  position: fixed;
  z-index: 2500;
  min-width: 240px;
  max-width: 340px;
  padding: 8px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: 0 18px 46px rgba(0,0,0,.35);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.dropdown[hidden]{ display:none !important; }
.dropdown .item{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text);
}
.dropdown .item:hover{ background: var(--surface-hover); }
.dropdown .item .label{
  flex:1;
  overflow:hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dropdown .empty{
  padding: 10px;
  color: var(--text-dim);
  font-size: 12px;
}
.dropdown .subhead{
  padding: 6px 10px;
  color: var(--text-dim);
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.badge{
  position:absolute; top:-6px; right:-6px;
  font-size:11px; line-height:1; padding:3px 7px;
  border-radius:999px;
  background: hsl(48 90% 74%);
  color:#000 !important;
  font-weight:800;
  border: 1px solid hsl(48 70% 45% / .55);
  box-shadow: 0 1px 0 hsl(0 0% 100% / .08);
}

/* --- Rail polish for Manage Policies --- */
/* Overlay matches the content area exactly so both rounded corners
   sit inside the rail (no clipping at x=0 from .rail{overflow:hidden}).
   The right padding + scrollbar gutter keeps it clear of the
   scrollbar; the left edge sits flush with the rail's icon column. */
.policies-header{
  display:flex; align-items:center; gap:6px;
  padding:4px 8px 4px 0;
  margin:0;
  border-radius:var(--radius-md);
  position:relative; z-index:0;
  cursor:pointer;
}
.policies-header::before{
  content:''; position:absolute;
  top:2px; left:0; right:0; height:30px;
  border-radius:var(--radius-md);
  background:transparent;
  transition:background .15s;
  pointer-events:none; z-index:-1;
}
.policies-header:hover::before{ background:var(--surface-hover); }
.policies-header > h3{ flex-shrink:0; }
.policies-toggle{ flex-shrink:0; }
.rail-section h3{ justify-content:flex-start; }
.rail-section h3 > .icon-btn{ margin-left:auto; flex-shrink:0; }
.section-controls{
  display:flex; align-items:center; gap:4px;
  margin-left:8px;
  /* Visibility gate moved to the kebab button itself (see rule below).
     Keeping the wrap fully opaque means the position:fixed menu inside
     isn't dimmed by parent opacity multiplication when it's open. */
}
/* Kebab is hidden by default and only appears when the user hovers (or
   keyboard-focuses) the section header. Decoupled from menu state so
   opening the menu doesn't pin the kebab visible after mouseout. */
.section-controls .runs-header-menu-wrap > .icon-btn{
  opacity:0 !important; pointer-events:none !important;
  transition:opacity .15s !important;
}
/* Exclude the case where the dropdown menu itself is being hovered:
   the menu is a DOM descendant of .policies-header, so naive :hover
   would propagate up and keep the kebab visible while the mouse is
   over the menu. :not(:has(.runs-header-menu:hover)) skips that. */
.policies-header:hover:not(:has(.runs-header-menu:hover)) .section-controls .runs-header-menu-wrap > .icon-btn{
  opacity:.8 !important; pointer-events:auto !important;
}
.policies-header:hover:not(:has(.runs-header-menu:hover)) .section-controls .runs-header-menu-wrap > .icon-btn:hover{
  opacity:1 !important;
}
/* The kebab fades out as soon as the mouse leaves the header, even when
   the dropdown is open. The menu stays visible (it's position:fixed and
   only closes on outside-click) and the chevron stays as a down-arrow
   because the kebab button retains aria-expanded="true" while open. */
/* Dark mode: drop the border/background on the section-header
   action icons so they read as glyphs, not buttons. Light mode keeps
   the boxed look (better contrast on the lighter surface). */
html:not(.light) .section-controls .icon-btn{
  background:transparent; border-color:transparent;
}
/* Kebab hover stays glyph-only — no surface-hover box, no border.
   The dots brighten via .icon-btn:hover's existing opacity tweak,
   which is enough affordance without adding a button chrome. */
html:not(.light) .section-controls .icon-btn:hover{
  background:transparent; border-color:transparent;
}
.section-pills{
  display:flex; align-items:center; gap:4px; flex-wrap:nowrap;
  opacity:0; pointer-events:none;
  transition:opacity .15s;
}
.section-pills:empty{ display:none; }
.policies-header:hover .section-pills{
  opacity:1; pointer-events:auto;
}
.icon-btn.sm{ width:26px; height:26px; padding:0; opacity:.8; flex-shrink:0; }
.icon-btn.sm:hover{ opacity:1 }

.count-badge{
  background: hsl(48 90% 74%);
  color:#000 !important;
  border-color: hsl(48 70% 45% / .55);
}

/* ====================== Cards ====================== */
.card{
  padding:var(--sp-lg);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  background:var(--surface);
  transition:background .2s ease-in-out;
  position: relative; /* keep shadows, tooltips, etc. */
  z-index: 0;         /* ensure header stays above */
}
.card:hover{ background:var(--surface-hover); }

/* Cap any generic card-like elements. Exclude *-hover-card variants:
   their z-index:3000 must win so they float above the assessment/run/
   coverage panels (z-index 1001) when they pop out of the rail. */
[class*="card"]:not([class*="hover-card"]){ z-index: 0; }

/* Consistent vertical rhythm */
.history-wrap{ margin-bottom:var(--sp-lg); }
.card + .card{ margin-top:var(--sp-lg); }
.askbar + .card{ margin-top:var(--sp-lg); }

/* System status popover — anchored beside the "Ready" health label in the
   topbar. The wrap is the positioning context; the card is absolutely
   positioned below the icon and toggled by the systemStatusBtn click handler. */
.system-status-wrap{ position:relative; display:inline-flex; }
.system-status-card{
  /* Fixed-positioned (not absolute) so it can escape the topbar's
     stacking context — backdrop-filter creates one, and the card was
     visually clipped by the topbar even with z-index:9999 because the
     wrap (inline-flex, icon-button-tall) was centered in the topbar,
     leaving the card's "top:100%+8px" anchor above the topbar's
     bottom. Pinning to viewport-relative coords sidesteps both. */
  position:fixed;
  top:calc(var(--topbar-h) + 4px);
  right:var(--sp-md);
  z-index:9999;
  min-width:280px; max-width:min(520px, calc(100vw - 32px));
  padding:var(--sp-md) var(--sp-lg);
  background:hsl(210 30% 13%);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  box-shadow:0 8px 24px hsl(0 0% 0%/.55);
}
.system-status-card[hidden]{ display:none !important; }
.system-status-card .card-title{
  font-weight:600; color:var(--text-bright);
  margin-bottom:var(--sp-sm);
}
.system-status-card .system-status-grid{
  display:flex; flex-direction:column;
  gap:var(--sp-xs);
}

/* Entry animation for cards */
@keyframes fadeSlideUp {
  from { opacity:0; transform:translateY(6px); }
  to   { opacity:1; transform:translateY(0); }
}
.reveal { animation: fadeSlideUp .28s ease-out both; }
@media (prefers-reduced-motion: reduce){ .reveal { animation:none; } }

/* Staggered reveal (sources/context list items) */
.reveal-stagger:nth-of-type(1){ animation-delay:0s; }
.reveal-stagger:nth-of-type(2){ animation-delay:0.06s; }
.reveal-stagger:nth-of-type(3){ animation-delay:0.12s; }
.reveal-stagger:nth-of-type(4){ animation-delay:0.18s; }

/* ====================== Typography & Links ====================== */
.card-title{ font-weight:600; color:var(--text-bright); margin-bottom:12px; }
.card-title.card-title-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
}
.card-title .title-right{
  display:inline-flex;
  align-items:center;
  gap:10px;
  margin-left:auto;
}
.card-title .title-right .btn-ghost.sm{ margin-top: 0; }
.card-title .title-right .small{
  max-width: 52ch;
  overflow:hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.body{ white-space:pre-wrap; line-height:1.6; }

.body .ans-secs{ white-space: normal; display:grid; gap:12px; }

/* Accordion affordance — header is clickable; chevron rotates with state.
   The actual collapse-on-click behavior is gated on body.split-view in
   the rules below, but the chrome ships in both modes so users get
   visual feedback that the headers are interactive. */
.body .ans-sec-h{ cursor: pointer; user-select: none; }
.body .ans-sec-chev{
  flex: 0 0 auto;
  color: var(--text-dim);
  opacity: .7;
  transition: transform .15s ease;
  margin-left: 2px;
}
.body .ans-sec.is-collapsed .ans-sec-chev{ transform: rotate(-90deg); }
.body .ans-sec-h:hover .ans-sec-chev{ opacity: 1; }
.body .ans-sec-h:focus-visible{
  outline: 2px solid var(--pea-cream-dim);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Activate the accordion only when the right column is docked. In
   wide mode the .is-collapsed class is visually inert and every
   section renders open as before. */
body.split-view .body .ans-sec.is-collapsed .ans-sec-b{ display: none; }
body.split-view .body .ans-sec.is-collapsed{ padding-bottom: 8px; }

/* "Show N more" affordance for long lists (>3 items). */
.body .ans-li-hidden{ display: none; }
.body .ans-ul-toggle{
  list-style: none;
  margin-left: -16px;
  margin-top: 2px;
}
.body .ans-ul-show-more{
  background: transparent;
  border: none;
  padding: 2px 0;
  color: var(--accent);
  font-size: 11.5px;
  font-style: italic;
  cursor: pointer;
}
.body .ans-ul-show-more:hover{ text-decoration: underline; }
.body .ans-ul-show-more:focus-visible{
  outline: 2px solid var(--pea-cream-dim);
  outline-offset: 2px;
  border-radius: 4px;
}
.body .ans-sec{
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px;
  background: var(--surface);
}
.body .ans-sec-h{
  display:flex;
  align-items:center;
  gap:10px;
  font-weight: 700;
  color: var(--text-bright);
  margin-bottom: 6px;
}
/* Title eats remaining space so the pill + chevron always anchor to
   the right edge — consistent across sections regardless of title
   length. (Without this, justify-content:space-between centered the
   pill between the title and the chevron, drifting per-section.) */
.body .ans-sec-h .ans-sec-title{ flex: 1; min-width: 0; }
.body .ans-pill{
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text-dim);
  background: var(--surface-hover);
  flex: 0 0 auto;
}
.body .ans-pill.policy{ border-color: hsl(88 64% 70% / .30); color: var(--pea-green); }
.body .ans-pill.nist{ border-color: hsl(36 88% 70% / .30); color: var(--pea-amber); background: hsl(36 88% 70% / .06); }
.body .ans-pill.check{ border-color: hsl(52 92% 72% / .28); color: var(--pea-yellow); background: hsl(52 92% 72% / .06); }
.body .ans-pill.summary{ border-color: hsl(210 64% 70% / .30); color: hsl(210 84% 78%); background: hsl(210 84% 78% / .06); }
.body .ans-sec-supporting-nist-reference{
  border-left: 3px solid hsl(36 88% 70% / .60);
  background: linear-gradient(180deg, hsl(36 88% 70% / .06), var(--surface));
}
.body .ans-sec-summary{
  border-left: 3px solid hsl(210 84% 78% / .55);
  background: linear-gradient(180deg, hsl(210 84% 78% / .06), var(--surface));
}
.body .ans-sec-policy-coverage{
  border-left: 3px solid hsl(88 64% 70% / .50);
}
.body .ans-sec-implementation-details{
  border-left: 3px solid hsl(52 92% 72% / .55);
  background: linear-gradient(180deg, hsl(52 92% 72% / .05), var(--surface));
}
.body .ans-sec-policy-details{
  border-left: 3px solid hsl(88 64% 70% / .50);
}
.body .ans-sec-b{ color: var(--text); }
.body .ans-p{ margin: 0 0 8px; }
.body .ans-p:last-child{ margin-bottom: 0; }
.body .ans-ul{ margin: 0; padding-left: 18px; }
.body .ans-ul li{ margin: 2px 0; }

/* ====================== Policy Viewer ====================== */
.body .policy-view{
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: 12px;
  white-space: normal;
}
/* ===== Policy Panel — read-only document viewer (mirrors .assessment-panel) ===== */
.doc-panel[hidden]{ display:none !important; }
.doc-panel{
  position:fixed;
  top:var(--topbar-h); right:0; bottom:0; left:var(--rail-w);
  z-index:1001;
  background:var(--bg);
  display:flex; flex-direction:column; overflow:hidden;
  transition:left .18s ease;
}
body:has(.rail.collapsed) .doc-panel{ left:56px; }
.doc-panel-inner{
  display:flex; flex-direction:column; height:100%;
  width:100%; padding:16px 24px;
}
.doc-panel-hdr{
  display:flex; align-items:center;
  padding:6px 0 10px; border-bottom:1px solid var(--border);
  flex-shrink:0; gap:12px;
}
.doc-panel-hdr .panel-close-btn{ margin-left:auto; flex-shrink:0; }
.doc-panel-title-wrap{
  display:flex; align-items:center; gap:8px;
  min-width:0; flex:1;
}
.doc-panel-icon{
  flex:0 0 auto; color:var(--text-dim); opacity:.85;
}
.doc-panel-title{
  font-size:16px; font-weight:650; color:var(--text-bright);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.doc-panel-actions{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  flex-shrink:0;
}
.doc-panel-meta{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:6px 14px;
  padding:8px 0 10px;
  font-size:11px; color:var(--text-dim);
  border-bottom:1px solid var(--border);
  flex-shrink:0;
}
.doc-panel-meta .meta-item{
  display:inline-flex; align-items:center; gap:4px;
  white-space:nowrap;
}
.doc-panel-meta .meta-item-path{
  flex:0 1 auto; min-width:0;
  max-width:100%;
}
.doc-panel-meta .meta-item-path .mono{
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.doc-panel-meta .meta-ico{
  flex:0 0 auto; opacity:.7;
}
.doc-panel-body{
  flex:1; min-height:0;
  display:flex; flex-direction:column;
  padding-top:10px;
}
.doc-panel-body .policy-view-tools{
  display:flex; align-items:center; gap:8px;
  flex-wrap:wrap; flex-shrink:0;
  margin-bottom:10px;
}
.doc-panel-body .policy-view-pre{
  flex:1; min-height:0; overflow:auto;
  margin:0;
  padding:12px;
  border:1px solid var(--border); border-radius:var(--radius-md);
  background:rgba(0,0,0,.06);
  white-space:pre-wrap; word-break:break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-size:13px; line-height:1.5;
  scrollbar-width:thin; scrollbar-color:var(--border) transparent;
}
.doc-panel-body .policy-view-pre::-webkit-scrollbar{ width:6px; height:6px; }
.doc-panel-body .policy-view-pre::-webkit-scrollbar-track{ background:transparent; }
.doc-panel-body .policy-view-pre::-webkit-scrollbar-thumb{ background-color:var(--border); border-radius:6px; }
.doc-panel-body .policy-view-pre::-webkit-scrollbar-thumb:hover,
.doc-panel-body .policy-view-pre::-webkit-scrollbar-thumb:active{ background-color:#B3A99E; }
.doc-panel-body .policy-view-pre mark.mark{
  padding:0 .06em; background:hsl(45 90% 60%/.35); color:inherit;
}
.doc-panel-body .policy-view-pre mark.active{
  background:hsl(45 90% 60%/.7); color:#000;
}
.policy-view-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
}
.policy-view-title{
  font-weight: 800;
  color: var(--text-bright);
  min-width: 0;
  overflow:hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.policy-view-actions{
  display:flex;
  align-items:center;
  gap:8px;
  flex: 0 0 auto;
}
.policy-view-meta{
  margin-top: 4px;
}
.policy-view-tools{
  margin-top: 8px;
  display:flex;
  align-items:center;
  gap:8px;
  flex-wrap: wrap;
}
.policy-view-tools .policy-find{
  flex: 1 1 260px;
  min-width: 200px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: rgba(0,0,0,.14);
  color: var(--text);
}
.policy-view-tools .policy-find::placeholder{ color: var(--text-dim); }
.policy-view-tools .policy-find-count{ min-width: 64px; text-align: right; }
.policy-view-body{
  margin-top: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: rgba(0,0,0,.06);
  max-height: 60vh;
  overflow:auto;
  padding: 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.policy-view-body::-webkit-scrollbar{ width:6px; height:6px; }
.policy-view-body::-webkit-scrollbar-track{ background:transparent; }
.policy-view-body::-webkit-scrollbar-thumb{ background-color:var(--border); border-radius:6px; }
.policy-view-body::-webkit-scrollbar-thumb:hover,
.policy-view-body::-webkit-scrollbar-thumb:active{ background-color:#B3A99E; }
.policy-view-pre{
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-size: 13px;
  line-height: 1.5;
}
.policy-view-pre mark.mark{
  padding: 0 .06em;
  border-radius: 3px;
  background: rgba(243, 154, 76, .25);
  color: inherit;
}
.policy-view-pre mark.mark.active{
  background: rgba(243, 154, 76, .55);
  outline: 1px solid rgba(243, 154, 76, .55);
}

#sources a, #context a, .main a{ color:var(--link, var(--accent)); text-decoration:none; }
#sources a:hover, #context a:hover, .main a:hover{ text-decoration:underline; }

.src-footer{
  margin-top: 10px;
  display:flex;
  align-items:center;
  justify-content:flex-end;
}
.src-footer button{ white-space: nowrap; }
.src-score{
  display:inline-block;
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text-dim);
  background: var(--surface-hover);
  margin-left: 8px;
  flex: 0 0 auto;
}
.src-row{
  display:flex;
  align-items:baseline;
  gap:8px;
  min-width:0;
}
.src-row a{
  min-width:0;
  overflow:hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display:inline-block;
  max-width: 100%;
}
.card.collapsed ol{ display:none; }
.card.collapsed .src-footer{ display:none; }

.pill{
  display:inline-block; padding:.1rem .45rem; border-radius:.5rem;
  font-size:.75rem; margin-right:.4rem; border:1px solid var(--border); opacity:.95;
}
.pill.policy{ background:rgba(127,191,144,.15); }
.pill.nist{ background:rgba(243,154,76,.15); }

/* ====================== Answer Header ====================== */
#answer .card-title{
  display:flex; align-items:center; justify-content:space-between; gap:8px; width:100%;
}

.mode-badge{
  margin-left: 10px;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-hover);
  font-size: 11px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.mode-badge.compliance{ border-color: hsl(88 64% 70% / .35); color: var(--pea-green); }
.mode-badge.policy{ border-color: hsl(48 64% 70% / .35); color: var(--pea-cream); }
.mode-badge.general{ border-color: var(--border); color: var(--text-dim); }
.mode-badge.assessment{ border-color: hsl(270 50% 60% / .35); color: hsl(270 100% 85%); }

/* ── Mode chips row (above askbar) ──────────────────────────── */
/* .mode-chips removed — assessmentToggle now lives inside .askbar-left */

/* Assessment answer paragraphs + citation bullets */
.assess-para{
  margin: 0 0 6px 0;
  line-height: 1.65;
}
.assess-cites{
  list-style: none;
  margin: 0 0 16px 0;
  padding: 0 0 0 12px;
  border-left: 2px solid var(--border);
}
.assess-cites li{
  font-size: 12px;
  color: var(--text-dim);
  padding: 1px 0;
}

/* ====================== Gap Panel ====================== */
.gap-panel{
  margin-top: 12px;
  padding: 12px;
  border: 1px dashed hsl(48 64% 70% / .35);
  border-radius: var(--radius-md);
  background: linear-gradient(180deg, hsl(48 64% 70% / .10), transparent);
}
.gap-panel.notice{
  border-style: solid;
  border-color: hsl(48 64% 70% / .25);
  background: linear-gradient(180deg, hsl(48 64% 70% / .06), transparent);
}
.gap-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
}
.gap-title{
  display:flex;
  align-items:center;
  gap:8px;
  font-weight: 650;
  color: var(--text-bright);
}
.gap-actions{
  display:flex;
  gap:8px;
  flex-wrap:wrap;
  justify-content:flex-end;
}

/* Kebab variant of .gap-actions for split-view. The 3 buttons can't fit
   alongside the title in a 380px column, so we collapse them into a
   "..." kebab. CSS-only swap: in wide mode .gap-actions-kebab is
   hidden; in split-view it replaces the inline button row. */
.gap-actions-kebab{
  display: none;
  position: relative;
  flex-shrink: 0;
}
.gap-kebab-btn{
  background: transparent;
  border: none;
  color: var(--text-dim);
  padding: 4px;
  cursor: pointer;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
}
.gap-kebab-btn:hover{ color: var(--text); background: var(--surface-hover); }
.gap-kebab-menu{
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 10;
  background: hsl(210 30% 13%);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 180px;
  box-shadow: 0 4px 16px hsl(0 0% 0% / .5);
}
.gap-kebab-menu[hidden]{ display: none !important; }
.gap-kebab-menu button{
  /* Mirror .runs-header-menu-item so this menu reads as part of the
     same family as the section-header kebabs (Policies / Assessments
     / Runs / Settings). */
  display: inline-flex; align-items: center;
  background: transparent;
  border: none;
  text-align: left;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  color: var(--text);
  cursor: pointer;
  font-size: 12px;
  white-space: nowrap;
  width: 100%;
}
.gap-kebab-menu button:hover{
  background: var(--surface-hover);
  color: var(--text-bright);
}
body.split-view .gap-actions{ display: none; }
body.split-view .gap-actions-kebab{ display: inline-flex; align-items: center; }
.gap-pill{
  display:inline-block;
  padding: 2px 7px;
  border-radius: 999px;
  border: 1px solid var(--border);
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.gap-pill.none{ border-color: hsl(0 80% 60% / .35); color: hsl(0 80% 75%); }
.gap-pill.partial{ border-color: hsl(48 64% 70% / .35); color: var(--pea-cream); }
.gap-meta{ margin-top: 8px; display:grid; gap:4px; }
.gap-suggest{ margin: 8px 0 0 18px; color: var(--text-dim); font-size: 12px; }

.gap-tasks-wrap{ margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.gap-tasks-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
.gap-tasks{
  list-style:none;
  padding-left:0;
  margin: 8px 0 0;
  display:grid;
  gap: 6px;
}
.gap-tasks li{
  display:grid;
  grid-template-columns: 1fr auto;
  gap: 6px 8px;
  align-items:start;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.gap-tasks li.done{ opacity: .65; }
.gap-tasks li .q{ grid-column: 1 / -1; font-size: 11px; }
.gap-tasks input[type="checkbox"]{ margin-right: 8px; }
.gap-tasks .label{ font-weight: 600; color: var(--text); }
/* Dark theme (default) — keep accent outline look */
#historyBtn{
  color: var(--pea-cream);
  background: transparent;
  border: 1px solid var(--pea-cream-dim);
  border-radius: var(--radius-md);
  padding: 6px 10px;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
#historyBtn:hover{
  background: var(--surface);
  color: var(--pea-cream);          /* <-- prevent white-on-hover */
}

/* Ensure the history icon follows the button color */
#historyBtn svg {
  color: currentColor !important;
  stroke: currentColor !important;
}

/* ====================== History UI ====================== */
.toolbar{ display:none !important; }
.history-list{ list-style:none; padding-left:0; margin:0; }
.history-list li{ padding:6px 8px; border-radius:var(--radius-sm); cursor:pointer; }
.history-list li:hover{ background:var(--surface-hover); }

.hidden{ display:none !important; }

.btn-clear{
  margin-top:8px; margin-bottom:16px;
  background:transparent;
  border:1px solid var(--border);
  color:var(--text-dim);
  font-size:12px; padding:4px 8px;
  border-radius:8px; cursor:pointer;
  transition:all 0.2s ease-in-out;
}
.btn-clear:hover{ color:var(--text-bright); border-color:var(--text-bright); }
.btn-clear[disabled]{
  opacity:.5; pointer-events:none; cursor:default; border-style:dashed;
}

/* Filter placeholder tone (parity with Ask field) */
.policies #policyFilter::placeholder { color: var(--text-dim); }

/* Stronger focus ring for keyboard users */
.policies #policyFilter:focus,
.askbar input:focus {
  outline: 2px solid transparent;
  border-color: var(--pea-cream-dim);
  box-shadow: 0 0 0 3px var(--focus-ring); /* soft accent halo */
}

/* Answer loading — no shimmer, peas handle the indicator */
#answer.loading .body{ color: var(--text-dim); }
#answer::before{
  content:"";
  position:absolute;
  left:16px; right:16px; top:0;
  height:1px;
  background: linear-gradient(90deg, transparent, var(--pea-cream-dim), transparent);
  opacity:.65;
  pointer-events:none;
}

/* Collapse chevron animation */
#policiesToggle svg, #assessmentsToggle svg,
#modelInfoToggle svg, #kbInfoToggle svg, #settingsToggle svg,
#runsToggle svg { transition: transform .16s ease; }
#policiesToggle[aria-expanded="false"] svg,
#assessmentsToggle[aria-expanded="false"] svg,
#modelInfoToggle[aria-expanded="false"] svg,
#kbInfoToggle[aria-expanded="false"] svg,
#settingsToggle[aria-expanded="false"] svg,
#runsToggle[aria-expanded="false"] svg { transform: rotate(-90deg); }

/* Rail top nav links */
.rail-nav-links{
  display:flex; flex-direction:column; gap:4px;
  padding-top:8px;
}
.rail-nav-link{
  display:flex; align-items:center; gap:8px;
  margin:0 -6px; padding:6px 14px 6px 6px;
  background:transparent; border:none; outline:none;
  -webkit-appearance:none; appearance:none;
  -webkit-tap-highlight-color:transparent;
  font-family:inherit; color:var(--text-bright); font-size:14px; font-weight:500;
  cursor:pointer; text-align:left;
  border-radius:var(--radius-md);
  transition:color .15s, background .15s;
}
.rail-nav-link:hover{ color:var(--text-bright); background:var(--surface-hover); }
.rail-nav-link svg{ opacity:.7; flex-shrink:0; width:18px; height:18px; }
.rail-nav-link[hidden]{ display:none !important; }

/* Nav icon swap — section icon replaced by chevron on hover / expanded */
.nav-icon-wrap{
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  width:18px; height:18px; flex-shrink:0;
}
/* Activity indicator: tiny pulsing dot in the top-right of the section icon.
   Replaces the in-header mini-peas spinner for Policies/Assessments — costs
   zero header width so it never competes with controls/pills. Stays visible
   through the icon→chevron hover swap because it lives outside that pair. */
.activity-dot{
  position:absolute; top:-2px; right:-2px;
  width:7px; height:7px; border-radius:50%;
  background:#91D3B3;
  box-shadow:0 0 6px rgba(145,211,179,.7);
  animation: activityPulse 1.4s ease-in-out infinite;
  pointer-events:none;
}
.activity-dot[hidden]{ display:none !important; }
@keyframes activityPulse{
  0%, 100%{ transform:scale(1); opacity:1; }
  50%{ transform:scale(1.35); opacity:.55; }
}
.nav-icon-wrap .section-icon,
.nav-icon-wrap .hover-chevron{
  position:absolute; inset:0; width:18px; height:18px;
  transition:opacity .15s;
}
.nav-icon-wrap .hover-chevron{ opacity:0; }
.policies-header:hover .section-icon{ opacity:0; }
.policies-header:hover .hover-chevron{ opacity:1; }
.policies-header:has([aria-expanded="true"]) .section-icon{ opacity:0; }
.policies-header:has([aria-expanded="true"]) .hover-chevron{ opacity:1; }
/* Collapsed rail = icons-only nav strip — always show the section glyph
   (Documents/Assessments/Schedules), never the expand chevron, since the
   section's expanded state is irrelevant when the rail itself is closed. */
.rail.collapsed .policies-header .section-icon{ opacity:1 !important; }
.rail.collapsed .policies-header .hover-chevron{ opacity:0 !important; }
/* Hide the right-side toggle chevron — click is delegated to the header */
.policies-toggle{ display:none !important; }
/* Make the header row feel clickable */
.policies-header{ cursor:pointer; }
/* But restore normal cursor over the action buttons */
.policies-header .icon-btn{ cursor:pointer; }

/* Model info / KB / Settings collapsible panes */
/* (model-info / kb-info pane visibility is handled by the
   grid-template-rows transition below; no display:none override here.
   #settingsPane was retired when Settings became header-only.) */

/* Model info / KB section h3 flex for toggle button */
.rail-section.model-info h3,
.rail-section.kb-info h3,
.rail-section.settings h3{ display:flex; align-items:center; }

/* Settings section pinned to bottom — outside the scroll wrapper so it never scrolls away.
   The Settings row is the OpenAI-style "account button" — a clearly
   bordered button at the bottom of the rail that pops a menu on click. */
.rail-section.settings{
  flex-shrink:0;
  padding:8px 0 var(--sp-md) 0;
  border-top:1px solid var(--border);
}
.rail-section.settings .policies-header{
  /* Button chrome: visible border, surface bg, rounded corners.
     Override the default policies-header padding so the row breathes
     like a button rather than a header label. */
  display:flex; align-items:center; gap:8px;
  padding:8px 10px;
  border:1px solid var(--border);
  border-radius:var(--radius-md);
  background:var(--surface);
  cursor:pointer;
  transition: background .15s, border-color .15s;
}
/* The default ::before hover halo on .policies-header conflicts with
   the new bordered look — neutralize it just for Settings. */
.rail-section.settings .policies-header::before{ display:none; }
.rail-section.settings .policies-header:hover{
  background: var(--surface-hover);
  border-color: var(--text-dim);
}
.rail-section.settings .policies-header:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:2px;
}
/* The kebab is now redundant — the whole row is the button — but we
   leave it in the DOM as the menu's logical anchor and ARIA target.
   Hide ONLY the kebab button, not its wrapper: the popup menu is a
   descendant of .section-controls, so display:none on the wrapper
   would prevent the menu from rendering even when toggled open
   (display:none propagates regardless of position:fixed). */
.rail-section.settings .section-controls .icon-btn{ display:none; }
/* Caret glyph on the right edge so the row reads as a popup-trigger,
   not a passive label. Rotates 180° when the menu is open. */
.rail-section.settings .policies-header h3{ flex:1; }
.rail-section.settings .policies-header::after{
  content:"";
  width:10px; height:10px; flex-shrink:0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%23808a99' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-size:contain; background-repeat:no-repeat;
  opacity:.7;
  transform: rotate(180deg);
  transition: transform .15s;
}
.rail-section.settings .policies-header[aria-expanded="true"]::after{
  transform: rotate(0deg);
}

/* ── Recents rail section ── */
.rail-section.recents{
  border-top:1px solid var(--border);
  margin-left:0; margin-right:calc(-1 * var(--sp-md));
  padding:8px var(--sp-md) 4px 0;
}

/* Group label between major rail sections — same uppercase, letter-
   spaced, full-width-divider treatment as the RECENT Q&A header. Used
   to bracket Model Information + Knowledge Base under "Evidence Engine". */
.rail-group-label{
  border-top:1px solid var(--border);
  margin-left:0; margin-right:calc(-1 * var(--sp-md));
  padding:8px var(--sp-md) 4px 0;
}
.rail-group-label h3{
  color:var(--text-dim); font-size:11px; font-weight:400;
  text-transform:uppercase; letter-spacing:.06em;
  margin:0;
}

/* Knowledge Base pane: breathing room between the chunks summary and
   the "Last ingest" line — they're two separate .kv blocks. The flex
   layout lives on the .pane-anim wrapper so it composes correctly with
   the grid-row pane animation below. */
#kbInfoPane > .pane-anim{
  display:flex; flex-direction:column; gap:6px;
}

/* ---------- Rail pane animation ----------
   Smoothly expand/collapse the section panes via grid-template-rows
   (modern technique: animates between 0fr and 1fr without needing a
   fixed max-height). Each pane's content is wrapped in a .pane-anim
   div so the grid trick has exactly one row to size. The [hidden]
   attribute drives the open/closed state — keeps the existing JS
   toggles working unchanged. */
#policiesPane,
#assessmentsPane,
#runsPane,
#modelInfoPane,
#kbInfoPane{
  display:grid;
  grid-template-rows:1fr;
  transition: grid-template-rows .22s ease-out;
}
#policiesPane[hidden],
#assessmentsPane[hidden],
#runsPane[hidden],
#modelInfoPane[hidden],
#kbInfoPane[hidden]{
  display:grid !important;          /* override default [hidden] -> display:none */
  grid-template-rows:0fr;
  pointer-events:none;
}
#policiesPane > .pane-anim,
#assessmentsPane > .pane-anim,
#runsPane > .pane-anim,
#modelInfoPane > .pane-anim,
#kbInfoPane > .pane-anim{
  overflow:hidden;
  min-height:0;                     /* required for the row to actually collapse */
}
@media (prefers-reduced-motion: reduce){
  #policiesPane,
  #assessmentsPane,
  #runsPane,
  #modelInfoPane,
  #kbInfoPane{ transition:none; }
}
/* The pane animation switched [hidden] panes from display:none to
   display:grid (so the row transition can run). Side effect: the pane
   now counts as a flex item inside its rail-section, so the section's
   own 12px gap renders between the header and the (zero-height) pane,
   adding visible space between section rows. Suppress the gap while
   the pane is collapsed so the rail tightens back up to its pre-
   animation rhythm. */
.rail-section:has(> [id$="Pane"][hidden]){
  gap:0;
}
.recents-header{
  display:flex; align-items:center; gap:6px;
  padding:2px 0 4px;
}
.recents-header h3{
  color:var(--text-dim); font-size:11px; font-weight:400;
  text-transform:uppercase; letter-spacing:.06em;
}
.recents-header .icon-btn{ opacity:.5; border:none; background:transparent; }
.recents-header .icon-btn:hover{ opacity:1; background:var(--surface-hover); }
.recents-list{
  list-style:none; padding:0; margin:0;
  display:flex; flex-direction:column; gap:1px;
}
.recents-list li{
  padding:5px 6px;
  border-radius:var(--radius-md);
  cursor:pointer;
  color:var(--text-dim); font-size:13px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  transition:background .15s, color .15s;
}
.recents-list li:hover{ background:var(--surface-hover); color:var(--text); }

/* Settings row (label + control) */
.settings-row{
  display:flex; align-items:center; justify-content:space-between;
  padding:6px 4px; font-size:12px; color:var(--text-dim);
}

/* center the upload controls inside the rail */
.policies .upload-row{
  justify-content: center;          /* center children */
  width: 100%;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}

/* tighten spacing so it reads like a compact toolbar */
.policies .upload-row .icon-btn.pick{ padding:8px }
.policies .upload-row #uploadBtn{
  padding:8px 12px;
  border-radius: var(--radius-md);
}

.btn-ghost{
  background:transparent;
  border:1px solid var(--border);
  color:var(--text-dim);
  border-radius: var(--radius-md);
  cursor:pointer;
  transition:background .15s ease, border-color .15s ease, color .15s ease;
}
.btn-ghost:hover{ background:var(--surface-hover); color:var(--text); border-color:var(--pea-cream-dim); }
.btn-ghost.sm{ font-size:12px; padding:4px 8px; margin-top:6px; }


/* Visible focus for all icon buttons */
.icon-btn:focus-visible {
  outline: 2px solid var(--pea-cream-dim);
  outline-offset: 2px;
  border-radius: 8px;
}

/* Upload row: we no longer display a text <input>, so remove those styles */
.upload-row input { display: none; } /* ensure hidden file input stays hidden */

/* Keep the filename text nicely aligned and clipped */
.upload-row #fileName {
  flex: 1;
  min-width: 0;              /* allows text-overflow to work in flex */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Utility + highlight */
.muted { color: var(--text-dim); }
.hl { background: rgba(243,154,76,.15); border-radius: 3px; padding: 0 2px; }

/* --- Custom Scrollbar for Manage Policies & rail --- */

/* Applies to all scrollable elements inside the rail */
.rail-scroll,
.policies #policies {
  scrollbar-gutter: stable;
}

/* Chrome, Edge, Safari */
.rail-scroll::-webkit-scrollbar,
.policies #policies::-webkit-scrollbar {
  width: 6px;
}

.rail-scroll::-webkit-scrollbar-track,
.policies #policies::-webkit-scrollbar-track {
  background: transparent;
}

.rail-scroll::-webkit-scrollbar-thumb,
.policies #policies::-webkit-scrollbar-thumb {
  background-color: var(--border);
  border-radius: 6px;
  transition: background-color 0.2s ease;
}

.rail::-webkit-scrollbar-thumb:hover,
.policies #policies::-webkit-scrollbar-thumb:hover {
  background-color: var(--pea-cream-dim);
}

/* Hide right gutter flicker on dark backgrounds */
.rail, 
.policies #policies {
  scrollbar-gutter: stable both-edges;
}

/* Askbar icon: disabled state */
.askbar .icon-btn[disabled]{
  opacity:.5;
  pointer-events:none;
}

/* Topbar hamburger contrast */
header.topbar #menuToggle { color: var(--topbar-fg); }
header.topbar #menuToggle:hover { color: var(--accent); }

/* Explicit per-theme */
html.light header.topbar #menuToggle { color: #e0fdfc; }
html.light header.topbar #menuToggle:hover { color: #65e5d5; }

html:not(.light) header.topbar #menuToggle { color: var(--text-bright); }
html:not(.light) header.topbar #menuToggle:hover { color: var(--text-bright); opacity:.9; }

/* Ensure the SVG actually inherits */
#menuToggle svg { color: currentColor; stroke: currentColor; fill: none; }

/* Safety: Topbar icon inheritance + theme colors */
.topbar .icon-btn svg { color: currentColor; stroke: currentColor; fill: none; }
/* Strip the global .icon-btn surface+border treatment for topbar icons so
   the 3 right-side actions (Coverage / Gap Tasks / System Status) read as
   clean nav icons instead of a bordered button strip. Mirrors the existing
   #menuToggle override on the left side of the bar. */
.topbar .icon-btn{
  background: transparent;
  border: none;
}
.topbar .icon-btn:hover{
  background: transparent;
  border-color: transparent;
}
html:not(.light) .topbar .icon-btn { color: var(--text-bright); }
html.light .topbar .icon-btn { color: var(--topbar-fg); }

/* Topbar theme toggle – icon only, no box */
.topbar #themeToggle {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  padding: 6px;
  margin-right: 0.5rem; /* spacing from health label */
}
.topbar #themeToggle:hover {
  background: transparent !important;
  opacity: .9;
}

/* Ensure the SVGs inherit the bar color */
.topbar #themeToggle svg {
  color: currentColor;
  stroke: currentColor;
  fill: none;
}

/* Light: snowflake should be the topbar foreground ink */
html.light .topbar #themeToggle { color: var(--topbar-fg); }

/* Dark: moon should be white */
html:not(.light) .topbar #themeToggle { color: var(--text-bright); }

/* Scoped snowflake visibility polish */
html.light header.topbar #themeToggle svg {
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.35));
}

/* Optional micro-brighten on hover for clarity */
html.light header.topbar #themeToggle:hover svg {
  filter: drop-shadow(0 0 1.5px rgba(0, 0, 0, 0.45));
}

/* Micro-animation: smooth theme fade */
body { transition: background-color 0.2s ease, color 0.2s ease; }

/* Subtle hover pulse for count pill */
@keyframes pillPulse {
  0%,100% { transform: translateY(0); }
  50%     { transform: translateY(-1px); }
}
.count-badge:hover {
  animation: pillPulse .25s ease-in-out;
}
/* Hamburger / sidebar toggle */
#menuToggle,
button#menuToggle,
header .hamburger {
  color: var(--topbar-fg);
  background: transparent;
  border: none;
  padding: 6px;
  transition: color 0.15s ease;
}

#menuToggle:hover,
header .hamburger:hover {
  color: var(--accent);
}

/* Light mode: deep navy header → snow-white icon */
html.light #menuToggle,
html.light header .hamburger {
  color: #e0fdfc;
}
html.light #menuToggle:hover,
html.light header .hamburger:hover {
  color: #65e5d5; /* aqua accent on hover */
}

/* Dark mode: restore pea-cream accent */
html:not(.light) #menuToggle,
html:not(.light) header .hamburger {
  color: var(--text-bright);
}
html:not(.light) #menuToggle:hover,
html:not(.light) header .hamburger:hover {
  color: var(--text-bright);
  opacity: 0.85;
}
/* === Dark-mode specific fixes for Askbar icon buttons === */

/* Clear (the X) — accent outline, steady border */
.askbar #clearBtn {
  color: var(--pea-cream);                 /* X color */
  background: transparent;
  border: 1px solid var(--pea-cream-dim);  /* visible border at rest */
  border-radius: var(--radius-md);
  padding: 6px;
}
.askbar #clearBtn:hover {
  background: var(--surface);              /* subtle fill */
  color: var(--pea-cream);                 /* keep accent (no white flip) */
  border-color: var(--pea-cream);          /* stronger accent on hover */
}
/* ensure SVG inherits */
.askbar #clearBtn svg { color: currentColor; stroke: currentColor; }

/* History (clock) — same accent outline behavior */
#historyBtn {
  color: var(--pea-cream);
  background: transparent;
  border: 1px solid var(--pea-cream-dim);
  border-radius: var(--radius-md);
  padding: 6px;
}
#historyBtn:hover {
  background: var(--surface);
  color: var(--pea-cream);
  border-color: var(--pea-cream);
}
#historyBtn svg { color: currentColor; stroke: currentColor; }

/* Neutralize the global hover brightening in Dark mode for these buttons
   by NOT overriding the color here; just enforce a solid border. */
#historyBtn:hover,
.askbar #clearBtn:hover {
  border-width: 1px;            /* keep visible */
  border-style: solid;
}


/* Safety: don’t let any earlier rule zero out the border on hover */
#historyBtn:hover,
.askbar #clearBtn:hover {
  border-width: 1px;            /* keep visible */
  border-style: solid;
}

/* ===== Coverage Analysis Panel ===== */
.coverage-panel[hidden]{ display:none !important; }
.coverage-panel{
  /* Same content-area framing as .assessment-panel: rail + topbar stay
     visible so the panel reads as a view, not a takeover overlay. */
  position:fixed; top:var(--topbar-h); right:0; bottom:0;
  left:var(--rail-w);
  z-index:1001;
  background:var(--bg); display:flex; flex-direction:column;
  overflow:hidden;
  transition: left .18s ease;
}
body:has(.rail.collapsed) .coverage-panel{ left:56px; }
.coverage-inner{
  display:flex; flex-direction:column; height:100%;
  width:100%; padding:16px 24px;
}
.coverage-hdr{
  display:flex; align-items:center; justify-content:space-between;
  padding:14px 0 10px; border-bottom:1px solid var(--border); flex-shrink:0;
}
.coverage-title{ font-size:16px; font-weight:650; color:var(--text-bright); }
.coverage-hdr-right{ display:flex; align-items:center; gap:16px; }
.coverage-summary{ display:flex; gap:10px; flex-wrap:wrap; }
.cov-pill{
  display:inline-flex; align-items:center; gap:5px;
  padding:3px 10px; border-radius:999px; font-size:11px;
  border:1px solid var(--border); color:var(--text-dim);
}
.cov-pill.strong{ border-color:hsl(120 50% 50%/.35); color:hsl(120 50% 65%); }
.cov-pill.partial{ border-color:hsl(48 64% 70%/.35); color:var(--pea-cream); }
.cov-pill.none   { border-color:hsl(0 80% 60%/.35);  color:hsl(0 80% 75%); }
.cov-pill .dot{ width:7px; height:7px; border-radius:50%; background:currentColor; flex-shrink:0; }

.coverage-filters{
  display:flex; gap:6px; flex-wrap:wrap; padding:10px 0 6px; flex-shrink:0;
}
.cov-fam-btn{
  padding:3px 10px; border-radius:999px; border:1px solid var(--border);
  background:transparent; color:var(--text-dim); font-size:11px; cursor:pointer;
}
.cov-fam-btn:hover{ background:var(--surface-hover); color:var(--text); }
.cov-fam-btn.active{ border-color:var(--pea-cream-dim); color:var(--pea-cream); background:hsl(48 64% 70%/.08); }

.coverage-body{ flex:1; overflow-y:auto; padding-bottom:24px; }
.coverage-body::-webkit-scrollbar{ width:6px; }
.coverage-body::-webkit-scrollbar-track{ background:transparent; }
.coverage-body::-webkit-scrollbar-thumb{ background-color:var(--border); border-radius:6px; transition:background-color .2s ease; }
.coverage-body::-webkit-scrollbar-thumb:hover{ background-color:var(--pea-cream-dim); }

.cov-family{ margin-top:16px; }
.cov-family-hdr{
  display:flex; align-items:center; gap:8px;
  font-size:12px; font-weight:650; color:var(--text-bright);
  padding:6px 0 4px; border-bottom:1px solid var(--border); margin-bottom:4px;
  cursor:pointer; user-select:none;
}
.cov-family-hdr .fam-code{
  display:inline-block; padding:1px 6px; border-radius:4px;
  background:var(--surface); font-family:monospace; font-size:11px;
}
.cov-family-hdr .fam-chevron{ margin-left:auto; color:var(--text-dim); transition:transform .15s; }
.cov-family.collapsed .fam-chevron{ transform:rotate(-90deg); }
.cov-family.collapsed .cov-ctrl-list{ display:none; }

.cov-ctrl-list{ list-style:none; padding:0; margin:0; display:grid; gap:2px; }
.cov-ctrl-row{
  display:grid; grid-template-columns:80px 1fr auto auto auto; align-items:center;
  gap:8px; padding:5px 6px; border-radius:var(--radius-sm);
}
.cov-ctrl-row:hover{ background:var(--surface-hover); }
.cov-ctrl-id{ font-family:monospace; font-size:12px; font-weight:600; color:var(--text); }
.cov-ctrl-title{ font-size:12px; color:var(--text-dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cov-ctrl-bar{ display:flex; gap:3px; align-items:center; }
.cov-ctrl-dot{ width:8px; height:8px; border-radius:50%; background:var(--border); flex-shrink:0; }
.cov-ctrl-dot.filled.strong{ background:hsl(120 50% 55%); }
.cov-ctrl-dot.filled.partial{ background:hsl(48 64% 65%); }
.cov-ctrl-ask{
  padding:2px 8px; border-radius:var(--radius-sm); font-size:11px;
  border:1px solid var(--border); background:transparent; color:var(--text-dim);
  cursor:pointer; white-space:nowrap;
}
.cov-ctrl-ask:hover{ border-color:var(--pea-cream-dim); color:var(--pea-cream); background:hsl(48 64% 70%/.08); }
.cov-ctrl-flag{
  padding:2px 8px; border-radius:var(--radius-sm); font-size:11px;
  border:1px solid var(--border); background:transparent; color:var(--text-dim);
  cursor:pointer; white-space:nowrap;
}
.cov-ctrl-flag:hover{ border-color:hsl(0 80% 60%/.5); color:hsl(0 80% 75%); background:hsl(0 80% 60%/.08); }
.cov-ctrl-flag.flagged{ border-color:hsl(48 64% 70%/.35); color:var(--pea-cream); cursor:pointer; }
.cov-ctrl-flag.flagged:hover{ border-color:hsl(0 80% 60%/.5); color:hsl(0 80% 75%); background:hsl(0 80% 60%/.08); }
.cov-ctrl-flag.flagged:hover::after{ content:" ×"; }
.cov-export-btns{ display:flex; gap:6px; align-items:center; }
.cov-export-btns .btn-ghost.sm{ margin-top:0; }

/* ===== Gap Tasks Panel ===== */
.gap-tasks-panel[hidden]{ display:none !important; }
.gap-tasks-panel{
  /* Same content-area framing as the other detail panels: rail and
     topbar stay visible. Card framing (top gap, rounded corners,
     split-view right-offset) is applied in the block at the end of
     this file alongside .assessment-panel / .coverage-panel / etc. */
  position:fixed;
  top:var(--topbar-h); right:0; bottom:0; left:var(--rail-w);
  z-index:1001;
  background:var(--bg); display:flex; flex-direction:column; overflow:hidden;
  transition:left .18s ease;
}
body:has(.rail.collapsed) .gap-tasks-panel{ left:56px; }
.gap-tasks-panel-inner{
  display:flex; flex-direction:column; height:100%;
  max-width:800px; margin:0 auto; width:100%; padding:0 16px;
}
.gap-tasks-panel-hdr{
  display:flex; align-items:center; justify-content:space-between;
  padding:14px 0 10px; border-bottom:1px solid var(--border); flex-shrink:0; gap:12px;
}
.gap-tasks-panel-title{ font-size:16px; font-weight:650; color:var(--text-bright); flex-shrink:0; }
.gap-tasks-panel-hdr-right{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.gap-tasks-panel-filters{ display:flex; gap:6px; flex-wrap:wrap; align-items:center; }
.gap-family-sep{ width:1px; height:18px; background:var(--border); flex-shrink:0; margin:0 2px; }
.gap-tasks-panel-list{
  flex:1; overflow-y:auto; padding:12px 0 24px;
}
.gap-tasks-panel-list::-webkit-scrollbar{ width:6px; }
.gap-tasks-panel-list::-webkit-scrollbar-track{ background:transparent; }
.gap-tasks-panel-list::-webkit-scrollbar-thumb{ background-color:var(--border); border-radius:6px; }
.gap-tasks-panel-list::-webkit-scrollbar-thumb:hover{ background-color:var(--pea-cream-dim); }
.gap-tasks-panel-empty{
  display:flex; align-items:center; justify-content:center;
  height:120px; color:var(--text-dim); font-size:13px; text-align:center; padding:0 16px;
}
.gap-task-card{
  display:grid;
  grid-template-columns:auto 1fr auto;
  gap:8px 10px; align-items:start;
  padding:10px 12px; margin-bottom:6px;
  border:1px solid var(--border); border-radius:var(--radius-md);
  background:var(--surface);
  transition:opacity .15s;
}
.gap-task-card.done{ opacity:.55; }
.gap-task-card input[type="checkbox"]{ margin-top:2px; cursor:pointer; }
.gap-task-card-body{ display:grid; gap:3px; }
.gap-task-card-title{
  font-weight:600; font-size:13px; color:var(--text-bright);
  display:flex; align-items:center; gap:6px; flex-wrap:wrap;
}
.gap-task-card-meta{ font-size:11px; color:var(--text-dim); }
.gap-task-card-q{ font-size:11px; color:var(--text-dim); font-style:italic; }
.gap-task-source-badge{
  display:inline-block; padding:1px 6px; border-radius:999px;
  font-size:10px; border:1px solid var(--border); color:var(--text-dim);
}
.gap-task-source-badge.matrix{ border-color:hsl(200 60% 60%/.35); color:hsl(200 60% 70%); }

/* ===== Policy Editor Panel ===== */
.policy-editor-panel[hidden]{ display:none !important; }
.policy-editor-panel{
  /* Same coordinates as .assessment-panel and the policy-view-mode panel
     — anchored below the topbar and right of the rail so the rail stays
     visible and the user doesn't have to close the editor to navigate. */
  position:fixed;
  top:var(--topbar-h); right:0; bottom:0; left:var(--rail-w);
  z-index:1001;
  background:var(--bg); display:flex; flex-direction:column; overflow:hidden;
  transition:left .18s ease;
}
body:has(.rail.collapsed) .policy-editor-panel{ left:56px; }
.policy-editor-inner{
  display:flex; flex-direction:column; height:100%;
  padding:16px 24px;
}
/* Header chrome mirrors .doc-panel-hdr so View and Edit feel like the
   same surface. Mode is signaled by the .panel-mode-pill next to the
   title (and by the EDIT-only meta strip + footer). */
.policy-editor-hdr{
  display:flex; align-items:center;
  padding:6px 0 10px; border-bottom:1px solid var(--border);
  flex-shrink:0; gap:12px;
}
.policy-editor-hdr .panel-close-btn{ margin-left:auto; flex-shrink:0; }
.policy-editor-title-wrap{
  display:flex; align-items:center; gap:8px;
  min-width:0; flex:1;
}
.policy-editor-icon{
  flex:0 0 auto; color:var(--text-dim); opacity:.85;
}
.policy-editor-title{
  font-size:16px; font-weight:650; color:var(--text-bright);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  min-width:0;
}
.policy-editor-actions{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  flex-shrink:0;
}
.policy-editor-meta{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:6px 14px;
  padding:8px 0 10px;
  font-size:11px; color:var(--text-dim);
  border-bottom:1px solid var(--border);
  flex-shrink:0;
}
.policy-editor-meta .meta-item{
  display:inline-flex; align-items:center; gap:4px;
  white-space:nowrap;
}
.policy-editor-meta .meta-item-path{
  flex:0 1 auto; min-width:0;
  max-width:100%;
}
.policy-editor-meta .meta-item-path .mono{
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.policy-editor-meta .meta-ico{
  flex:0 0 auto; opacity:.7;
}
.policy-editor-msg{ font-size:12px; color:var(--text-dim); white-space:pre-wrap; }
.policy-editor-msg.ok{ color:hsl(120 50% 60%); }
.policy-editor-msg.err{ color:hsl(0 80% 65%); }
.policy-editor-msg.warn{ color:hsl(38 90% 60%); }
.policy-editor-area{
  flex:1; resize:none; border:none; outline:none;
  background:var(--surface); color:var(--text);
  font-family:"Consolas","Menlo","Monaco",monospace;
  font-size:13px; line-height:1.6; padding:12px 16px;
  overflow-y:auto; tab-size:2;
  margin-top:10px;
  border-radius:var(--radius-md);
  scrollbar-width:thin; scrollbar-color:var(--border) transparent;
}
.policy-editor-area::-webkit-scrollbar{ width:6px; height:6px; }
.policy-editor-area::-webkit-scrollbar-track{ background:transparent; }
.policy-editor-area::-webkit-scrollbar-thumb{ background-color:var(--border); border-radius:6px; }
.policy-editor-area::-webkit-scrollbar-thumb:hover,
.policy-editor-area::-webkit-scrollbar-thumb:active{ background-color:#B3A99E; }
.policy-editor-footer{
  padding:5px 0; font-size:11px; color:var(--text-dim);
  border-top:1px solid var(--border); flex-shrink:0; min-height:24px;
  margin-top:0;
}

/* ── Shared panel-mode pill (VIEW / EDIT) ────────────────────────
   Sits next to the doc title in either panel. Compact, neutral by
   default for VIEW; warm accent for EDIT so a quick glance tells
   you the document is mutable. */
.panel-mode-pill{
  display:inline-flex; align-items:center;
  padding:2px 8px; border-radius:999px;
  font-size:10px; font-weight:600; letter-spacing:.06em;
  text-transform:uppercase;
  border:1px solid var(--border);
  background:var(--surface-hover);
  color:var(--text-dim);
  flex-shrink:0;
}
.panel-mode-pill.view{
  /* Neutral — just confirms which mode you're in */
}
.panel-mode-pill.edit{
  border-color: hsl(38 90% 55% / .45);
  background: hsl(38 90% 55% / .12);
  color: hsl(38 90% 65%);
}

/* ============================================================
   Assessment Rail Section
   ============================================================ */
.rail-section.assessments{ margin-top:0; }
.assessments-list{ max-height:390px; overflow-y:auto; margin-bottom:4px; scrollbar-gutter:stable; }
.assessments-list::-webkit-scrollbar{ width:6px; }
.assessments-list::-webkit-scrollbar-track{ background:transparent; }
.assessments-list::-webkit-scrollbar-thumb{ background-color:var(--border); border-radius:6px; }
.assessments-list::-webkit-scrollbar-thumb:hover{ background-color:var(--pea-cream-dim); }
.assessments-list li{ display:flex; align-items:center; }

.assessment-rail-item{
  display:flex; flex-direction:row; align-items:flex-start; gap:4px;
  padding:6px 8px; border-radius:var(--radius-sm);
  cursor:pointer; border:none; background:transparent;
  color:var(--text); text-align:left; flex:1; min-width:0;
}
.assessment-rail-item:hover{ background:var(--surface-hover); }
.assessment-rail-item:hover .assessment-rail-item-name{ color:var(--text); }
.assessment-rail-item .asmnt-icon-wrap{
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  margin-top: 1px;
}
.assessment-rail-item .asmnt-icon-wrap > .bullet{
  position: absolute;
  top: -3px;
  right: -5px;
  margin: 0;
  z-index: 1;
}
.assessment-rail-item .asmnt-icon{
  color: var(--text-dim);
  opacity: .7;
}
.assessment-rail-item:hover .asmnt-icon{ opacity: .9; }
.assessment-rail-item-content{
  display:flex; flex-direction:column; gap:2px; flex:1; min-width:0;
}
.assessment-rail-item-name{
  font-size:12px; font-weight:400; color:var(--text-bright);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:180px;
}
.assessment-rail-item-meta{
  font-size:11px; color:var(--text-dim);
  display:flex; gap:6px; align-items:center; flex-wrap:wrap;
}
.assessment-status-pill{
  display:inline-block; padding:1px 6px; border-radius:999px; font-size:10px;
  border:1px solid var(--border);
}
.assessment-status-pill.pending{ color:var(--text-dim); }
.assessment-status-pill.running{ border-color:hsl(48 64% 70%/.5); color:var(--pea-amber); }
.assessment-status-pill.done   { border-color:hsl(120 50% 50%/.4); color:hsl(120 50% 65%); }
.assessment-status-pill.error  { border-color:hsl(0 80% 60%/.4);  color:hsl(0 80% 70%); }

/* RunJob lifecycle states — reuse the assessment pill base. Kept
   distinct from the assessment-level classes so run statuses
   (scheduled/queued/running/completed/failed/canceled) don't collide
   with assessment-level pending/running/done/error. */
.assessment-status-pill.draft    { color:var(--text-dim); font-style:italic; }
.assessment-status-pill.scheduled{ border-color:hsl(210 60% 55%/.5); color:hsl(210 70% 72%); }
.assessment-status-pill.queued   { color:var(--text-dim); }
.assessment-status-pill.completed{ border-color:hsl(120 50% 50%/.4); color:hsl(120 50% 65%); }
.assessment-status-pill.failed   { border-color:hsl(0 80% 60%/.4);  color:hsl(0 80% 70%); }
.assessment-status-pill.canceled {
  border-color:hsl(220 5% 50%/.4); color:var(--text-dim);
  text-decoration:line-through; text-decoration-thickness:1px;
}
/* When the run is still RUNNING but a cancel has been requested, the
   pill stays "running" but we render a subtle amber hint adjacent so
   users can see their click was accepted. */
.run-cancel-pending-hint{
  display:inline-block; margin-left:6px; padding:0 6px;
  border-radius:999px; font-size:10px;
  border:1px solid hsl(48 64% 70%/.5); color:var(--pea-amber);
}

/* Recurring schedules modal — reuses .asmnt-modal-* primitives. */
.schedules-modal{ min-width:480px; max-width:600px; }

/* Step 23 — Activity / overview modal.
 * Operator-focused recent-activity view: summary cards on top, flat
 * time-ordered feed below. Deliberately plain (no charts). Items link
 * into the existing schedules / run-detail surfaces. */
.activity-modal{ min-width:560px; max-width:720px; }
.activity-summary{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(140px, 1fr));
  gap:8px; margin:10px 0;
}
.activity-summary .activity-card{
  border:1px solid var(--border); border-radius:6px;
  padding:8px 10px; background:var(--surface-2, transparent);
}
.activity-summary .activity-card .activity-card-label{
  font-size:11px; color:var(--text-dim); text-transform:uppercase;
  letter-spacing:.04em;
}
.activity-summary .activity-card .activity-card-value{
  font-size:20px; font-weight:600; margin-top:2px;
}
.activity-summary .activity-card .activity-card-sub{
  font-size:11px; color:var(--text-dim); margin-top:2px;
}
.activity-summary .activity-card.alert .activity-card-value{
  color:var(--crit, #e06060);
}
.activity-controls{
  display:flex; gap:10px; align-items:flex-end; flex-wrap:wrap;
  margin:6px 0 8px;
}
.activity-control{ display:flex; flex-direction:column; gap:2px; font-size:11px; }
.activity-control select{ min-width:140px; }
.activity-status{ font-size:12px; margin:4px 0; }
/* Step 24 — small note that the actor filter is informational. Keeps
 * the UI honest about the lack of real authentication without taking
 * up real estate. */
.activity-actor-hint{
  font-size:10px; margin:4px 2px 8px; opacity:.7;
  font-style:italic;
}
/* Step 27 — saved filter presets + compact upcoming-runs panel. Both
 * are operator-convenience additions; kept small to avoid drifting
 * the Activity modal into dashboard territory. */
.activity-presets{
  display:flex; gap:8px; align-items:flex-end; flex-wrap:wrap;
  margin:2px 0 6px; padding:6px 8px;
  background:var(--surface-2, transparent);
  border:1px dashed var(--border); border-radius:6px;
}
.activity-presets .activity-control select{ min-width:200px; }
.activity-upcoming{ margin:4px 0 8px; }
.activity-upcoming > summary{
  cursor:pointer; font-size:12px; color:var(--text-dim);
  padding:3px 0;
}
.activity-upcoming > summary .count-badge{ margin-left:6px; }
.activity-upcoming-list{
  list-style:none; margin:4px 0 0; padding:0;
  border:1px solid var(--border); border-radius:6px;
  max-height:140px; overflow-y:auto;
}
.activity-upcoming-list:empty::before{
  content:"No scheduled runs queued."; color:var(--text-dim);
  display:block; padding:8px 10px; font-size:12px;
}
.activity-upcoming-list li{
  display:grid; grid-template-columns: 1fr auto auto;
  gap:8px; padding:6px 10px;
  border-bottom:1px dashed var(--border);
  font-size:12px;
}
.activity-upcoming-list li:last-child{ border-bottom:none; }
.activity-upcoming-list .up-when{
  color:var(--text-dim); font-family:var(--mono, monospace);
  white-space:nowrap;
}
.activity-upcoming-list .up-open{ font-size:11px; padding:2px 8px; }
.activity-list{
  list-style:none; margin:0; padding:0;
  max-height:360px; overflow-y:auto;
  border:1px solid var(--border); border-radius:6px;
}
.activity-list:empty::before{
  content:"No recent activity."; color:var(--text-dim);
  display:block; padding:14px; text-align:center; font-size:12px;
}
.activity-list li{
  display:grid;
  grid-template-columns: auto 1fr auto;
  gap:8px; padding:8px 10px;
  border-bottom:1px dashed var(--border);
}
.activity-list li:last-child{ border-bottom:none; }
.activity-list .act-when{
  color:var(--text-dim); font-family:var(--mono, monospace);
  font-size:11px; align-self:center; white-space:nowrap;
}
.activity-list .act-main{ min-width:0; }
.activity-list .act-main .act-type{
  display:inline-block; padding:1px 6px; border-radius:999px;
  border:1px solid var(--border); font-size:10px;
  text-transform:uppercase; letter-spacing:.04em; margin-right:6px;
}
.activity-list .act-main .act-type.t-run_failed,
.activity-list .act-main .act-type.t-delivery_failed{
  color:var(--crit, #e06060); border-color:var(--crit, #e06060);
}
.activity-list .act-main .act-type.t-run_completed,
.activity-list .act-main .act-type.t-delivery_delivered{
  color:var(--ok, #4caf50); border-color:var(--ok, #4caf50);
}
.activity-list .act-main .act-summary{ font-size:13px; }
.activity-list .act-main .act-sub{
  font-size:11px; color:var(--text-dim); margin-top:2px;
  display:flex; gap:8px; flex-wrap:wrap;
}
.activity-list .act-main .act-sub .act-actor{
  font-family:var(--mono, monospace); opacity:.8;
}
.activity-list .act-actions{
  display:flex; gap:4px; align-items:center;
}
.activity-list .act-actions button{
  font-size:11px; padding:2px 8px;
}
.asmnt-modal-subtitle{ font-size:13px; margin:12px 0 6px; }

.schedules-list{
  max-height:260px; overflow-y:auto;
  border:1px solid var(--border); border-radius:6px;
  margin:8px 0;
}
.schedules-list:empty::before{
  content:"No recurring schedules yet.";
  display:block; padding:12px; color:var(--text-dim); font-size:12px;
}
.schedule-row{
  display:grid;
  /* Added a leading auto column for the batch-select checkbox
     introduced in step 17. */
  grid-template-columns: auto 1fr auto auto auto;
  align-items:center; gap:10px;
  padding:8px 10px; border-bottom:1px solid var(--border);
}
.sched-select{ width:16px; height:16px; cursor:pointer; }

/* Row under the schedules list holding "+ New" + "Batch edit" actions. */
.schedules-actions-row{
  display:flex; gap:6px; align-items:center;
  margin:8px 0;
}

/* Step-17 batch-edit modal — reuses .asmnt-modal-* primitives. */
.sched-batch-edit-modal{ min-width:480px; max-width:600px; }

/* Step-18 skip-dates UI. Compact add-row + chips list, fits inside
   the existing modal fieldset styling. */
.skip-dates-add-row{
  display:flex; gap:6px; align-items:center;
  margin:4px 0;
}
.skip-dates-add-row input[type="date"]{ flex:1 1 auto; }
.skip-dates-list{
  list-style:none; padding:0; margin:4px 0 0;
  display:flex; flex-wrap:wrap; gap:4px;
}
.skip-dates-list:empty::before{
  content:"No skip dates set.";
  color:var(--text-dim); font-size:11px;
}
.skip-dates-list li{
  display:inline-flex; align-items:center; gap:4px;
  padding:2px 8px; border-radius:999px;
  border:1px solid var(--border);
  font-size:11px; font-family:var(--mono, monospace);
}
.skip-dates-list li button{
  background:none; border:none; cursor:pointer;
  color:var(--text-dim); padding:0; font-size:14px;
  line-height:1;
}
.skip-dates-list li button:hover{ color:hsl(0 80% 72%); }

/* Small indicator on schedule rows when skips exist. */
.sched-skip-count{
  font-size:11px; color:var(--text-dim);
}

/* Step-21 skip-date bulk-add / holiday-set import panel. Lives as a
   collapsed <details> inside the skip-dates fieldset so the default
   single-date flow stays uncluttered. */
.skip-dates-bulk{
  margin-top:8px; padding:6px 0;
  border-top:1px dashed var(--border);
}
.skip-dates-bulk summary{
  cursor:pointer; user-select:none;
  font-size:11px; color:var(--text-dim);
}
.skip-dates-bulk summary::-webkit-details-marker{ display:none; }
.skip-dates-bulk summary::before{
  content:"▸ "; display:inline-block; width:1em;
}
.skip-dates-bulk[open] summary::before{ content:"▾ "; }
.skip-dates-bulk textarea{
  width:100%; font-family:var(--mono, monospace); font-size:12px;
  margin:4px 0;
}
.holiday-set-row{
  display:flex; gap:6px; align-items:center;
  margin:4px 0;
}
.holiday-set-row select{ flex:1 1 auto; }

/* Step-20 schedules filter row — compact controls above the list. */
.schedules-filter-row{
  display:flex; flex-wrap:wrap; gap:6px; align-items:center;
  margin:8px 0 6px;
}
.schedules-filter-row select{
  flex:0 0 auto; font-size:12px;
  padding:2px 6px;
}
.schedules-filter-status{
  font-size:11px; margin:0 0 6px;
}

/* Filter-chip buttons. Pressed state uses amber (matches pending-action
   treatment elsewhere) to make active filters obvious. */
.filter-chip{
  padding:2px 8px; border-radius:999px;
  border:1px solid var(--border);
  background:transparent; color:var(--text-dim);
  font-size:11px; cursor:pointer;
}
.filter-chip:hover{ color:var(--text); }
.filter-chip[aria-pressed="true"]{
  border-color:hsl(48 64% 70%/.5);
  color:var(--pea-amber, hsl(48 64% 60%));
  background:hsl(48 64% 55%/.08);
}

/* Step-19 schedule history panel inside the edit form. Uses <details>
   for collapse/expand so there's no extra JS toggle to maintain. */
.sched-history-row{
  padding:8px 10px; margin:8px 0;
}
.sched-history-row summary{
  cursor:pointer; user-select:none;
  font-size:12px; color:var(--text-dim);
}
.sched-history-row summary::-webkit-details-marker{ display:none; }
.sched-history-row summary::before{
  content:"▸ "; display:inline-block; width:1em;
}
.sched-history-row[open] summary::before{ content:"▾ "; }
.sched-history-list{
  list-style:none; padding:0; margin:6px 0 0;
  font-size:11px;
}
.sched-history-list:empty::before{
  content:"No changes recorded yet."; color:var(--text-dim);
}
.sched-history-list li{
  display:grid; grid-template-columns: auto auto 1fr auto; gap:8px;
  padding:3px 0; border-bottom:1px dashed var(--border);
}
.sched-history-list li:last-child{ border-bottom:none; }
.sched-history-list li .hist-when{ color:var(--text-dim); font-family:var(--mono, monospace); }
.sched-history-list li .hist-source{
  padding:0 6px; border-radius:999px; border:1px solid var(--border);
  font-size:10px; align-self:center;
}
.sched-history-list li .hist-summary{ color:var(--text); }
/* Step 22: actor attribution. Subtle and only shown when present —
 * rendering implies informational attribution, not a verified identity. */
.sched-history-list li .hist-actor{
  color:var(--text-dim); font-size:10px; font-family:var(--mono, monospace);
  align-self:center; opacity:.75;
}
.schedule-row:last-child{ border-bottom:none; }
.schedule-row.disabled{ opacity:.55; }
.schedule-row .sched-main{ min-width:0; }
.schedule-row .sched-name{ font-weight:600; font-size:13px; }
.schedule-row .sched-sub{
  font-size:11px; color:var(--text-dim);
  display:flex; gap:10px; flex-wrap:wrap;
}

.schedules-form{
  margin-top:10px; padding:10px;
  border:1px dashed var(--border); border-radius:6px;
}

/* Step 16: inline recent-runs panel under each schedule row. */
.sched-recent-runs{
  margin-top:8px; padding:8px 10px;
  border-top:1px solid var(--border);
  font-size:12px;
}
.sched-recent-summary{
  margin-bottom:6px; font-size:11px;
}
.sched-recent-run{
  display:flex; gap:8px; align-items:center;
  padding:3px 0;
}
.sched-recent-run .muted{ color:var(--text-dim); font-size:11px; }
.sched-runs-toggle{ margin-left:auto; }

/* Run detail panel: "Spawned by" row may contain a small inline
   button; give it breathing room. */
.run-spawned-from{ margin-right:6px; }
.sched-days{
  display:flex; flex-wrap:wrap; gap:10px;
  font-size:12px; padding:4px 0;
}
.sched-days label{ display:inline-flex; gap:4px; align-items:center; cursor:pointer; }

/* Batch modal — reuses the modal shell + field primitives. Distinct
   class so the assessment list stays compact. */
.batch-modal{ min-width:560px; max-width:720px; }

.batch-assessments-row{ margin:8px 0 12px; }
.batch-assessments-controls{
  display:flex; gap:6px; align-items:center;
  margin:4px 0 6px; flex-wrap:wrap;
}
.batch-assessments-controls input{ flex:1 1 200px; }
.batch-assessments-list{
  max-height:180px; overflow-y:auto;
  border:1px solid var(--border); border-radius:6px;
  padding:6px 8px;
}
.batch-assessments-list label{
  display:flex; gap:8px; align-items:center;
  padding:3px 0; font-size:13px; cursor:pointer;
}
.batch-assessments-list label:hover{ background:var(--surface-hover); }

/* Per-item results panel shown after submit. Keeps the modal from
   jumping layouts — displayed inline between the form and the action
   buttons so the user can still tweak + re-submit. */
.batch-results{
  border:1px solid var(--border); border-radius:6px;
  padding:10px; margin-top:10px;
  background:var(--surface-hover);
}
.batch-results-summary{ font-size:13px; margin-bottom:6px; }
.batch-results-summary .ok{ color:hsl(120 50% 65%); font-weight:600; }
.batch-results-summary .fail{ color:hsl(0 80% 72%); font-weight:600; }
.batch-results-list{
  max-height:160px; overflow-y:auto;
  font-size:12px;
}
.batch-result-row{
  display:grid; grid-template-columns: auto 1fr; gap:6px 10px;
  padding:3px 0;
}
.batch-result-row .status-created{ color:hsl(120 50% 65%); }
.batch-result-row .status-failed{ color:hsl(0 80% 72%); }
.batch-result-row .err-msg{
  grid-column:2 / -1; color:var(--text-dim); font-size:11px;
}

/* DeliveryAction states (used in the run detail panel). */
.delivery-status-pill{
  display:inline-block; padding:1px 6px; border-radius:999px; font-size:10px;
  border:1px solid var(--border);
}
.delivery-status-pill.pending  { color:var(--text-dim); }
.delivery-status-pill.delivered{ border-color:hsl(120 50% 50%/.4); color:hsl(120 50% 65%); }
.delivery-status-pill.failed   { border-color:hsl(0 80% 60%/.4);  color:hsl(0 80% 70%); }

/* Scheduled Runs rail list item — mirrors .assessment-rail-item but
   carries run-specific meta (delivery counts, artifact count). */
.run-rail-item{
  display:flex; flex-direction:row; align-items:flex-start; gap:4px;
  width:100%; min-width:0; padding:6px 8px; border-radius:6px;
  border:1px solid transparent; background:transparent;
  text-align:left; cursor:pointer; color:inherit; overflow:hidden;
}
.run-rail-item .run-icon-wrap{
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  margin-top: 1px;
}
.run-rail-item .run-icon-wrap > .bullet{
  position: absolute;
  top: -3px;
  right: -5px;
  margin: 0;
  z-index: 1;
}
.run-rail-item .run-icon{
  color: var(--text-dim);
  opacity: .7;
}
.run-rail-item:hover .run-icon{ opacity: .9; }
.run-rail-item-content{
  display:flex; flex-direction:column; gap:2px; flex:1; min-width:0;
}
.run-rail-item:hover{ background:var(--surface-hover); }
.run-rail-item:hover .run-rail-item-name{ color:var(--text); }
.run-rail-item-name{ color:var(--text-bright); font-weight:400; font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.run-rail-item-assessment{ font-size:11px; color:var(--text-dim); opacity:.7; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.run-rail-item-meta{
  display:flex; flex-wrap:wrap; gap:6px; align-items:center;
  font-size:11px; color:var(--text-dim);
}
.run-rail-item-meta .sep{ opacity:.4; }

.runs-admin-row{
  display:flex; flex-wrap:nowrap; align-items:center; gap:6px; padding:4px 8px 8px;
  min-width:0;
}

.runs-overflow-wrap{
  position:relative; flex-shrink:0;
}
.runs-overflow-menu{
  position:absolute; top:calc(100% + 4px); right:0; z-index:200;
  background:hsl(210 30% 13%); border:1px solid var(--border);
  border-radius:var(--radius-md); padding:4px;
  display:flex; flex-direction:column; gap:2px;
  min-width:140px; box-shadow:0 4px 16px hsl(0 0% 0%/.5);
}
.runs-overflow-menu[hidden]{ display:none !important; }
.runs-overflow-item{
  background:transparent; border:none; cursor:pointer;
  color:var(--text); font-size:12px; text-align:left;
  padding:6px 10px; border-radius:var(--radius-sm);
  white-space:nowrap; width:100%;
}
.runs-overflow-item:hover{ background:var(--surface-hover); color:var(--text-bright); }

/* Section-header kebab menu (Scheduled Runs). Visually identical to the
   admin-row overflow menu so operators recognize the pattern. Right-edge
   anchored under the kebab, just outside the rail-section padding. */
.runs-header-menu-wrap{
  position:relative; flex-shrink:0;
}
/* All four kebab sections (Policies, Assessments, Scheduled Runs,
   Settings) push their .section-controls to the right edge of the
   header overlay so the kebab sits at the end. */
.rail-section.scheduled-runs .section-controls,
.rail-section.assessments .section-controls,
.rail-section.policies .section-controls,
.rail-section.settings .section-controls{
  margin-left:auto;
}

/* Settings is header-only (no expandable pane), so suppress the
   icon→chevron swap on hover — the gear stays the gear. */
.rail-section.settings .nav-icon-wrap .section-icon{ opacity:1 !important; }
.rail-section.settings .nav-icon-wrap .hover-chevron{ display:none; }
.runs-header-menu{
  /* Positioned by JS on open so the menu can escape the rail's stacking
     context (avoiding the .section-controls opacity hierarchy that made
     the menu appear translucent over Model Info / Knowledge Base). */
  position:fixed; z-index:9999;
  background:hsl(210 30% 13%); border:1px solid var(--border);
  border-radius:var(--radius-md); padding:4px;
  display:flex; flex-direction:column; gap:2px;
  min-width:220px; box-shadow:0 4px 16px hsl(0 0% 0%/.5);
}
/* Visual separator between groups of menu items (e.g., Refresh utility
   above the create/manage actions). */
.runs-header-menu-divider{
  height:1px; background:var(--border); margin:4px 2px;
}
.runs-header-menu[hidden]{ display:none !important; }
.runs-header-menu-item{
  display:inline-flex; align-items:center; gap:8px;
  background:transparent; border:none; cursor:pointer;
  color:var(--text); font-size:12px; text-align:left;
  padding:6px 10px; border-radius:var(--radius-sm);
  white-space:nowrap; width:100%;
}
.runs-header-menu-item:hover{ background:var(--surface-hover); color:var(--text-bright); }
.runs-header-menu-item svg{ flex-shrink:0; opacity:.85; }
/* (Menu-open kebab pinning lives next to the kebab visibility rules near
   the .section-controls block — it targets the button directly so the
   parent wrap doesn't dim the position:fixed menu inside.) */

/* Lift the section header above the .assessment-panel (z-index 1001)
   while its kebab menu is open. .policies-header creates its own
   stacking context (position:relative; z-index:0) so the menu's inner
   z-index:9999 is otherwise trapped below the panel — raising the
   header to 1002 lets the menu render on top of the panel area. */
.policies-header:has(.runs-header-menu:not([hidden])){
  z-index:1002;
}

/* Status-chip count badge (consolidated from the old header pills). */
.run-status-chip .chip-count{
  display:inline-block; margin-left:6px;
  font-size:10px; font-weight:700;
  padding:0 5px; min-width:14px; text-align:center;
  border-radius:999px;
  background:hsl(210 12% 22%);
  color:var(--text);
  line-height:1.5;
}
.run-status-chip.active .chip-count{
  background:rgba(0,0,0,.18); color:#000;
}
.run-status-chip[data-status="failed"] .chip-count,
.run-status-chip[data-status="error"] .chip-count,
.run-status-chip[data-status="overdue"] .chip-count{
  background:var(--status-overdue); color:#fff;
}
.run-status-chip[data-status="failed"].active .chip-count,
.run-status-chip[data-status="error"].active .chip-count,
.run-status-chip[data-status="overdue"].active .chip-count{
  background:var(--status-overdue-active); color:#fff;
}
/* Policy review-status chip color cues — share the --status-* tokens
   with .file-list .bullet so the chip count badges and the per-row
   dots speak the exact same color language (amber = due soon, red =
   overdue, violet = not set, green = current/healthy). */
.run-status-chip[data-status="due-soon"] .chip-count{
  background:var(--status-due-soon); color:#fff;
}
.run-status-chip[data-status="due-soon"].active .chip-count{
  background:var(--status-due-soon-active); color:#fff;
}
.run-status-chip[data-status="not-set"] .chip-count{
  background:var(--status-not-set); color:#fff;
}
.run-status-chip[data-status="not-set"].active .chip-count{
  background:var(--status-not-set-active); color:#fff;
}
.run-status-chip[data-status="current"] .chip-count{
  background:var(--status-current); color:#fff;
}
.run-status-chip[data-status="current"].active .chip-count{
  background:var(--status-current-active); color:#fff;
}
/* Assessment + run lifecycle chips share the same palette as policies so
   the rail reads consistently. Mapping:
     pending  → violet  (waiting / not started, like "not set")
     running  → amber   (in progress, like "due soon" — needs attention)
     done     → green   (complete and healthy, like "current")
     completed → green  (run finished successfully)
   error/failed already share the overdue red rule above. */
.run-status-chip[data-status="pending"] .chip-count{
  background:var(--status-not-set); color:#fff;
}
.run-status-chip[data-status="pending"].active .chip-count{
  background:var(--status-not-set-active); color:#fff;
}
.run-status-chip[data-status="running"] .chip-count{
  background:var(--status-due-soon); color:#fff;
}
.run-status-chip[data-status="running"].active .chip-count{
  background:var(--status-due-soon-active); color:#fff;
}
.run-status-chip[data-status="done"] .chip-count,
.run-status-chip[data-status="completed"] .chip-count{
  background:var(--status-current); color:#fff;
}
.run-status-chip[data-status="done"].active .chip-count,
.run-status-chip[data-status="completed"].active .chip-count{
  background:var(--status-current-active); color:#fff;
}
/* Queued chip — waiting-to-start runs. Blue count badge distinguishes
   it from the amber "Running" (in-flight) and the violet "Pending"
   (assessment lifecycle). */
.run-status-chip[data-status="queued"] .chip-count{
  background:hsl(210 80% 55%); color:#fff;
}
.run-status-chip[data-status="queued"].active .chip-count{
  background:hsl(210 80% 42%); color:#fff;
}
/* Hide a chip's count when it's zero — keeps the row visually quiet
   when there's nothing in that bucket. */
.run-status-chip .chip-count[data-empty="true"]{ display:none; }

.run-panel-meta{
  display:flex; flex-direction:row; flex-wrap:wrap;
  gap:8px 0;
  padding:10px 16px 12px;
  border-bottom:1px solid var(--border);
}
.run-panel-meta .kv{
  display:flex; flex-direction:column; gap:3px;
  font-size:12px; min-width:0;
  /* Per-column visual separator — keeps adjacent values from blending
     into one long string of text. The first column has no left border
     so the row reads as a clean grid, not a pipe-delimited dump. */
  padding:0 16px;
  border-left:1px solid var(--border);
}
.run-panel-meta .kv:first-child{
  padding-left:0;
  border-left:none;
}
.run-panel-meta .kv .label{
  color:var(--text-dim); font-size:10px;
  text-transform:uppercase; letter-spacing:.5px;
  white-space:nowrap;
}
.run-panel-meta .kv .value{
  font-variant-numeric:tabular-nums; word-break:break-word;
  font-size:12px; color:var(--text);
  white-space:nowrap;
}
.run-panel-meta .kv .value .run-job-id{
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size:11px;
  color: var(--text-dim);
}
.run-panel-meta .kv .value .meta-date-ico{
  margin-right: 5px;
  vertical-align: -1px;
  opacity: 0.6;
  flex-shrink: 0;
}

/* ── Flag-for-review (per-question, run results) ──
   Sits at the right end of each .run-result-head row. Outline glyph
   when un-pressed; solid amber when flagged. Click target keeps
   icon-btn-style padding so the row layout stays calm. */
.run-result-head{ position:relative; }
.run-result-flag{
  margin-left:auto;
  display:inline-flex; align-items:center; justify-content:center;
  width:24px; height:24px; padding:0;
  background:transparent; border:1px solid transparent;
  border-radius:var(--radius-sm);
  color:var(--text-dim);
  cursor:pointer;
  flex-shrink:0;
  transition: color .15s, background .15s, border-color .15s;
}
.run-result-flag:hover{
  color: hsl(38 90% 60%);
  background: hsl(38 90% 60% / .08);
  border-color: hsl(38 90% 60% / .25);
}
.run-result-flag.flagged{
  color: hsl(38 90% 55%);
  background: hsl(38 90% 55% / .14);
  border-color: hsl(38 90% 55% / .45);
}
.run-result-flag.flagged:hover{
  background: hsl(38 90% 55% / .22);
}

/* "Review N flagged" pill in run panel header.
   Shows only when at least one question is flagged on the current
   run (visibility toggled via the [hidden] attribute in JS). */
.run-review-flags-btn{
  border-color: hsl(38 90% 55% / .55);
  color: hsl(38 90% 60%);
}
.run-review-flags-btn:hover{
  background: hsl(38 90% 55% / .12);
}

/* ── Flag-review modal ──
   Fixed-width centered modal listing flagged questions. Body content
   is gated by THREEP_TIER — free shows a paywall card, Plus shows
   the full per-question signal trail. */
.flag-review-modal{
  width: min(720px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  display: flex; flex-direction: column;
  padding: 0;
  overflow: hidden;
}
.flag-review-hdr{
  display:flex; align-items:center;
  padding:14px 20px 10px;
  border-bottom:1px solid var(--border);
  flex-shrink:0;
}
.flag-review-hdr .asmnt-modal-title{ flex:1; margin:0; }
.flag-review-body{
  padding:16px 20px 20px;
  overflow-y:auto;
}
.flag-review-list{
  display:flex; flex-direction:column; gap:14px;
}
.flag-review-row{
  border:1px solid var(--border);
  border-radius:var(--radius-md);
  padding:12px 14px;
  background:var(--surface);
}
.flag-review-row-head{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  margin-bottom:8px;
}
.flag-review-row-q{
  font-weight:600; font-size:13px; flex:1; min-width:0;
}
.flag-review-row-answer{
  font-size:12px; color:var(--text);
  white-space:pre-wrap; word-break:break-word;
  margin-bottom:10px;
}
.flag-review-signals{
  display:grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap:8px 16px;
  padding:8px 0;
  border-top:1px solid var(--border);
  border-bottom:1px solid var(--border);
  margin:8px 0;
}
.flag-review-signal{
  display:flex; flex-direction:column; gap:2px;
  font-size:12px; min-width:0;
}
.flag-review-signal .label{
  color:var(--text-dim); font-size:10px;
  text-transform:uppercase; letter-spacing:.5px;
  white-space:nowrap;
}
.flag-review-signal .value{
  color:var(--text); word-break:break-word;
}


.run-panel-body{ padding:12px 16px; }
.run-panel-section{ margin-bottom:18px; }
.run-panel-section h4{
  margin:0 0 8px; font-size:12px; text-transform:uppercase;
  color:var(--text-dim); letter-spacing:.5px;
}

/* Step 28 follow-up — Results review inside the run detail panel.
 * Per-question rows showing the actual answer + citations. Kept
 * compact so a 100-question assessment stays scannable. */
.run-results-body{ display:block; }
.run-results-empty{ padding:8px 0; font-size:12px; }
.run-results-meta{
  font-size:11px; margin:0 0 8px; padding-bottom:6px;
  border-bottom:1px dashed var(--border);
}
.run-results-list{
  /* No internal max-height/scroll — the outer .assessment-panel-body
     already owns the panel's vertical scroll. Capping here created a
     nested scrollbar and left the artifacts section sitting below a
     wall of whitespace. Let the list grow to its natural height and
     the artifacts naturally end up at the bottom of the panel's
     single scroll flow. */
  display:flex; flex-direction:column; gap:10px;
}
.run-result-row{
  border:1px solid var(--border); border-radius:6px;
  padding:8px 10px; background:var(--surface-2, transparent);
}
.run-result-head{
  display:flex; gap:8px; align-items:flex-start;
  margin-bottom:4px;
}
.run-result-idx{
  color:var(--text-dim); font-family:var(--mono, monospace);
  font-size:11px; min-width:3em; padding-top:2px;
}
.run-result-status{
  padding:1px 6px; border-radius:999px; border:1px solid var(--border);
  font-size:10px; text-transform:uppercase; letter-spacing:.04em;
  align-self:center;
}
.run-result-status.ok{ color:var(--ok, #4caf50); border-color:var(--ok, #4caf50); }
.run-result-status.error{ color:var(--crit, #e06060); border-color:var(--crit, #e06060); }
.run-result-status.skipped{ color:var(--text-dim); }
.run-result-question{ font-weight:600; font-size:13px; }
.run-result-answer{
  font-size:12px; white-space:pre-wrap;
  padding:4px 0 0 calc(3em + 8px);
  color:var(--text);
}
.run-result-answer-full{
  font-size:12px; white-space:pre-wrap;
  margin-top:4px;
}
.run-result-more > summary{
  font-size:11px; color:var(--text-dim); cursor:pointer;
  padding:2px 0 0 calc(3em + 8px);
}
.run-result-empty{
  font-size:11px; padding:2px 0 0 calc(3em + 8px);
}
.run-result-error{
  font-size:11px; color:var(--crit, #e06060);
  padding:4px 0 0 calc(3em + 8px);
}
.run-result-citations{
  margin-top:6px; padding-left:calc(3em + 8px);
  font-size:11px;
}
.run-result-citations > summary{
  cursor:pointer; color:var(--text-dim);
}
.run-result-citations ul{ margin:4px 0 0; padding:0 0 0 18px; }
.run-result-citations li{ margin:3px 0; }
.run-result-snippet{
  color:var(--text-dim); font-size:11px;
  white-space:pre-wrap; margin-top:2px;
}

.run-rail-results-hint{
  margin-left:auto; font-size:10px; color:var(--text-dim);
  font-style:italic; white-space:nowrap;
  display:inline-flex; align-items:center; gap:4px;
}
.run-rail-results-icon{
  flex:0 0 auto; opacity:.8;
}

.run-artifact-row, .run-delivery-row{
  display:flex; flex-wrap:wrap; gap:8px; align-items:center;
  padding:6px 8px; border:1px solid var(--border); border-radius:6px;
  margin-bottom:6px; font-size:12px;
}
.run-artifact-row a{ color:inherit; text-decoration:underline; }
.run-delivery-row .dest{ color:var(--text-dim); font-family:var(--mono, monospace); font-size:11px; }
.run-delivery-row .err  { color:hsl(0 80% 72%); font-size:11px; flex-basis:100%; }
.run-delivery-row .retry-btn{ margin-left:auto; }

.run-history-entry{
  padding:6px 8px; border-left:2px solid hsl(0 80% 60%/.4);
  margin-bottom:6px; font-size:12px; background:var(--surface-hover);
}
.run-history-entry .stage{ color:var(--text-dim); font-size:10px; }

/* Cooperative-cancel banner: visible while a cancel has been requested
   but execution hasn't reached the next safe checkpoint yet. Uses a
   subtle amber (pending-action) treatment so users can tell the click
   was accepted and something is in flight, distinct from the terminal
   gray of a finalized cancel. */
.run-cancel-banner{
  padding:10px 12px; border-radius:6px;
  background:hsl(48 64% 55%/.12);
  border:1px solid hsl(48 64% 55%/.45);
  border-left:3px solid var(--pea-amber, hsl(48 64% 60%));
}
.run-cancel-banner h4{ color:var(--pea-amber, hsl(48 64% 60%)); margin:0 0 4px; }
.run-cancel-banner p{ margin:0; font-size:12px; }

/* Scheduler status row above the runs admin buttons. Banner-style
   pill that explains what the scheduler is doing without abbreviation. */
.runs-scheduler-row{
  display:flex; padding:6px 4px 4px;
}
.scheduler-pill{
  display:inline-flex; align-items:center; gap:6px;
  padding:3px 10px; border-radius:999px; font-size:11px;
  border:1px solid var(--border); color:var(--text-dim);
  cursor:default; white-space:nowrap;
}
.scheduler-pill .scheduler-dot{
  width:6px; height:6px; border-radius:50%;
  background:var(--text-dim);
}
.scheduler-pill.on {
  border-color:hsl(120 50% 50%/.4); color:hsl(120 50% 65%);
}
.scheduler-pill.on .scheduler-dot{ background:hsl(120 50% 55%); }
.scheduler-pill.warn{
  border-color:hsl(48 64% 70%/.5); color:var(--pea-amber);
}
.scheduler-pill.warn .scheduler-dot{ background:var(--pea-amber); }
.scheduler-pill.off{
  border-color:hsl(0 40% 60%/.4); color:var(--text-dim);
}
.scheduler-pill.off .scheduler-dot{ background:hsl(0 40% 60%); }

/* "Test URL" inline result in the create-run modal. Uses the same
   delivery-status-pill colors so success/failure read consistently. */
.run-create-test-row{
  display:flex; align-items:center; gap:10px;
  margin-top:6px; flex-wrap:wrap;
}
.run-create-test-result{
  font-size:12px; padding:2px 8px; border-radius:4px;
  border:1px solid var(--border);
}
.run-create-test-result.ok{
  border-color:hsl(120 50% 50%/.4); color:hsl(120 50% 65%);
}
.run-create-test-result.fail{
  border-color:hsl(0 80% 60%/.4); color:hsl(0 80% 72%);
}

/* Delivery row: expandable attempt-history details. Matches existing
   panel typography; keeps the collapsed state compact. */
.run-delivery-details{
  margin-top:6px; font-size:11px; color:var(--text-dim);
}
.run-delivery-details summary{
  cursor:pointer; user-select:none;
  list-style:none;
}
.run-delivery-details summary::-webkit-details-marker{ display:none; }
.run-delivery-details summary::before{
  content:"▸ "; display:inline-block; width:1em; transition:transform .1s ease;
}
.run-delivery-details[open] summary::before{ content:"▾ "; }
.run-delivery-details .attempt-row{
  padding:4px 6px; margin-top:4px;
  border-left:2px solid var(--border);
  background:var(--surface-hover);
  font-family:var(--mono, monospace);
}
.run-delivery-details .dest-url{
  font-family:var(--mono, monospace); font-size:11px;
  color:var(--text-dim); word-break:break-all;
}

/* New Scheduled Run modal — reuses .asmnt-modal-* layout primitives. */
.run-create-modal{ min-width:360px; max-width:520px; }
/* The parent .asmnt-modal-fields is a 2-col grid (80px / 1fr) for
   "label | input" pairs. Fieldsets and the conditional Scheduled-for row
   are full-width sections that should span both columns rather than be
   squeezed into the right column. */
.run-create-modal .run-create-fieldset,
.run-create-modal #runCreateScheduleRow{
  grid-column: 1 / -1;
}
.run-create-fieldset{
  display:flex; flex-direction:column; gap:8px;
  border:1px solid var(--border); border-radius:6px;
  padding:10px 14px 12px;
  margin:4px 0;
}
.run-create-fieldset legend{
  font-size:11px; color:var(--text-dim);
  text-transform:uppercase; letter-spacing:.5px; padding:0 4px;
}
.run-create-radio, .run-create-check{
  display:flex; align-items:center; gap:8px;
  padding:2px 0; font-size:13px; cursor:pointer;
}
/* Tighten the gap between a label and its immediately-following input
   inside a fieldset so they read as a pair rather than two siblings. */
.run-create-fieldset > .asmnt-modal-label{ margin-bottom:-4px; }
.run-create-hint{ margin:2px 0 0; font-size:11px; }
/* Scheduled-for row: align label | datetime input on one line, hint
   spans below — mirrors the parent modal's "label | input" rhythm. */
#runCreateScheduleRow{
  display:grid; grid-template-columns:80px 1fr;
  align-items:center; gap:4px 10px;
}
#runCreateScheduleRow > .run-create-hint{
  grid-column:1 / -1; margin:0;
}
/* Conditional sub-rows inside the Delivery fieldset stack their own
   label/input/hint vertically with consistent spacing. */
#runCreateFolderRow, #runCreateHttpRow{
  display:flex; flex-direction:column; gap:6px;
}
/* The explicit display rules above (grid/flex) override the UA
   stylesheet's [hidden]→display:none, so the JS .hidden=true toggle
   was being ignored. Pin these back to display:none when hidden so
   the radio + delivery-type change handlers can actually gate
   visibility. */
#runCreateScheduleRow[hidden],
#runCreateFolderRow[hidden],
#runCreateHttpRow[hidden]{
  display: none;
}
.run-create-error{
  padding:8px 10px; margin-top:8px;
  border-radius:6px; background:hsl(0 80% 40%/.15);
  color:hsl(0 80% 78%); font-size:12px;
}
.asmnt-returned-badge{
  display:inline-block; padding:1px 6px; border-radius:999px; font-size:10px;
  border:1px solid hsl(210 60% 50%/.4); color:hsl(210 70% 70%);
}
/* .asmnt-warn-pill replaced by .rail-pill — see unified pill rules above */
.asmnt-past-due-badge{
  font-size:10px; font-weight:700; color:hsl(18 90% 65%);
  white-space:nowrap;
}
.asmnt-due-soon-badge{
  font-size:10px; font-weight:700; color:hsl(45 90% 60%);
  white-space:nowrap;
}

/* Upload form */
.assessment-upload-form{
  display:flex; flex-direction:column; gap:4px; padding:2px 0 4px;
}
.assessment-meta-input{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-sm);
  color:var(--text); font-size:13.5px; padding:4px 8px; width:100%; box-sizing:border-box;
}
.assessment-meta-input:focus{ outline:none; border-color:var(--accent); }
.assessment-meta-input.sm{ font-size:13.5px; }
.assessment-meta-row{
  display:flex; align-items:center; gap:6px;
}
.assessment-meta-label{
  font-size:11px; color:var(--text-dim); white-space:nowrap; width:52px; flex-shrink:0;
}
/* Calendar icon visible on dark background */
.assessment-meta-input[type="date"]::-webkit-calendar-picker-indicator,
.assessment-panel-meta input[type="date"]::-webkit-calendar-picker-indicator{
  filter:invert(0.7); cursor:pointer; opacity:0.8;
}
.assessment-meta-input[type="date"]::-webkit-calendar-picker-indicator:hover,
.assessment-panel-meta input[type="date"]::-webkit-calendar-picker-indicator:hover{ opacity:1; }
/* Match .policies scoped upload-row rules for .assessments */
.assessments .upload-row{
  justify-content: center;
  width: 100%;
  padding: 8px;
  margin-top: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.assessments .upload-row .icon-btn.pick{ color:var(--pea-cream); padding:8px; }
.assessments .upload-row .icon-btn.pick:hover{ color:var(--pea-cream); }
.assessments .upload-row #assessmentUploadBtn{
  padding: 8px 12px;
  border-radius: var(--radius-md);
}
.upload-row #assessmentFileName{
  flex:1; color:var(--text-dim); font-size:var(--size-sm);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* Rail run button */
.assessment-run-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:26px; height:26px; padding:0;
  border-radius:var(--radius-sm); border:1px solid var(--pea-cream-dim);
  background:transparent; color:var(--pea-cream); cursor:pointer; font-size:11px;
  flex-shrink:0; line-height:1;
}
.assessment-run-btn:hover{ background:var(--surface); }

/* ============================================================
   Assessment Results Panel (full-screen overlay)
   ============================================================ */
.assessment-panel[hidden]{ display:none !important; }
.assessment-panel{
  /* Inset from the left so the rail stays visible, and from the top so
     the topbar stays visible — the panel reads as a content-area view
     rather than an overlay that takes over the whole window. */
  position:fixed; top:var(--topbar-h); right:0; bottom:0;
  left:var(--rail-w);
  z-index:1001;
  background:var(--bg); display:flex; flex-direction:column; overflow:hidden;
  transition: left .18s ease;
}
body:has(.rail.collapsed) .assessment-panel{ left:56px; }
.assessment-panel-inner{
  display:flex; flex-direction:column; height:100%;
  width:100%; padding:16px 24px;
}
.assessment-panel-hdr{
  display:flex; align-items:center;
  padding:14px 0 10px; border-bottom:1px solid var(--border); flex-shrink:0; gap:12px;
}
.assessment-panel-title{
  font-size:16px; font-weight:650; color:var(--text-bright); flex-shrink:0;
  display:inline-flex; align-items:center; gap:8px;
}
.assessment-panel-title .panel-title-icon{
  flex-shrink:0; opacity:.85;
}
.assessment-panel-hdr-right{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.assessment-panel-progress{ font-size:12px; }
.assessment-panel-hdr .panel-close-btn{ margin-left:auto; flex-shrink:0; }

/* Editable metadata bar */
.assessment-panel-meta{
  display:flex; gap:0; flex-wrap:nowrap; padding:8px 0 6px;
  border-bottom:1px solid var(--border); flex-shrink:0; overflow:hidden;
}
.assessment-meta-field{
  display:flex; align-items:center; gap:6px;
  padding:4px 12px 4px 0; margin-right:12px; font-size:12px;
}
.assessment-meta-field label{
  color:var(--text-dim); white-space:nowrap; margin:0;
}
.assessment-meta-field input{
  background:transparent; border:none; border-bottom:1px solid transparent;
  color:var(--text); font-size:12px; padding:1px 4px; min-width:80px; max-width:200px;
  border-radius:0;
}
.assessment-meta-field input:hover{ border-bottom-color:var(--border); }
.assessment-meta-field input:focus{
  outline:none; border-bottom-color:var(--accent); background:var(--surface);
  border-radius:var(--radius-sm) var(--radius-sm) 0 0;
}

/* Progress bar */
.assessment-progress-bar{
  height:3px; background:var(--surface); flex-shrink:0; margin:4px 0;
}
.assessment-progress-fill{
  height:100%; background:var(--pea-amber); border-radius:2px;
  transition:width .4s ease;
}

/* Q&A list */
.assessment-panel-body{
  flex:1; overflow-y:auto; padding:16px 0 40px;
}
.assessment-panel-body::-webkit-scrollbar{ width:6px; }
.assessment-panel-body::-webkit-scrollbar-track{ background:transparent; }
.assessment-panel-body::-webkit-scrollbar-thumb{
  background-color:var(--border); border-radius:6px;
}
.assessment-panel-body::-webkit-scrollbar-thumb:hover,
.assessment-panel-body::-webkit-scrollbar-thumb:active{ background-color:#B3A99E; }
.assessment-qa-item{
  position:relative;
  margin-bottom:24px; padding-bottom:20px; border-bottom:1px solid var(--border);
}
.assessment-qa-item:last-child{ border-bottom:none; }
.assessment-qa-num{ font-size:11px; color:var(--text-dim); margin-bottom:3px; }
.assessment-qa-question{
  font-size:13px; font-weight:600; color:var(--text-bright); margin-bottom:8px; line-height:1.4;
  /* Reserve room for the flag button anchored top-right so long
     question text doesn't run under it. */
  padding-right:48px;
}
.assessment-qa-item > .run-result-flag{
  position:absolute;
  top:0; right:16px;
}

/* Fresh-answer celebration. When a question flips from running → done
   during an active poll, _renderAssessmentQA tags that single row with
   .is-fresh and injects a .sparkle-burst. The animations are one-shots
   keyed off CSS — the next poll re-render strips .is-fresh, so each
   row celebrates exactly once. */
.assessment-qa-item.is-fresh{
  animation: aqa-halo 1.4s ease-out 1;
}
@keyframes aqa-halo{
  0%   { box-shadow: 0 0 0 0 transparent;
         background: transparent; }
  18%  { box-shadow: 0 0 24px 4px rgba(33,81,245,0.45);
         background: rgba(33,81,245,0.06); }
  100% { box-shadow: 0 0 0 0 transparent;
         background: transparent; }
}
/* Shimmer sweep across the answer text. Translucent gradient overlay
   on a pseudo-element so the underlying text stays fully readable. */
.assessment-qa-item.is-fresh .assessment-qa-answer{
  position: relative;
  overflow: hidden;
}
.assessment-qa-item.is-fresh .assessment-qa-answer::after{
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(33,81,245,0.32) 50%,
    transparent 100%);
  /* forwards: when no further poll re-render strips .is-fresh (e.g.
     the last items to transition before the assessment finishes), the
     overlay needs to park at its 100% keyframe — offscreen + opacity 0
     — instead of snapping back to its base translate(0) where the
     gradient would sit visible across the answer indefinitely. */
  animation: aqa-sweep 1.2s ease-out 1 forwards;
}
@keyframes aqa-sweep{
  0%   { transform: translateX(-100%); opacity: 0; }
  18%  { opacity: 1; }
  82%  { opacity: 1; }
  100% { transform: translateX(120%); opacity: 0; }
}
/* Respect users who've asked the OS to reduce motion — kill the
   one-shot celebration entirely. */
@media (prefers-reduced-motion: reduce){
  .assessment-qa-item.is-fresh,
  .assessment-qa-item.is-fresh .assessment-qa-answer::after{ animation: none !important; }
}
.assessment-qa-answer{ font-size:13px; color:var(--text); line-height:1.65; }
/* SECTION / TEXT / CITE structured answer labels */
.aqa-section{
  font-size:11px; font-weight:700; color:var(--accent);
  text-transform:uppercase; letter-spacing:.06em;
  margin:14px 0 4px;
}
.aqa-section:first-child{ margin-top:2px; }
.aqa-text{ margin:0 0 8px; line-height:1.6; font-size:13px; color:var(--text); }
.aqa-cite{
  font-size:11.5px; color:var(--text-dim); font-style:italic;
  padding:2px 0 2px 10px;
  border-left:2px solid var(--border);
  margin:0 0 10px;
}
.assessment-qa-pending{ font-size:12px; color:var(--text-dim); font-style:italic; }
.assessment-qa-error{ font-size:12px; color:hsl(0 80% 70%); }
.assessment-qa-cites{
  margin-top:8px; font-size:11px; color:var(--text-dim);
  border-left:2px solid var(--border); padding-left:8px; line-height:1.6;
}
.assessment-qa-running{
  display:inline-block; width:7px; height:7px; border-radius:50%;
  background:var(--pea-amber); margin-right:5px; vertical-align:middle;
  animation:asmnt-pulse 1s infinite alternate;
}
@keyframes asmnt-pulse{ from{opacity:.25} to{opacity:1} }

/* Danger button variant */
.btn-ghost.sm.danger{ color:hsl(0 80% 65%); }
.btn-ghost.sm.danger:hover{
  background:hsl(0 80% 20%/.3); border-color:hsl(0 80% 50%/.4);
  color:hsl(0 80% 75%);
}

/* ============================================================
   Assessment Upload Modal
   ============================================================ */
.asmnt-modal-backdrop[hidden]{ display:none !important; }
.asmnt-modal-backdrop{
  position:fixed; inset:0; z-index:1100;
  background:hsl(0 0% 0%/.6); display:flex;
  align-items:flex-start; justify-content:center; padding:16px;
  overflow-y:auto;
}
.asmnt-modal{
  background:hsl(210 25% 12%); border:1px solid var(--border);
  border-radius:var(--radius); padding:24px 28px; width:100%; max-width:360px;
  display:flex; flex-direction:column; gap:14px; box-shadow:0 8px 40px hsl(0 0% 0%/.6);
  margin:auto;
}
.asmnt-modal-title{ font-size:15px; font-weight:650; color:var(--text-bright); margin:0; }
.asmnt-modal-filename{ font-size:12px; margin:0; }
.asmnt-modal-fields{
  display:grid; grid-template-columns:80px 1fr; align-items:center; gap:8px 10px;
}
.asmnt-modal-label{ font-size:12px; color:var(--text-dim); }
.asmnt-modal-input{
  background:var(--bg); border:1px solid var(--border); border-radius:var(--radius-sm);
  color:var(--text); font-size:13px; padding:5px 8px; width:100%; box-sizing:border-box;
}
.asmnt-modal-input:focus{ outline:none; border-color:var(--accent); }
.asmnt-modal-input[type="date"]::-webkit-calendar-picker-indicator{
  filter:invert(0.7); cursor:pointer;
}
.asmnt-modal-actions{
  display:flex; justify-content:flex-end; gap:8px; margin-top:4px;
}
.asmnt-modal-actions button[id="asmntModalConfirm"]{
  padding:6px 16px; border:1px solid var(--pea-cream-dim);
  border-radius:var(--radius-sm); background:transparent;
  color:var(--pea-cream); cursor:pointer;
}
.asmnt-modal-actions button[id="asmntModalConfirm"]:hover{ background:var(--surface-hover); }

/* ── Bulk Policy Upload Modal ── */
.bulk-file-list[hidden], .bulk-progress-wrap[hidden]{ display:none !important; }
.bulk-upload-modal{ max-width:520px; }
.bulk-modal-header{ display:flex; align-items:center; justify-content:space-between; }
.bulk-drop-zone{
  border:1.5px dashed var(--border); border-radius:var(--radius);
  padding:24px 20px; display:flex; flex-direction:column; align-items:center;
  gap:8px; text-align:center; cursor:pointer;
  transition:border-color .15s, background .15s;
}
.bulk-drop-zone:hover, .bulk-drop-zone.drag-over{
  border-color:var(--accent); background:var(--accent-soft);
}
.bulk-drop-zone svg{ color:var(--text-dim); }
.bulk-drop-zone p{ margin:0; font-size:13px; color:var(--text-dim); }
.bulk-drop-zone code{ color:var(--text); background:var(--surface-hover); padding:1px 5px; border-radius:3px; font-size:12px; }
.bulk-drop-hint{ font-size:11px !important; opacity:.7; }
.bulk-browse-link{ background:none; border:none; padding:0; color:var(--accent); cursor:pointer; font-size:inherit; text-decoration:underline; text-underline-offset:2px; }
.bulk-file-list{ display:flex; flex-direction:column; gap:2px; max-height:240px; overflow-y:auto; scrollbar-gutter:stable; }
.bulk-file-row{
  display:grid; grid-template-columns:1fr auto auto auto;
  align-items:center; gap:8px;
  padding:5px 4px; border-radius:var(--radius-sm); font-size:12px;
}
.bulk-file-row:hover{ background:var(--surface-hover); }
.bulk-file-name{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:var(--text); }
.bulk-file-size{ color:var(--text-dim); white-space:nowrap; }
.bulk-file-chip{ font-size:10px; padding:2px 7px; border-radius:999px; border:1px solid; white-space:nowrap; line-height:1.4; }
.bulk-file-chip[data-state="queued"]   { color:var(--text-dim); border-color:var(--border); }
.bulk-file-chip[data-state="uploading"]{ color:var(--pea-cream); border-color:var(--pea-cream-dim); }
.bulk-file-chip[data-state="converting"],
.bulk-file-chip[data-state="converted"],
.bulk-file-chip[data-state="ingesting"]{ color:var(--pea-amber); border-color:var(--pea-amber-dim); }
.bulk-file-chip[data-state="done"] { color:var(--pea-green); border-color:rgba(16,185,129,.35); }
.bulk-file-chip[data-state="error"]{ color:#F87171; border-color:rgba(248,113,113,.35); }
.bulk-file-remove{
  background:none; border:none; padding:2px; color:var(--text-dim);
  cursor:pointer; line-height:1; border-radius:3px; opacity:.6;
  display:flex; align-items:center; justify-content:center;
}
.bulk-file-remove:hover{ opacity:1; color:#F87171; background:rgba(248,113,113,.1); }
.bulk-progress-wrap{ display:flex; align-items:center; gap:10px; padding-top:2px; }
.bulk-progress-track{ flex:1; height:4px; background:var(--border); border-radius:999px; overflow:hidden; }
.bulk-progress-fill{ height:100%; width:0%; background:var(--accent); border-radius:999px; transition:width .3s ease; }
.bulk-progress-label{ font-size:11px; color:var(--text-dim); white-space:nowrap; }
#bulkUploadStart{ padding:6px 16px; border:1px solid var(--pea-cream-dim); border-radius:var(--radius-sm); background:transparent; color:var(--pea-cream); cursor:pointer; }
#bulkUploadStart:hover:not(:disabled){ background:var(--surface-hover); }
#bulkUploadStart:disabled{ opacity:.4; cursor:not-allowed; }

/* ====================== Detail panel card framing ======================
   Lives at the end of the file so it wins over each panel's individual
   base rule (which sets full-bleed top/right/bottom/left). All four
   panel types — Assessments / Schedules / Coverage / Editor / Document —
   share the same workbench card treatment: dropped down from the topbar,
   inset from the rail and right edge, rounded, with a soft drop shadow. */
.assessment-panel,
.coverage-panel,
.policy-editor-panel,
.doc-panel,
.gap-tasks-panel{
  top: calc(var(--topbar-h) + var(--panel-gap));
  right: var(--panel-gap);
  bottom: var(--panel-gap);
  left: calc(var(--rail-w) + var(--panel-gap));
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  box-shadow: 0 6px 24px hsl(0 0% 0%/.45);
}
body:has(.rail.collapsed) .assessment-panel,
body:has(.rail.collapsed) .coverage-panel,
body:has(.rail.collapsed) .policy-editor-panel,
body:has(.rail.collapsed) .doc-panel,
body:has(.rail.collapsed) .gap-tasks-panel{
  left: calc(56px + var(--panel-gap));
}
/* Split-view shrinks the right edge to leave room for the ask column
   plus the inter-card gap. Wins via specificity (body.split-view + class
   = 0,2,0 vs the unscoped block above at 0,1,0). */
body.split-view .assessment-panel,
body.split-view .coverage-panel,
body.split-view .policy-editor-panel,
body.split-view .doc-panel,
body.split-view .gap-tasks-panel{
  right: calc(var(--ask-dock-w) + var(--panel-gap) * 2);
}
