/* ────────────────────────────────────────────────────────────────────────
 * utilities.css — utility & component classes for the inline-style refactor
 * ────────────────────────────────────────────────────────────────────────
 * Pen-test 2026-05-05 finding WA-2026-05-05-02 (drop CSP `style-src
 * 'unsafe-inline'`). This stylesheet ships the class library that the
 * subsequent template refactors swap in for inline `style="..."` attributes.
 *
 * Classes are sized off the static-pattern frequency table in
 * `compliance/inline-style-audit-2026-05-05.md`. Anything in this file is
 * intentionally project-scoped (no Tailwind-style explosion of every
 * possible permutation); each rule replaces a real inline pattern that
 * occurs ≥5 times in the templates.
 *
 * Naming convention:
 *   .u-*              utility — single-purpose, low-specificity
 *   .card-*           card-shaped components
 *   .icon-circle      circular avatar / icon container
 *   .status-card      dynamic-color border card; template sets --status-color
 *
 * The "Phase 3" status-card class consumes a CSS custom property so
 * template-interpolated dynamic colors can be expressed as a single token
 * instead of a full inline declaration:
 *
 *   <div class="status-card" style="--status-color: {{ pdata.color }}">
 *
 * That keeps `style=` lean and lets the upcoming Phase 4 CSP tightening
 * pin the inline value via `'unsafe-hashes'` or move to a per-request
 * `<style nonce="…">` block.
 *
 * Loaded from templates/base.html alongside base.css, so every page in
 * the app has access to these classes.
 * ──────────────────────────────────────────────────────────────────────── */


/* ── Display ───────────────────────────────────────────────────────── */
/* Replaces inline `style="display:none"` (17 occurrences in templates). */
.u-hidden { display: none; }


/* ── Cursor ────────────────────────────────────────────────────────── */
.u-cursor-pointer { cursor: pointer; }


/* ── Vertical alignment ────────────────────────────────────────────── */
.u-valign-middle { vertical-align: middle; }


/* ── Margin scale (4 / 8 / 16 / 24 px — matches existing site scale) ── */
.u-mt-4 { margin-top:    16px; }

.u-mb-1 { margin-bottom:  4px; }
.u-mb-2 { margin-bottom:  8px; }
.u-mb-4 { margin-bottom: 16px; }
.u-mb-6 { margin-bottom: 24px; }


/* ── Color tokens ──────────────────────────────────────────────────── */
.u-color-accent { color: var(--accent); }
.u-color-text   { color: var(--text); }
.u-color-muted  { color: var(--text-muted); }


/* ── Text styles ───────────────────────────────────────────────────── */

/* Tiny muted inline-block with rotation-ready transition.
   Used by chevron / disclosure indicators — 11 occurrences. */
.u-text-tiny-muted {
  color: var(--text-muted);
  display: inline-block;
  font-size: 0.7rem;
  transition: transform .2s;
}

/* Small muted text — caption / metadata pattern (7 occurrences). */
.u-text-sm-muted {
  color: var(--text-muted);
  font-size: 0.85rem;
}

/* Semibold body text — 7 occurrences. */
.u-text-base-semibold {
  font-size: 0.9rem;
  font-weight: 600;
}

