/* ─────────────────────────────────────────────────────────────────────
   workspaces.css — shared styling for the reusable Workspace HUD and the
   Observation workspace (first real consumer). Deliberately reuses this
   codebase's existing visual language (dark panel background #0f172a,
   #334155/#1e293b borders, the same monospace instrument-readout font
   stack, the same red/amber/blue/green accent palette already used by the
   Instrument Panel's Scanner readout and evidence meters) rather than
   inventing a second design system — see INSTRUMENT_PANEL.md and
   CLAUDE.md's Instrument Panel milestones for the established language
   this file extends, not replaces.
   ───────────────────────────────────────────────────────────────────── */

/* ─── Workspace HUD (public/workspaces/workspace-hud.js) ─────────────── */

/* HUD visual polish pass (see CLAUDE.md) — the HUD previously read as a
   plain toolbar sitting above the list rather than an instrument sharing
   the Instrument Panel's own visual language. Brought into line with
   that language directly: the outer panel now uses the SAME "physical
   instrument" treatment index.html's own .dashboard uses (a slightly
   lighter #1e293b fill against the darker #0f172a page/list background,
   a brighter border, and a soft outer shadow + faint inset top highlight
   — not a flat card), and the meter/stat readouts move from plain text
   onto small recessed "digital display" surfaces (inset shadow, dark
   fill) matching the seven-segment/gauge readouts elsewhere in this
   codebase's Instrument Panel. Deliberately no glow/pulse/animation
   beyond what already existed (the meter fill's width transition) — per
   explicit instruction to avoid flashy effects and prioritize
   readability and hierarchy instead. Still tightened for persistent/
   sticky use (sticky-HUD follow-up pass) — every pixel of height here is
   a permanent tax on the content scrolling beneath it. */
.workspace-hud {
  position: sticky;
  top: 0;
  z-index: 3;
  background: #1e293b;
  border: 1px solid #3f5573;
  border-radius: 10px;
  padding: 0.55rem 0.95rem 0.6rem;
  margin-bottom: 0.85rem;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.workspace-hud-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid rgba(148, 163, 184, 0.16);
}

.workspace-hud-title {
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #93c5fd;
  flex-shrink: 0;
}

.workspace-hud-meter {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex: 1 1 240px;
  min-width: 180px;
}

.workspace-hud-meter-track {
  flex: 1 1 auto;
  height: 6px;
  border-radius: 3px;
  background: #0b1220;
  border: 1px solid #334155;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}

.workspace-hud-meter-fill {
  height: 100%;
  border-radius: 3px;
  transition: width 0.4s ease, background 0.3s ease;
}

/* The meter's own numeric readout as a small recessed "digital display"
   chip — same inset-shadow/dark-fill language the Instrument Panel's
   seven-segment Confidence digit and gauge value line already use — so
   it reads as an instrument reading, not plain inline text. */
.workspace-hud-meter-readout {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  flex-shrink: 0;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  background: #0b1220;
  border: 1px solid #334155;
  border-radius: 5px;
  padding: 0.15rem 0.55rem;
  box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.45);
}

/* Typography-fidelity correction (see CLAUDE.md): the percentage is now
   real seven-segment digit markup (workspace-hud.js's pctDigitsHtml()),
   not text — this rule just lays the digit spans + the static "%" out in
   a row; .hud-digit/.hud-seg-* (below) do the actual rendering. */
.workspace-hud-meter-pct {
  display: inline-flex;
  align-items: center;
  gap: 1px;
}

.hud-pct-symbol {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 0.62rem;
  font-weight: 700;
  color: #64748b;
  margin-left: 2px;
}

.workspace-hud-meter-label {
  font-size: 0.64rem;
  font-weight: 600;
  color: #94a3b8;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.workspace-hud-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: 0.4rem;
  column-gap: 0.85rem;
  margin-top: 0.5rem;
}

/* Instrument-readout refinement pass (see CLAUDE.md) — supersedes the
   prior "stacked value-over-label tile" design. That version made each
   stat feel like a small standalone card; this pass reads closer to a
   real instrument's labeled readout: a flat, "painted" label directly on
   the panel (no box, no background of its own — silkscreen text, not a
   control), immediately followed by a small recessed digital window
   holding only the number ("NEEDS REVIEW [ 2 ]"). Only .workspace-hud-
   stat-value gets a box; the label is bare text sitting on the same
   surface as the rest of the HUD panel. */
.workspace-hud-stat {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
}

.workspace-hud-stat-label {
  font-size: 0.62rem;
  font-weight: 700;
  color: #94a3b8;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

/* The recessed readout window — same dark-fill/inset-shadow "digital
   display" language as the meter readout above and the Instrument
   Panel's own seven-segment Confidence digit, deliberately darker than
   the label's own transparent background so the two read as genuinely
   different materials (painted panel vs. glass-fronted window), not just
   two differently-styled text spans.
   A genuinely FIXED width (not min-width — a min-width still let a
   1-digit value render narrower than a 3-digit one in practice, nudging
   whatever sat after it in the row, exactly what this was supposed to
   prevent) plus `flex-shrink: 0` plus `box-sizing: border-box` (so the
   40px includes padding/border, not just content) — measured against
   this exact font/size/weight to comfortably fit three tabular-nums
   digits ("999" ≈ 23px content) with room to spare. `overflow: visible`
   (the default) is deliberate: a value that somehow exceeds three digits
   spills past the window rather than being silently clipped — an honest
   failure mode for a genuinely unrealistic count, not a hidden one. */
.workspace-hud-stat-value {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
  width: 40px;
  flex-shrink: 0;
  box-sizing: border-box;
  min-height: 1.3rem;
  padding: 0.05rem 0.4rem;
  background: #060a12;
  border: 1px solid #263449;
  border-radius: 4px;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.55);
}

/* ─── Seven-segment digit readout ─────────────────────────────────────
   A 0.5x-scaled, otherwise UNCHANGED copy of index.html's own
   .sevenseg-* segment geometry (that file's Confidence readout — see
   its own CSS comment for the full per-segment design rationale this
   was derived from). Every offset/size below is exactly half the
   original's, chosen deliberately so the proportions — and therefore
   the glyph shapes — are identical to the Instrument Panel's own
   digits, just smaller, rather than a freehand redraw at a smaller
   size. workspace-hud.js's SEVEN_SEG_MAP (a direct copy of index.html's
   own map) decides which segments light up; this block only draws them.
   `hud-` prefixed so this can never collide with index.html's own
   .sevenseg-* / .seg-* class names, since both files run on the same page
   today (index.html's Instrument Panel + this HUD, in the Observation
   workspace) — two independent, same-page instruments, not one shared
   implementation, per this file's own "self-contained duplication"
   precedent (see workspace-hud.js's header comment). */
.hud-digit {
  position: relative;
  width: 8px;
  height: 15px;
  flex: 0 0 auto;
}

/* The leftmost ("hundreds") position of a percentage readout only —
   deliberately narrow, since it only ever needs to house the two right-
   hand strokes (b+c) at exactly 100%, never a full glyph. Mirrors
   .sevenseg-digit.sevenseg-partial exactly (7px at full scale -> 3.5px
   at this 0.5x scale). */
.hud-digit.hud-digit-partial {
  width: 3.5px;
}