/* Section label (uppercase-style heading variant) — 6 occurrences. */
.u-section-label {
  color: var(--text-muted);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* Captions sitting right below a value with 4px breathing room. */
.u-caption-sm {
  color: var(--text-muted);
  font-size: 0.85rem;
  margin-top: 4px;
}
.u-caption-xs {
  color: var(--text-muted);
  font-size: 0.82rem;
  margin-top: 4px;
}


/* ── Flex row primitives ──────────────────────────────────────────── */

/* `align-items:center; display:flex; gap:8px` — 6 occurrences. */
.u-flex-row {
  align-items: center;
  display: flex;
  gap: 8px;
}

/* Same as .u-flex-row but tighter gap + medium weight — 11 occurrences. */
.u-flex-row-medium {
  align-items: center;
  display: flex;
  font-weight: 500;
  gap: 6px;
}

/* Heading-ish flex row with bottom margin — 5 occurrences. */
.u-flex-row-semibold-mb-2 {
  align-items: center;
  display: flex;
  font-weight: 600;
  gap: 6px;
  margin-bottom: 8px;
}


/* ── Wrappable label cells (table / list contexts) ────────────────── */
/* `max-width:NNNpx; white-space:normal; word-wrap:break-word` */
.u-wrap-220 { max-width: 220px; white-space: normal; word-wrap: break-word; }
.u-wrap-260 { max-width: 260px; white-space: normal; word-wrap: break-word; }


/* ── Sizing primitives ────────────────────────────────────────────── */
/* Severity bar / score-pill — `height:8px; width:60px` (6 occurrences). */
.u-pill-8x60 {
  height: 8px;
  width: 60px;
}


/* ── Card components ───────────────────────────────────────────────── */

/* `align-items:center; background:var(--surface,...); border-radius:10px;
   border:1px solid var(--border)` — flat card primitive (6 occurrences). */
.card-flat {
  align-items: center;
  background: var(--surface, rgba(30, 41, 59, 0.5));
  border: 1px solid var(--border);
  border-radius: 10px;
  display: flex;
}

/* Centered metric / stat card — 6 occurrences. */
.card-centered {
  background: var(--surface2);
  border-radius: 12px;
  padding: 20px;
  text-align: center;
}


/* ── Icon circle ──────────────────────────────────────────────────── */
/* Round, muted-grey background, centered icon glyph — 6 occurrences. */
.icon-circle {
  align-items: center;
  background: var(--border);
  border-radius: 50%;
  color: var(--text-muted);
  display: flex;
  flex-shrink: 0;
  justify-content: center;
}


/* ── Status card (dynamic-color via CSS custom property) ──────────── */
/* Phase 3 of the WA-2026-05-05-02 refactor. Templates set
 *   style="--status-color: {{ pdata.color }}"
 * and let CSS apply it via var() instead of interpolating a full CSS
 * declaration into the inline `style=` attribute. After Phase 4, the
 * final --status-color assignments are the only inline-style attribute
 * shape left, which is small and bounded enough to allowlist by
 * 'unsafe-hashes' or move into a per-request <style nonce="…"> block. */
.status-card {
  background: var(--surface2);
  border-left: 4px solid var(--status-color, var(--border));
  border-radius: 10px;
  padding: 16px;
}


/* ── Sentinel: zero-content rule that announces utilities loaded ──── */
/* (Useful smoke test in DevTools: getComputedStyle of `.u-hidden` →
 *  display === 'none' confirms the file shipped.) */


/* ── Additional utilities surfaced by the sample_report.html refactor ── */

/* Smaller muted text — sits between .u-text-tiny-muted and .u-text-sm-muted. */
.u-text-xs-muted   { color: var(--text-muted); font-size: 0.8rem;  }
.u-text-xs-accent  { color: var(--accent);     font-size: 0.8rem;  }

/* Inline emphasis — colored, semibold. Used for inline status callouts. */
.u-text-blue-semibold   { color: #3b82f6; font-weight: 600; }
.u-text-red-semibold    { color: #ef4444; font-weight: 600; }
.u-text-green-semibold  { color: #10a37f; font-weight: 600; }

/* Big red statistic — typically a failed-check count or risk score. */
.u-stat-red {
  color: var(--red);
  font-size: 1.8rem;
  font-weight: 700;
}

/* Severity-bar height variants (companion to .u-pill-8x60). */
.u-pill-h6 { height: 6px; }

/* Mono-style tiny text that wraps mid-token (URLs, hashes, IDs). */
.u-text-mono-tiny {
  font-size: 0.78rem;
  word-break: break-all;
}

/* Compact recommendation card — like .status-card but tighter padding /
   smaller radius. Templates set --status-color the same way. */
.status-card-sm {
  background: var(--surface2);
  border-left: 4px solid var(--status-color, var(--border));
  border-radius: 8px;
  margin-bottom: 8px;
  padding: 12px 16px;
}

/* Centered text helpers (rare but appear ≥2× in sample_report). */
.u-text-center { text-align: center; }

/* Width-0 bar fill — initial state for an animated progress bar. The
   template provides --bar-color for the fill hue; the bar's actual
   width is animated by JS and remains the only legitimate inline
   `style="width: NN%"` pattern. */
.u-bar-fill {
  background: var(--bar-color, var(--red));
  width: 0%;
}


/* ── Surfaced by the report.html refactor (Phase 2/B) ───────────────── */
.u-wordwrap-break  { word-wrap: break-word; overflow-wrap: break-word; }
.u-overflow-x-auto { overflow-x: auto; }
.u-overflow-y-none { max-height: none; }
.u-mr-1            { margin-right: 4px; }
.u-mx-2            { margin-left: 6px; margin-right: 6px; }
.u-flex-row-gap-16 { align-items: center; display: flex; gap: 16px; }

/* Reset margins for headings that sit inside compact card-like containers. */
.u-m-0           { margin: 0; }
.u-m-0-mb-3      { margin: 0 0 12px; }

/* Square-rounded icon container (40x40 px), backgrounded by --icon-bg. */
.icon-tile-40 {
  align-items: center;
  background: var(--icon-bg, rgba(59, 130, 246, 0.15));
  border-radius: 10px;
  display: flex;
  flex-shrink: 0;
  height: 40px;
  justify-content: center;
  width: 40px;
}

/* ── Phase 3 dynamic-bar shape (covers width:N% background:dynamic) ── */
/* Templates set both --bar-color and --bar-width; the class consumes
   them, so the inline style attribute is reduced to a pair of custom
   properties. Already present .u-bar-fill kept for the fixed-0% case. */
.u-bar-dyn {
  background: var(--bar-color, var(--accent));
  width: var(--bar-width, 0%);
}

/* ── Surfaced by the dashboard.html refactor (Phase 2/C) ─────────────── */
.u-text-sm           { color: var(--text);       font-size: 0.85rem; }
.u-text-sm-semibold  { color: var(--text);       font-size: 0.85rem; font-weight: 600; }
.u-caption-tiny      { color: var(--text-muted); font-size: 0.75rem; margin-top: 2px; }
.u-text-mono-78      { color: var(--text-muted); font-size: 0.78rem; }

/* Display: block helper for label + bottom-margin rows. */
.u-block-label-mb-2 {
  color: var(--text);
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: 6px;
}

/* Italic blockquote-style line. */
.u-italic-line {
  color: #f1f5f9;
  font-size: 0.92rem;
  font-style: italic;
  line-height: 1.6;
}

/* Decorative card with surface background and 400px max width. */
.card-surface-narrow {
  background: var(--surface, rgba(30, 41, 59, 0.5));
  border: 1px solid var(--border);
  border-radius: 12px;
  max-width: 400px;
  padding: 20px 24px;
  text-align: left;
}

/* ── Surfaced by the Phase 2/D-E long-tail refactor ─────────────────── */

/* Spacing — whitespace-tolerant variants (some templates wrote
   "margin-bottom: 8px" with a space; the no-space versions live above). */
.u-mb-2-v   { margin-bottom: 8px;  }
.u-mb-4-v   { margin-bottom: 16px; }
.u-mb-3     { margin-bottom: 12px; }

.u-mt-3     { margin-top: 12px; }
.u-mt-4-v   { margin-top: 16px; }

/* Tiny font-size shortcut. */
.u-text-xs        { font-size: 0.8rem; }

/* Border helpers used by api_docs / 404. */
.u-border-bottom  { border-bottom: 1px solid var(--border); }

/* Inline code-block style — bg-alt chip with mono font. */
.u-code-chip {
  background: var(--bg-alt);
  border-radius: 3px;
  font-family: var(--mono);
  padding: 2px 6px;
}

/* progress.html: 24x24 circular badge, neutral background. */
.icon-badge-24 {
  align-items: center;
  aspect-ratio: 1 / 1;
  background: var(--border);
  border-radius: 50%;
  box-sizing: border-box;
  color: var(--text-muted);
  display: flex;
  flex: 0 0 24px;
  font-size: 0.7rem;
  height: 24px;
  justify-content: center;
  line-height: 1;
  min-width: 24px;
  width: 24px;
}

/* progress.html: pipeline-step pill (flex row + bordered card). */
.pipeline-step {
  align-items: center;
  background: var(--surface, rgba(30, 41, 59, 0.5));
  border: 1px solid var(--border);
  border-radius: 10px;
  display: flex;
  gap: 10px;
  padding: 10px 14px;
  transition: all .3s;
}


/* ── Phase 2/F additions — push hash count below GFE's 8KB header limit ── */

/* Common margin/positioning singletons. */
.u-mt-0       { margin-top: 0; }
.u-my-2       { margin: 8px 0; }
.u-position-rel { position: relative; }
.u-text-center-mb-5 { text-align: center; margin-bottom: 20px; }
.u-text-center-mt-8 { text-align: center; margin-top: 32px; }
.u-mt-3-mb-0 { margin-top: 12px; }
.u-mt-5      { margin-top: 20px; }
.u-mt-5-bordertop { margin-top: 20px; border-top: 1px solid var(--border); padding-top: 16px; }
.u-mt-10     { margin-top: 40px; }
.u-mb-6-no-semi { margin-bottom: 24px; } /* paired w/ inline value w/o semicolon */
.u-mt-0-mb-3 { margin: 0 0 12px; }

/* Tooltip-style help text with dotted underline. */
.u-help-dotted {
  border-bottom: 1px dotted var(--text-muted);
  cursor: help;
}


/* Accent-hover semibold inline link (3× in dashboard footer). */
.u-link-accent-hover {
  color: var(--accent-hover);
  font-size: 0.9rem;
  font-weight: 600;
}

/* Vertical flex column for pipeline steps. */
.u-flex-col-center {
  align-items: center;
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 6px;
}

/* Compact metric heading + caption pair — used 3× each in dashboard. */
.u-metric-value {
  margin: 0;
  font-size: 1.2rem;
  font-weight: 700;
  color: #fff;
}
.u-metric-caption {
  margin: 0;
  font-size: 0.82rem;
  color: var(--text-muted);
}
.u-tiny-caption-tight {
  color: var(--text-muted);
  font-size: 13px;
  margin-top: 2px;
}

/* Standard CTA button padding pairs. */
.u-btn-padding-lg { padding: 12px 28px; }
.u-btn-padding-md { padding: 14px 36px; font-size: 1.05rem; }

/* Border-left accent (collapsible-section heading style). */
.u-section-callout {
  border-left: 3px solid #3b82f6;
  padding-left: 16px;
  margin-bottom: 24px;
}
.u-section-callout-bare {
  border-left: 3px solid #3b82f6;
  padding-left: 16px;
}

/* Animated collapse container (FAQ accordion). */
.u-collapse-hidden {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height 0.4s ease, opacity 0.4s ease, margin 0.3s ease;
  margin-top: 0;
  max-width: 680px;
  margin-left: auto;
  margin-right: auto;
}

/* 40×40 colored icon tile variants (already have icon-tile-40 with custom prop). */
.u-ml-2 { margin-left: 8px; }

/* Display:flex with column-gap variations. */
.u-flex-row-gap-12 {
  align-items: center;
  display: flex;
  gap: 12px;
  margin-bottom: 8px;
}
.u-flex-row-gap-12-flex-start {
  align-items: flex-start;
  display: flex;
  gap: 12px;
}
.u-flex-row-stretch {
  align-items: stretch;
  display: flex;
  gap: 8px;
}
.u-flex-wrap-row {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Stat-display widgets. */
.u-stat-2-5     { font-size: 2.5rem; font-weight: 700; }
.u-stat-2-5-red { font-size: 2.5rem; font-weight: 700; color: var(--red); }

/* Width singletons. */
.u-w-50 { width: 50px; }
.u-w-80 { width: 80px; }

/* Auto-fit grid layouts (responsive cards). */
.u-grid-200 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.u-grid-180 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 24px;
}

/* font-size + line-height pair used in 404. */
.u-text-1rem-loose { font-size: 1rem; line-height: 1.6; margin-bottom: 32px; }
.u-text-1-6rem-bold { font-size: 1.6rem; font-weight: 700; color: #fff; }
.u-text-1rem-bold-mb-3 { font-size: 1rem; font-weight: 700; margin: 0 0 12px; }
.u-text-1rem-bold-mb-1 { font-size: 1rem; font-weight: 700; margin: 0 0 4px; }
.u-text-1-1rem-semibold { font-size: 1.1rem; font-weight: 600; }
.u-text-1-4rem { font-size: 1.4rem; }
.u-mb-4-no-semi { margin-bottom: 16px; }

/* CTA pill with hex border (4× in 404.html). */
.u-pill-cta-blue {
  font-size: 0.88rem;
  padding: 6px 12px;
  border: 1px solid rgba(59, 130, 246, 0.2);
  border-radius: 6px;
}

/* Status text colors (more variants). */
.u-text-green-light { color: #10b981; }
.u-text-green-var { color: var(--green); }

.u-white-space-nowrap { white-space: nowrap; }


/* ── Phase 2/G additions — final pass to fit under 8KB ──────────────── */
.u-flex-row-gap-10 { align-items: center; display: flex; gap: 10px; }
.u-text-base-bold  { font-size: 1rem; font-weight: 700; }
.u-text-base-semi  { font-size: 1rem; font-weight: 600; }
.u-text-082        { font-size: 0.82rem; }
.u-text-088        { font-size: 0.88rem; }
.u-text-1-3        { font-size: 1.3rem; }
.u-text-1-8        { font-size: 1.8rem; }
.u-text-4          { font-size: 4rem; }
.u-color-red       { color: var(--red); }
.u-color-error     { color: #f87171; }
.u-color-success-light { color: #4ade80; }
.u-margin-0-auto-md { margin-top: 32px; max-width: 680px; margin-left: auto; margin-right: auto; }
.u-link-underline-tight {
  background: none;
  border: none;
  font-size: 0.82rem;
  padding: 4px 0;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.u-card-onboard {
  background: var(--surface, rgba(30,41,59,0.5));
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px;
  text-align: left;
  overflow: hidden;
}
.u-card-info {
  background: var(--surface2);
  border-radius: 12px;
  padding: 20px;
}
.u-card-fancy {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px;
  background: linear-gradient(135deg, rgba(99,102,241,0.05), rgba(16,185,129,0.05));
}
.u-form-input {
  flex: 1;
  padding: 10px 14px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 0.9rem;
}
.u-input-100 {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 14px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 0.95rem;
  transition: border-color .2s;
}
.u-text-success-tiny {
  max-width: 680px;
  margin: 12px auto 0;
  padding: 0 8px;
  text-align: center;
  color: #4ade80;
  font-size: 0.9rem;
  line-height: 1.4;
  font-weight: 600;
}
.u-flex-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.u-text-2-2-mb-2 { font-size: 2.2rem; margin-bottom: 10px; }
.u-cta-padding-md { padding: 10px 24px; font-size: 0.9rem; }
.u-cursor-disabled { cursor: not-allowed; min-width: 160px; }
.u-spinning {
  display: inline-block;
  animation: spin 2s linear infinite;
  margin-right: 8px;
}
.u-grid-3-12 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.u-flex-center-wrap {
  align-items: center;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}
.u-flex-wrap-center {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
}
.u-text-center-pad-md { text-align: center; padding: 60px 0; }
.u-cta-padding-lg-1-05 { padding: 14px 36px; font-size: 1.05rem; }
.u-text-link { color: var(--text); text-decoration: none; }
.u-success-pill {
  background: rgba(74,222,128,0.15);
  color: #4ade80;
  padding: 4px 12px;
  border-radius: 9999px;
  font-size: 0.78rem;
  font-weight: 600;
}
.u-card-success-stat {
  background: rgba(74,222,128,0.08);
  border: 1px solid rgba(74,222,128,0.2);
  border-radius: 10px;
  padding: 12px;
  text-align: center;
}
.u-card-error-stat {
  background: rgba(248,113,113,0.08);
  border: 1px solid rgba(248,113,113,0.2);
  border-radius: 10px;
  padding: 12px;
  text-align: center;
}
.u-text-1-2-bold-success { font-size: 1.2rem; font-weight: 700; color: #4ade80; }
.u-text-1-rem-success { font-weight: 700; font-size: 1.05rem; color: #4ade80; }
.u-text-1-rem-white { font-weight: 700; font-size: 1.05rem; color: #fff; }
.u-text-1-rem-bold-white { font-weight: 700; font-size: 1rem; color: #fff; }
.u-list-decimal { list-style: decimal; padding-left: 20px; }
.u-radial-overlay {
  position: absolute;
  top: 0;
  right: 0;
  width: 200px;
  height: 200px;
  background: radial-gradient(circle, rgba(59,130,246,0.08), transparent);
  pointer-events: none;
}
.u-padding-y { padding-top: 80px; padding-bottom: 48px; }
.u-text-loose-narrow { font-size: 0.88rem; line-height: 1.6; max-width: 280px; }
.u-error-text-margin { margin: 8px 0 0; color: #f87171; line-height: 1.4; font-weight: 600; }
.u-leading-tight { margin: 8px 0 0; line-height: 1.4; }
.u-inline-shift {
  display: inline-block;
  margin-right: 6px;
  transform: translateY(1px);
}
.u-spinner-anim {
  display: inline-block;
  animation: spin 2s linear infinite;
  margin-right: 8px;
}
.u-error-msg-row {
  font-size: 0.82rem;
  color: #4ade80;
  margin-bottom: 8px;
  line-height: 1.4;
}
.u-card-action-row {
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.u-card-text-row {
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  text-align: left;
}
.u-text-center-padded {
  text-align: center;
  padding: 80px 0 60px;
  max-width: 520px;
  margin: 0 auto;
}
.u-text-bold-1-05 { font-weight: 700; font-size: 1.05rem; color: #fff; }
.u-mt-3-only { margin-top: 12px; }
.u-metric-caption-2 { margin: 0; font-size: 0.82rem; }
.u-tiny-2 { font-size: 13px; margin-top: 2px; }


/* ── Final cleanup additions ───────────────────────────────────────── */
.u-fw-600 { font-weight: 600; }
.u-m-0 { margin: 0; }
.u-text-1-2-bold { font-size: 1.2rem; font-weight: 700; }
.u-text-078-semi { font-size: 0.78rem; font-weight: 600; }
.u-text-085 { font-size: 0.85rem; }
.u-no-decoration { text-decoration: none; }


/* ── PR #52 follow-up — fit Report-Only header under GFE's 8 KB limit ── */
/* The PR #49 UI refactor added the AI Visibility "Top Actions" cards
 * and the per-platform score grid to sample_report.html, which between
 * them introduced 21 new inline-style attribute bodies — pushing the
 * CSP Report-Only header to 8,460 bytes and over GFE's 8,192-byte cap
 * (silently strips). The classes below absorb every one of those new
 * inline-style bodies plus a few longstanding 2-occurrence patterns
 * that survived prior phases.
 *
 * Audit: scripts/audit_inline_styles.py templates  (2026-05-13). */

/* AI Visibility "Top Actions" card (3 occurrences in sample_report.html). */
.ai-action-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 10px;
  padding: 14px 16px;
}
.ai-action-header {
  align-items: center;
  display: flex;
  gap: 10px;
  margin-bottom: 8px;
}
.ai-action-num {
  align-items: center;
  background: var(--accent, #6366f1);
  border-radius: 50%;
  color: #fff;
  display: inline-flex;
  flex: 0 0 26px;
  font-size: 0.85rem;
  font-weight: 700;
  height: 26px;
  justify-content: center;
  width: 26px;
}
.ai-action-title {
  color: var(--text);
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
}
.ai-action-why {
  color: var(--text-muted);
  font-size: 0.82rem;
  line-height: 1.5;
  margin: 0 0 8px 0;
}
.ai-action-body {
  color: var(--text);
  font-size: 0.85rem;
  line-height: 1.5;
  margin: 0;
}
.ai-action-label        { color: var(--text);              font-weight: 600; }
.ai-action-label-accent { color: var(--accent, #6366f1);   font-weight: 600; }

/* 40×40 purple icon tile (2 occurrences — report.html + sample_report.html). */
.icon-tile-40-purple {
  align-items: center;
  background: rgba(139, 92, 246, 0.15);
  border-radius: 10px;
  display: flex;
  height: 40px;
  justify-content: center;
  width: 40px;
}

/* Plain warning-yellow text (2× in dashboard.html). */
.u-color-warning { color: #fbbf24; }

/* font-size: 0.78rem alone (2× in progress.html). */
.u-text-078 { font-size: 0.78rem; }

/* Status-card tone modifiers. CSS custom properties cascade, so setting
 * --bar-color on the parent .status-card also colors a nested .u-bar-fill
 * without a second inline style on the bar. */
.tone-good        { --status-color: var(--green); }
.tone-warn        { --status-color: var(--yellow); }
.tone-chatgpt     { --status-color: #10a37f; --bar-color: #10a37f; }
.tone-perplexity  { --status-color: #1e88e5; --bar-color: #1e88e5; }
.tone-claude      { --status-color: #d97706; --bar-color: #d97706; }
.tone-gemini      { --status-color: #6366f1; --bar-color: #6366f1; }