.hud-digit .seg {
  position: absolute;
  background: var(--hud-seg-color, #eef2f7);
  opacity: 0.14;
  border-radius: 0.5px;
  transition: opacity 0.35s ease, box-shadow 0.35s ease;
}

.hud-digit .seg.lit {
  opacity: 1;
  box-shadow: 0 0 2px var(--hud-seg-color, #eef2f7);
}

.hud-seg-a { top: 0; left: 1px; width: 6px; height: 1.5px; }
.hud-seg-g { top: 6.75px; left: 1px; width: 6px; height: 1.5px; }
.hud-seg-d { bottom: 0; left: 1px; width: 6px; height: 1.5px; }
.hud-seg-f { top: 1.5px; left: 0; width: 1.5px; height: 5.25px; }
.hud-seg-b { top: 1.5px; right: 0; width: 1.5px; height: 5.25px; }
.hud-seg-e { top: 8.25px; left: 0; width: 1.5px; height: 5.25px; }
.hud-seg-c { top: 8.25px; right: 0; width: 1.5px; height: 5.25px; }

/* Text-stat variant (Interview workspace's first use — see workspace-
   hud.js's render()) — same recessed "digital display" material as
   .workspace-hud-stat-value (dark fill, inset shadow, matching border),
   just sized for a short word/phrase instead of a fixed 3-digit box, since
   a seven-segment digit has no letter glyphs to render "READY" or a use-
   case label with.

   Stable-instrument-width pass: `flex-shrink: 0` is required here (not
   just on the OUTER .workspace-hud-stat, which already has it) — this
   span is itself a flex ITEM inside .workspace-hud-stat's own flex
   container, and flex items default to shrinkable, so without this a
   caller-supplied inline `width` (see workspace-hud.js's render()) could
   still be silently squeezed below its housing size whenever the row
   runs short on space. `max-width: 260px` remains only as a ceiling for
   any FUTURE caller that renders a text stat with no explicit width —
   every current Interview stat sets its own fixed width inline, which
   this max-width must stay comfortably above (never below) or it would
   silently re-introduce the exact instability this pass exists to fix. */
.workspace-hud-stat-text {
  display: inline-flex;
  align-items: center;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  flex-shrink: 0;
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0.12rem 0.5rem;
  min-height: 1.3rem;
  box-sizing: border-box;
  background: #060a12;
  border: 1px solid #263449;
  border-radius: 4px;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.55);
}

/* Narrow viewports: relax the fixed housing back to content-sizing
   (still capped, still ellipsis-safe) — deliberate responsive wrapping
   rather than a desktop-calibrated fixed width overflowing a phone
   screen. .workspace-hud-stats already flex-wraps at the whole-stat
   (label+value pair) level, so this only affects how much horizontal
   room the value box itself claims once it's on its own line. */
@media (max-width: 640px) {
  .workspace-hud-stat-text {
    width: auto !important;
    max-width: 100%;
  }
}

.workspace-hud-subtext {
  margin-top: 0.55rem;
  font-size: 0.78rem;
  color: #94a3b8;
  line-height: 1.5;
}

/* ─── Observation workspace (public/workspaces/observation-workspace.js) ─ */

.obs-categories {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Sticky current-section/category indicator — sits directly beneath the
   sticky Workspace HUD (see workspace-hud.js's own comment on WHY applying
   `position: sticky` straight to the caller's own container, not a nested
   wrapper, is what makes sticky positioning actually work here — this
   element follows the identical rule: it's a direct sibling of
   #observation-hud-mount and .obs-categories inside the SAME container,
   never nested inside either). `top` is set dynamically in JS
   (updateSectionIndicator(), observation-workspace.js) to exactly match
   the HUD's own rendered height, so the two never overlap regardless of
   how tall the HUD happens to be at a given viewport width. Hidden by
   default (both the `hidden` attribute AND an explicit [hidden] override
   below — see CLAUDE.md's "Real bug found... .shell-dropdown-panel" note
   for why an explicit override is worth the belt-and-suspenders here) —
   only shown once JS determines there's something worth orienting around. */
.obs-section-indicator {
  position: sticky;
  z-index: 2;
  background: #0f172a;
  border-bottom: 1px solid #1e293b;
  padding: 0.3rem 0.9rem;
  margin: 0 0 0.6rem;
  font-size: 0.7rem;
  font-weight: 600;
  color: #93c5fd;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.obs-section-indicator[hidden] {
  display: none;
}

.obs-category {
  border: 1px solid #1e293b;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.015);
}

.obs-category-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.65rem 0.9rem;
  cursor: pointer;
  font-weight: 700;
  font-size: 0.9rem;
  list-style: none;
}

.obs-category-summary::-webkit-details-marker {
  display: none;
}

.obs-category-summary::before {
  content: '\25B8';
  display: inline-block;
  margin-right: 0.5rem;
  color: #64748b;
  transition: transform 0.15s ease;
}

.obs-category[open] > .obs-category-summary::before {
  transform: rotate(90deg);
}

.obs-category-name {
  flex: 1 1 auto;
}

.obs-category-count {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 0.8rem;
  color: #94a3b8;
  background: #1e293b;
  border-radius: 10px;
  padding: 0.05rem 0.55rem;
}

/* Needs Review gets its own accent so it visibly reads as the section
   deserving attention, matching the amber "deserves review" language
   already established elsewhere in this codebase (evidence meters,
   Scanner RUNNING state) — never red (not an error), never green
   (nothing here is resolved yet). Strengthened per explicit product
   direction: this is the one section a user should notice without
   feeling alarmed by it — "these are the few things CheckMyARM wasn't
   completely sure about," not a warning. A thicker, more saturated
   border plus a very faint amber wash (not a loud fill) and a slightly
   larger, bolder heading accomplish that without borrowing the red/
   "danger" language this codebase reserves for real blockers elsewhere
   (e.g. an Unsupported card). */
.obs-category[data-category="needs_review"] {
  border-width: 2px;
  border-color: rgba(245, 158, 11, 0.55);
  background: linear-gradient(180deg, rgba(245, 158, 11, 0.05), rgba(245, 158, 11, 0.015) 40%, transparent 70%);
}

.obs-category[data-category="needs_review"] .obs-category-summary {
  padding-top: 0.95rem;
  padding-bottom: 0.95rem;
}

.obs-category[data-category="needs_review"] .obs-category-name {
  color: #fbbf24;
  font-size: 1.02rem;
  font-weight: 700;
}

.obs-category[data-category="needs_review"] .obs-category-summary::before {
  color: #fbbf24;
}

.obs-category[data-category="needs_review"] .obs-category-count {
  color: #fde68a;
  background: rgba(245, 158, 11, 0.16);
  border: 1px solid rgba(245, 158, 11, 0.3);
}

.obs-category-body {
  padding: 0 0.9rem 0.85rem;
}

.obs-empty {
  padding: 0.5rem 0;
  color: #64748b;
  font-size: 0.82rem;
}

.obs-kind-group {
  margin-top: 0.5rem;
}

.obs-kind-group:first-child {
  margin-top: 0;
}

.obs-kind-heading {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #64748b;
  margin-bottom: 0.35rem;
}

.obs-kind-count {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  color: #475569;
}

/* Workload-category sub-grouping — User Installed's Applications only (see
   observation-workspace.js, renderAppCategoryGroups()). Deliberately a
   lighter, smaller heading than .obs-kind-heading — this is one level
   deeper in the hierarchy (Applications -> Development -> item rows), not
   a peer of it. */
.obs-appcat-groups {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.obs-appcat-group {
  margin-top: 0.15rem;
}

.obs-appcat-heading {
  font-size: 0.74rem;
  font-weight: 600;
  color: #93c5fd;
  margin-bottom: 0.2rem;
  padding-left: 0.1rem;
}

.obs-appcat-count {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-weight: 400;
  color: #64748b;
}

/* Compact rows, not cards — deliberately dense so large scan populations
   (100-300+ apps/devices) stay scannable rather than each item consuming
   card-sized vertical space. */
.obs-item-list {
  display: flex;
  flex-direction: column;
}

.obs-item-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.3rem;
  border-bottom: 1px solid #1e293b;
  flex-wrap: wrap;
}

.obs-item-row:last-child {
  border-bottom: none;
}

.obs-item-name {
  flex: 1 1 220px;
  min-width: 140px;
  font-size: 0.85rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.obs-item-tags {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-shrink: 0;
}

.obs-kind-tag {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  color: #93c5fd;
  background: rgba(59, 130, 246, 0.12);
}

.obs-kind-tag.device {
  color: #c4b5fd;
  background: rgba(167, 139, 250, 0.12);
}

.obs-source-tag {
  font-size: 0.65rem;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  white-space: nowrap;
}

.obs-source-tag.auto {
  color: #64748b;
  background: rgba(100, 116, 139, 0.12);
}

.obs-source-tag.override {
  color: #34d399;
  background: rgba(16, 185, 129, 0.14);
}

/* Workload-signal chips — compact, plausible-use evidence, placed BEFORE
   the kind/source/Why? group in .obs-item-tags. Never the sole carrier of
   meaning: every chip pairs a decorative icon (aria-hidden) with a
   screen-reader-only text fallback (.obs-signal-text) and an aria-label —
   never relies on color alone (strength is opacity-only, deliberately no
   scoring legend this pass). Each chip is itself an explanation target
   (see .obs-explain-popover below) — no separate button is added per
   signal. */
.obs-signal-group {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
}

.obs-signal-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.3rem;
  font-size: 0.78rem;
  line-height: 1;
  background: rgba(148, 163, 184, 0.1);
  border: 1px solid rgba(148, 163, 184, 0.25);
  border-radius: 4px;
  cursor: pointer;
  padding: 0;
}

.obs-signal-chip:hover,
.obs-signal-chip:focus-visible,
.obs-signal-chip.obs-explain-active {
  background: rgba(59, 130, 246, 0.16);
  border-color: rgba(96, 165, 250, 0.5);
  outline: none;
}

/* Strength expressed only as restrained opacity on the icon itself — not
   a color/legend system. */
.obs-signal-weak .obs-signal-icon { opacity: 0.5; }
.obs-signal-moderate .obs-signal-icon { opacity: 0.75; }
.obs-signal-strong .obs-signal-icon { opacity: 1; }

.obs-signal-icon {
  display: inline-block;
}

/* Genuine DOM text fallback (screen readers, and any environment where the
   emoji glyph itself doesn't render) — visually hidden, not merely
   decorative duplicate text. */
.obs-signal-text {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.obs-signal-overflow {
  font-size: 0.62rem;
  font-weight: 700;
  color: #93c5fd;
  width: auto;
  padding: 0 0.3rem;
}

/* Recognition Taxonomy category badges (OBSERVATION_RECOGNITION_TAXONOMY.md)
   — every category an app matched, not just the one it's grouped under.
   Deliberately its own small color, distinct from the blue/purple
   kind-tag and the amber signal-chip family, so "what kind of software is
   this" doesn't visually blend into either existing tag concept. */
.obs-category-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  font-size: 0.65rem;
  font-weight: 600;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  color: #5eead4;
  background: rgba(45, 212, 191, 0.12);
  white-space: nowrap;
}

/* Windows provenance badge — a THIRD, distinct badge family (ownership,
   not type — see renderWindowsProvenanceBadge() in
   observation-workspace.js for the full rationale). Deliberately its own
   "Windows blue" tint, different from the teal category badges above,
   the plain gray attribute badges below, and the blue/purple kind tags
   already in this row, so ownership reads as its own kind of fact rather
   than blending into any existing badge family. The four-square glyph is
   a generic motif, not a reproduction of Microsoft's registered logo —
   the accompanying "Windows" text carries the actual meaning, per
   explicit instruction to prioritize legibility over icon-only branding
   fidelity at badge size. */
.obs-provenance-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.65rem;
  font-weight: 700;
  padding: 0.12rem 0.45rem;
  border-radius: 4px;
  color: #8ec2fb;
  background: rgba(56, 132, 255, 0.14);
  border: 1px solid rgba(96, 165, 250, 0.35);
  white-space: nowrap;
}

.obs-provenance-icon {
  width: 9px;
  height: 9px;
  flex-shrink: 0;
}

.obs-provenance-icon rect {
  fill: currentColor;
}

/* Attribute badges (PWA / Microsoft Store / Startup / Pinned to Taskbar)
   — deliberately the SAME plain, text-only visual language as
   .obs-source-tag (a hard scanner-observed fact, not a category guess),
   never the colored icon-chip language categories/signals use — the
   categories-vs-attributes split OBSERVATION_RECOGNITION_TAXONOMY.md §5.3
   calls for, expressed visually. */
.obs-attribute-badge {
  font-size: 0.65rem;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  color: #94a3b8;
  background: rgba(148, 163, 184, 0.1);
  border: 1px solid rgba(148, 163, 184, 0.2);
  white-space: nowrap;
}

/* Why? affordance — now just a plain explanation TARGET (data-explain-key,
   see the singleton .obs-explain-popover below), no inline popover markup
   of its own. */
.obs-explain-btn {
  font-size: 0.65rem;
  font-weight: 600;
  color: #60a5fa;
  background: transparent;
  border: none;
  padding: 0.1rem 0.25rem;
  cursor: pointer;
  border-radius: 3px;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 2px;
}

.obs-explain-btn:hover,
.obs-explain-btn:focus-visible,
.obs-explain-btn.obs-explain-active {
  color: #93c5fd;
  background: rgba(59, 130, 246, 0.12);
  outline: none;
}

/* Singleton explanation popover — exactly ONE of these exists on the
   page (appended to document.body by the JS controller, not nested
   inside any row), positioned via JS-computed `top`/`left` against
   getBoundingClientRect() of whichever target is currently active.
   position: fixed (not absolute) is what makes that viewport-relative
   math correct without any scroll-offset arithmetic. Shown/hidden purely
   via the `hidden` attribute — content is swapped, the node itself is
   never destroyed or recreated, so opening/closing never touches
   render() or list layout. */
.obs-explain-popover {
  position: fixed;
  z-index: 200;
  width: 240px;
  background: #0b1220;
  border: 1px solid #334155;
  border-radius: 6px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.45);
  padding: 0.5rem 0.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.obs-explain-popover[hidden] {
  display: none;
}

.obs-explain-title {
  font-size: 0.76rem;
  font-weight: 700;
  color: #e2e8f0;
}

.obs-explain-row {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
}

.obs-explain-label {
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #64748b;
}

.obs-explain-value {
  font-size: 0.74rem;
  color: #e2e8f0;
  line-height: 1.35;
}

@media (max-width: 640px) {
  .obs-explain-popover {
    width: 200px;
  }
}

.obs-item-reason {
  flex: 1 1 100%;
  font-size: 0.74rem;
  color: #64748b;
  line-height: 1.4;
  padding-left: 0.05rem;
}

.obs-reclassify-select {
  flex-shrink: 0;
  background: #1e293b;
  color: #e2e8f0;
  border: 1px solid #334155;
  border-radius: 5px;
  font-size: 0.72rem;
  font-family: inherit;
  padding: 0.25rem 0.4rem;
  cursor: pointer;
}

.obs-reclassify-select:hover {
  border-color: #64748b;
}

.obs-reclassify-select:focus-visible {
  outline: 2px solid #3b82f6;
  outline-offset: 1px;
}

@media (max-width: 640px) {
  .obs-item-row {
    align-items: flex-start;
  }

  .obs-item-name {
    flex-basis: 100%;
  }
}

/* ─── Interview workspace (public/workspaces/interview-workspace.js) ──── */

.iv-step {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Entry step — three actions (Run Windows Scanner / Learn More / Continue
   Without Scanning), matching this codebase's "single-question page for a
   decision that materially changes the path" interaction rule. Deliberately
   its own small button family, not a reuse of index.html's own page-local
   .scan-cta-box/.whatnext-slot styling — this file's modules stay self-
   contained from index.html's inline script (see the file header comment
   in interview-workspace.js), so a visually-consistent-but-independently-
   defined set of classes is the correct call here, same as every other
   workspace module. */
.iv-entry-actions,
.iv-nav-row,
.iv-review-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.iv-action-btn {
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.55rem 1rem;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid #334155;
  background: #1e293b;
  color: #e2e8f0;
}

.iv-action-btn:hover {
  border-color: #64748b;
}

.iv-action-primary {
  background: #1d4ed8;
  border-color: #2563eb;
  color: #fff;
}

.iv-action-primary:hover {
  background: #2563eb;
}

.iv-action-secondary {
  background: transparent;
  color: #93c5fd;
}

.iv-action-tertiary {
  background: transparent;
  color: #94a3b8;
}

.iv-learn-more {
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid #1e293b;
  border-radius: 8px;
  padding: 0.75rem 0.9rem;
}

.iv-learn-more[hidden] {
  display: none;
}

.iv-learn-more p {
  margin: 0;
  font-size: 0.82rem;
  color: #94a3b8;
  line-height: 1.55;
}

/* A single-select question (Intended Use) — a vertical list of full-width
   option cards rather than the compact radio-list dots this codebase's
   OLDER Use-Case UI used, since each option here also carries a one-line
   description (see INTENDED_USE_DESCRIPTIONS in interview-workspace.js). */
.iv-option-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.iv-option-btn {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  text-align: left;
  padding: 0.7rem 0.9rem;
  border-radius: 8px;
  border: 1px solid #334155;
  background: rgba(255, 255, 255, 0.015);
  color: #e2e8f0;
  cursor: pointer;
}

.iv-option-btn:hover {
  border-color: #64748b;
}

.iv-option-btn.selected {
  border-color: #3b82f6;
  background: rgba(59, 130, 246, 0.12);
}

.iv-option-label {
  font-size: 0.9rem;
  font-weight: 700;
}

.iv-option-desc {
  font-size: 0.78rem;
  color: #94a3b8;
}

/* Full-Replacement baseline shortcut card — a deliberately prominent,
   distinct surface (teal accent, matching this codebase's existing
   "supported/resolved" tint elsewhere — see report.html's .badge.supported)
   so it reads as a genuine shortcut offer, not just another option. */
.iv-baseline-card {
  border: 1px solid rgba(45, 212, 191, 0.35);
  background: rgba(45, 212, 191, 0.07);
  border-radius: 8px;
  padding: 0.85rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.iv-baseline-title {
  font-size: 0.92rem;
  font-weight: 700;
  color: #5eead4;
}

.iv-baseline-desc {
  font-size: 0.8rem;
  color: #94a3b8;
  line-height: 1.5;
}

.iv-baseline-card .iv-action-btn {
  align-self: flex-start;
}

/* Workload domains / expectation modifiers — compact GROUPED rows (the
   brief's own "present related questions together in compact groups"),
   never one question per screen. */
.iv-domain-list {
  display: flex;
  flex-direction: column;
}

.iv-domain-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.55rem 0.1rem;
  border-bottom: 1px solid #1e293b;
}

.iv-domain-row:last-child {
  border-bottom: none;
}

.iv-domain-row.iv-deferred {
  opacity: 0.55;
}

.iv-domain-label {
  flex: 1 1 240px;
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.iv-suggested-tag {
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #5eead4;
  background: rgba(45, 212, 191, 0.14);
  border-radius: 4px;
  padding: 0.08rem 0.4rem;
}

.iv-deferred-tag {
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #94a3b8;
  background: rgba(148, 163, 184, 0.12);
  border-radius: 4px;
  padding: 0.08rem 0.4rem;
}

.iv-provenance-note {
  display: block;
  font-size: 0.72rem;
  color: #64748b;
  font-weight: 400;
  margin-top: 0.1rem;
}

/* Three-way Yes / Occasionally / No (or Yes / Somewhat / No) response
   group — the one control shape every workload domain and expectation
   modifier row shares. */
.iv-tri-group {
  display: inline-flex;
  border: 1px solid #334155;
  border-radius: 6px;
  overflow: hidden;
  flex-shrink: 0;
}

.iv-tri-btn {
  font-size: 0.76rem;
  font-weight: 600;
  padding: 0.35rem 0.65rem;
  background: #0f172a;
  color: #94a3b8;
  border: none;
  border-right: 1px solid #334155;
  cursor: pointer;
}

.iv-tri-btn:last-child {
  border-right: none;
}

.iv-tri-btn:hover {
  background: #1e293b;
  color: #e2e8f0;
}

.iv-tri-btn.selected {
  background: #1d4ed8;
  color: #fff;
}

.iv-skip-link {
  align-self: flex-start;
  font-size: 0.76rem;
  font-weight: 600;
  color: #60a5fa;
  background: transparent;
  border: none;
  padding: 0.2rem 0;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
}

/* Back / Continue — every non-Review step ends with this row. */
.iv-nav-row {
  justify-content: space-between;
  border-top: 1px solid #1e293b;
  padding-top: 0.85rem;
}

.iv-nav-btn {
  font-size: 0.85rem;
  font-weight: 700;
  padding: 0.55rem 1.1rem;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid #334155;
  background: #1e293b;
  color: #e2e8f0;
}

.iv-nav-back {
  background: transparent;
  color: #94a3b8;
}

.iv-nav-continue {
  background: #1d4ed8;
  border-color: #2563eb;
  color: #fff;
  margin-left: auto;
}

.iv-nav-continue:disabled {
  background: #1e293b;
  border-color: #334155;
  color: #64748b;
  cursor: not-allowed;
}

/* Assessment Profile pass — the primary, prose-first presentation (see
   renderReviewStep() in interview-workspace.js). Deliberately plain
   paragraph typography, not a card/audit-row layout — this section's
   whole point is to read as "we understood you," not an itemized
   receipt of clicks. */
.iv-profile {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  margin-bottom: 1.1rem;
}

.iv-profile p {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.65;
  color: #cbd5e1;
}

.iv-profile-lead {
  font-size: 1.08rem !important;
  color: #e2e8f0 !important;
  font-weight: 600;
}

/* Application-themes preview ("begin introducing the categories
   Applications will use") — a distinct, gently emphasized panel so it
   reads as a genuine forward-looking preview, not just more prose.
   Reuses the same teal "resolved/supported" accent already established
   elsewhere in this file (.iv-baseline-card, .iv-suggested-tag) rather
   than inventing a new color language. */
.iv-profile-themes {
  border: 1px solid rgba(45, 212, 191, 0.3);
  background: rgba(45, 212, 191, 0.06);
  border-radius: 8px;
  padding: 0.85rem 1rem;
  margin-bottom: 1.1rem;
}

.iv-profile-themes-title {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #5eead4;
  margin-bottom: 0.55rem;
}

.iv-theme-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.6rem;
}

.iv-theme-chip {
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: rgba(45, 212, 191, 0.14);
  border: 1px solid rgba(45, 212, 191, 0.35);
  color: #99f6e4;
}

.iv-profile-note {
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.55;
  color: #94a3b8;
}

/* Detailed answers — visually SUBORDINATED, not removed (this pass's own
   "preserve Edit links and detailed answers, but visually subordinate
   them"). Collapsed by default, deliberately plainer disclosure styling
   than any other interactive control on this page, since opening it is
   optional, not part of the primary flow. */
.iv-detail-toggle {
  margin-top: 0.4rem;
  border-top: 1px solid #1e293b;
  padding-top: 0.85rem;
}

.iv-detail-toggle summary {
  cursor: pointer;
  font-size: 0.78rem;
  font-weight: 600;
  color: #64748b;
  list-style: none;
}

.iv-detail-toggle summary::-webkit-details-marker {
  display: none;
}

.iv-detail-toggle summary::before {
  content: '\25B8';
  display: inline-block;
  margin-right: 0.4rem;
  transition: transform 0.15s ease;
}

.iv-detail-toggle[open] summary::before {
  transform: rotate(90deg);
}

.iv-detail-toggle summary:hover {
  color: #94a3b8;
}

.iv-detail-body {
  margin-top: 0.75rem;
}

/* Review step (now the collapsed "Detailed answers" section's own inner
   layout — see .iv-detail-toggle above) */
.iv-review {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.iv-review-row {
  display: grid;
  grid-template-columns: 140px 1fr auto;
  gap: 0.75rem;
  align-items: start;
  padding: 0.7rem 0.1rem;
  border-bottom: 1px solid #1e293b;
}

.iv-review-row:last-child {
  border-bottom: none;
}

.iv-review-label {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #64748b;
  padding-top: 0.15rem;
}

.iv-review-value {
  font-size: 0.85rem;
  color: #e2e8f0;
  line-height: 1.5;
}

.iv-review-value em {
  color: #64748b;
  font-style: normal;
}

.iv-review-list {
  margin: 0;
  padding-left: 1.1rem;
}

.iv-review-list li {
  margin-bottom: 0.15rem;
}

.iv-review-note {
  font-size: 0.76rem;
  color: #94a3b8;
  margin-top: 0.2rem;
}

/* Unanswered items, named explicitly — never just a bare count (see
   unansweredListHtml() in interview-workspace.js). Deliberately a plain,
   muted note, not an amber "needs attention" treatment — an unanswered
   optional question is expected/normal now, not something to flag as a
   problem. */
.iv-unanswered-note {
  font-size: 0.76rem;
  color: #64748b;
  margin-top: 0.3rem;
  line-height: 1.5;
}

/* Top-of-Review progress summary — the one place the detailed answered/
   unanswered/total-applicable breakdown now lives, since the main HUD
   shows only a percentage (see hudConfig() in interview-workspace.js). */
.iv-progress-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  font-size: 0.78rem;
  color: #94a3b8;
  padding-bottom: 0.6rem;
  margin-bottom: 0.2rem;
  border-bottom: 1px solid #1e293b;
}

.iv-progress-summary span:first-child {
  color: #34d399;
  font-weight: 600;
}

.iv-edit-link {
  font-size: 0.76rem;
  font-weight: 600;
  color: #60a5fa;
  background: transparent;
  border: none;
  padding: 0.15rem 0.25rem;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  white-space: nowrap;
}

.iv-low-confidence-tag,
.iv-baseline-tag {
  display: inline-block;
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-radius: 4px;
  padding: 0.08rem 0.4rem;
  margin-left: 0.4rem;
}

.iv-low-confidence-tag {
  color: #fde68a;
  background: rgba(245, 158, 11, 0.16);
}

.iv-baseline-tag {
  color: #5eead4;
  background: rgba(45, 212, 191, 0.14);
}

.iv-complete-banner {
  font-size: 0.9rem;
  font-weight: 700;
  color: #34d399;
  background: rgba(16, 185, 129, 0.12);
  border: 1px solid rgba(16, 185, 129, 0.3);
  border-radius: 8px;
  padding: 0.7rem 0.9rem;
}

/* Non-blocking notices (Observation now available / scan in progress) —
   deliberately quiet, never a modal or a step of its own. */
.iv-observation-banner {
  font-size: 0.82rem;
  color: #93c5fd;
  background: rgba(59, 130, 246, 0.08);
  border: 1px solid rgba(59, 130, 246, 0.25);
  border-radius: 8px;
  padding: 0.6rem 0.85rem;
}

.iv-inline-link {
  font-size: 0.82rem;
  font-weight: 600;
  color: #93c5fd;
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
}

@media (max-width: 640px) {
  .iv-review-row {
    grid-template-columns: 1fr;
    gap: 0.3rem;
  }

  .iv-domain-row {
    flex-direction: column;
    align-items: flex-start;
  }

  /* .iv-domain-label's flex-basis (240px) is a WIDTH hint for the default
     row layout — reused unmodified as a flex-basis under column direction,
     it's reinterpreted as a HEIGHT hint instead, producing a ~240px-tall
     label. Reset to auto here so column layout sizes the label by its own
     content, the same real bug this comment exists to prevent
     reintroducing. */
  .iv-domain-label {
    flex-basis: auto;
  }
}

/* ─── Applications workspace (public/workspaces/applications-workspace.js)
   Deliberately reuses Observation's own .obs-category/.obs-category-
   summary/.obs-category-body/.obs-item-row/.obs-item-name/.obs-item-tags/
   .obs-category-badge/.obs-empty classes verbatim for the category/row
   shell (same collapsible-category-of-item-rows shape, same visual
   language) and Interview's .iv-tri-group/.iv-tri-btn for the Important/
   Background/Irrelevant quick-action buttons — per this pass's own "do
   not duplicate infrastructure unnecessarily" instruction. Only the
   handful of concepts genuinely NEW to this workspace (the evidence-based
   suggestion line, the inline note editor, the "this category came from
   your Interview answers" tag, the Suggested Actions/Interview-gap/Add
   panels) get their own classes below. Per the Applications Refinement
   pass, this workspace no longer renders a compatibility or per-row
   category badge at all — see CLAUDE.md. ───────────────────────────── */

.app-needs-review-heading,
.app-resolved-heading {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #93c5fd;
  margin: 1rem 0 0.5rem;
}

.app-needs-review-heading:first-of-type {
  margin-top: 0.5rem;
}

.app-item-row {
  flex-wrap: wrap;
  row-gap: 0.5rem;
}

.app-item-main {
  flex: 1 1 auto;
  min-width: 12rem;
}

/* The one sentence a Needs Review row is allowed to show — see
   buildRecommendation() in applications-workspace.js. Two tiers, matching
   the two words the workspace actually uses ("Suggested"/"Recommended") —
   deliberately a quieter blue/teal pairing, not the red/amber/green
   compatibility palette this workspace no longer shows at all. */
.app-suggestion-text {
  font-size: 0.74rem;
  margin-top: 0.15rem;
}

.app-suggestion-suggested { color: #93c5fd; }
.app-suggestion-recommended { color: #5eead4; font-weight: 600; }
/* A manual entry's just-created Important default (see commitReviewRow()/
   isDefaultPending()) — deliberately the quietest of the three tones,
   since it's explaining an already-applied default, not urging a choice
   the way "Suggested"/"Recommended" do. */
.app-suggestion-default { color: #94a3b8; font-style: italic; }

/* "Added by you" — the one per-row tag this workspace keeps (see
   manualTagHtml()) since it distinguishes a genuinely different kind of
   record, not a repeat of information the section heading already shows. */
.app-manual-tag {
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #c4b5fd;
  background: rgba(167, 139, 250, 0.14);
  border-radius: 4px;
  padding: 0.08rem 0.4rem;
  margin-left: 0.4rem;
}

/* Stated ONCE, directly above the Needs Review list (see render()'s
   relevantNoteHtml) — replaces what used to be a repeated per-category
   "From your Interview answers" badge (CLAUDE.md, Applications Final
   Polish pass, "Reduce repetitive Interview badges"). .app-category-
   relevant's border-color below is what still marks each relevant
   category individually, without repeating this same sentence next to
   every one of them. */
.app-relevant-note {
  font-size: 0.72rem;
  color: #5eead4;
  margin: 0.3rem 0 0.5rem;
}

.app-category-relevant {
  border-color: rgba(45, 212, 191, 0.3);
}

/* Inline note editor — collapsed by default (see noteToggleHtml() in
   applications-workspace.js), matching "optionally add notes... without
   unnecessary clicks": most rows never need this expanded. */
.app-note-toggle {
  font-size: 0.65rem;
  font-weight: 600;
  color: #60a5fa;
  background: transparent;
  border: none;
  padding: 0.1rem 0.25rem;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
}

.app-note-box {
  flex-basis: 100%;
  display: flex;
  gap: 0.5rem;
  margin-top: 0.3rem;
}

.app-note-box[hidden] {
  display: none;
}

.app-note-input {
  flex: 1 1 auto;
  min-height: 2.2rem;
  background: #0f172a;
  color: #e2e8f0;
  border: 1px solid #334155;
  border-radius: 5px;
  font-size: 0.78rem;
  font-family: inherit;
  padding: 0.35rem 0.5rem;
  resize: vertical;
}

.app-note-save {
  flex-shrink: 0;
  align-self: flex-start;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 0.35rem 0.7rem;
  border-radius: 5px;
  border: 1px solid #334155;
  background: #1e293b;
  color: #e2e8f0;
  cursor: pointer;
}

.app-note-save:hover {
  border-color: #64748b;
}

/* Suggested Actions — always optional, always explicit (see
   renderSuggestedActionsPanel()). A calm shelf, not an alert: same panel
   language as the workspace's own HUD (dark fill, subtle border), never a
   warning color, since nothing here is ever silently applied. */
.app-suggested-actions {
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 8px;
  padding: 0.65rem 0.85rem;
  margin: 0.75rem 0;
}

.app-suggested-actions-title {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #93c5fd;
  margin-bottom: 0.5rem;
}

.app-suggested-actions-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.app-action-btn {
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.4rem 0.75rem;
  border-radius: 6px;
  border: 1px solid #334155;
  background: #0f172a;
  color: #e2e8f0;
  cursor: pointer;
}

.app-action-btn:hover {
  border-color: #64748b;
}

.app-action-primary {
  border-color: #2dd4bf;
  color: #5eead4;
}

.app-suggested-actions-note {
  font-size: 0.72rem;
  color: #94a3b8;
  margin-top: 0.55rem;
  line-height: 1.4;
}

/* "Suggested from Your Interview" — an invitation to add something
   missing, never a list of guessed app names (see interviewGapCategories()).
   Deliberately a lighter touch than Suggested Actions — this is optional
   context, not something to act on immediately. */
.app-gap-panel {
  border: 1px dashed #334155;
  border-radius: 8px;
  padding: 0.6rem 0.85rem;
  margin: 0.75rem 0;
}

.app-gap-title {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #94a3b8;
  margin-bottom: 0.4rem;
}

.app-gap-row {
  padding: 0.3rem 0;
}

.app-gap-row-main {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.app-gap-label {
  font-weight: 600;
  font-size: 0.8rem;
  color: #e2e8f0;
}

.app-gap-text {
  font-size: 0.76rem;
  color: #94a3b8;
  flex: 1 1 auto;
}

.app-gap-add {
  font-size: 0.72rem;
  font-weight: 600;
  color: #60a5fa;
  background: transparent;
  border: none;
  padding: 0.1rem 0.25rem;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  white-space: nowrap;
}

/* Curated per-category example chips (see categoryExampleChipsHtml()) —
   small and secondary, never competing visually with the row's own "+ Add
   Application" action. */
.app-example-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.3rem;
}

.app-example-chips-label {
  font-size: 0.68rem;
  color: #64748b;
  margin-right: 0.15rem;
}

.app-example-chip {
  font-size: 0.72rem;
  color: #cbd5e1;
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
  cursor: pointer;
}

.app-example-chip:hover {
  border-color: #60a5fa;
  color: #93c5fd;
}

/* Primary Action (see CLAUDE.md, Applications Final Polish pass,
   "Reorganize the top of the workspace") — a real, solid-filled button
   rather than the previous quiet text link, so "+ Add Applications"
   visually outranks Suggested Actions' own buttons below it (which stay
   outlined/secondary — see .app-action-btn) rather than reading as an
   afterthought above a more prominent card. Collapsed by default (see
   renderAddPanel()); most review sessions never open it. */
.app-add-panel {
  margin: 0.9rem 0 0.85rem;
}

.app-add-toggle {
  font-size: 0.82rem;
  font-weight: 700;
  color: #0f172a;
  background: #2dd4bf;
  border: 1px solid #2dd4bf;
  border-radius: 6px;
  padding: 0.55rem 1.1rem;
  cursor: pointer;
}

.app-add-toggle:hover {
  background: #5eead4;
  border-color: #5eead4;
}

.app-add-form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.app-add-form[hidden] {
  display: none;
}

.app-add-textarea {
  background: #0f172a;
  color: #e2e8f0;
  border: 1px solid #334155;
  border-radius: 5px;
  font-size: 0.8rem;
  font-family: inherit;
  padding: 0.5rem 0.6rem;
  resize: vertical;
  min-height: 4.4rem;
}

.app-add-save {
  align-self: flex-start;
  flex-shrink: 0;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 0.4rem 0.75rem;
  border-radius: 5px;
  border: 1px solid #334155;
  background: #1e293b;
  color: #e2e8f0;
  cursor: pointer;
}

.app-add-save:hover {
  border-color: #64748b;
}

.app-add-save:disabled {
  opacity: 0.6;
  cursor: default;
}

.app-add-hint {
  font-size: 0.72rem;
  color: #94a3b8;
}

/* Review-and-resolution step (see renderBatchReviewPanel()) — replaces
   the add form in the same slot, same panel language as the rest of this
   workspace (dark fill, subtle border), never a separate modal/dialog. */
.app-batch-review {
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 8px;
  padding: 0.65rem 0.85rem;
  margin: 0.75rem 0;
}

.app-batch-review-title {
  font-size: 0.78rem;
  font-weight: 700;
  color: #e2e8f0;
  margin-bottom: 0.5rem;
}

.app-batch-note {
  font-size: 0.72rem;
  color: #94a3b8;
  margin-bottom: 0.4rem;
}

.app-batch-note-warning {
  color: #fbbf24;
}

.app-batch-review-rows {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0.4rem 0 0.7rem;
}

.app-batch-row {
  border: 1px solid #334155;
  border-radius: 6px;
  padding: 0.45rem 0.6rem;
  background: #0f172a;
}

.app-batch-row-already_present {
  opacity: 0.6;
}

.app-batch-include {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  cursor: pointer;
}

.app-batch-name {
  font-size: 0.82rem;
  font-weight: 600;
  color: #e2e8f0;
}

.app-batch-state {
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #93c5fd;
  background: rgba(59, 130, 246, 0.12);
  border-radius: 4px;
  padding: 0.08rem 0.4rem;
}

.app-batch-state-exact,
.app-batch-state-alias {
  color: #5eead4;
  background: rgba(45, 212, 191, 0.14);
}

.app-batch-state-fuzzy_strong,
.app-batch-state-fuzzy_ambiguous {
  color: #fbbf24;
  background: rgba(245, 158, 11, 0.14);
}

.app-batch-state-none {
  color: #94a3b8;
  background: rgba(148, 163, 184, 0.12);
}

.app-batch-state-already_present {
  color: #64748b;
  background: rgba(100, 116, 139, 0.12);
}

.app-batch-options {
  margin: 0.4rem 0 0 1.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.app-batch-option {
  font-size: 0.76rem;
  color: #cbd5e1;
  cursor: pointer;
}

.app-batch-already-note {
  color: #64748b;
  font-style: italic;
}

.app-batch-review-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

@media (max-width: 640px) {
  .app-item-row .iv-tri-group {
    flex-basis: 100%;
  }

  .app-batch-options {
    margin-left: 0;
  }
}
