/* ════════════════════════════════════════════════════════
   CORVUS — Chart Widget System
   Styles for all [data-widget] components rendered by
   corvus-widgets.js. Requires corvus-tokens.css.

   References SEMANTIC tokens (--cv-color-*, --cv-radius-*) only.
   Widget-internal class names (.kpi-inner, .heatmap-cell, etc.) are
   widget implementation details — kept as-is for now. Cross-widget
   primitives (.cv-sev-badge, .cv-fp-sq) use the cv- prefix and
   semantic vocabulary.
   ════════════════════════════════════════════════════════ */

/* ── Widget grid (legacy chart widget grid) ──────────── */
/* New widgets compose on a Tailwind grid (grid grid-cols-12 gap-4) instead.
   This class is retained for the existing chart widget partials. */

.widget-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-auto-rows: 200px;
  gap: 1rem;
  grid-auto-flow: dense;
}

/* ── Legacy chart widget card chrome ─────────────────── */
/* Used inside the existing chart widget partials. New widgets use
   .cv-widget (corvus-components.css) instead. */

.widget-card {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 1.25rem;
}

.widget-header {
  flex-shrink: 0;
  margin-bottom: .625rem;
}

.card-title {
  font-size: .75rem;
  font-weight: 600;
  color: var(--cv-color-text);
  margin-bottom: .125rem;
}

.card-sub {
  font-size: .6875rem;
  color: var(--cv-color-text-muted);
}

.widget-content {
  flex: 1;
  min-height: 0;
  position: relative;
}

/* ── KPI metric card ─────────────────────────────────── */

.kpi-inner {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  height: 100%;
  justify-content: center;
}

.kpi-row {
  display: flex;
  align-items: baseline;
  gap: .625rem;
}

.kpi-value {
  font-size: 2.125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--cv-color-text);
}

.kpi-trend {
  font-size: .69rem;
  font-weight: 600;
  padding: .2em .5em;
  border-radius: var(--cv-radius-md);
}

/* Trend variants — direction + evaluation. "up-bad" = trend rising AND that's
   bad for this metric (e.g. more open risks). "down-bad" = falling and bad
   (e.g. control pass rate dropping). The compound names carry both
   direction and judgement. */
.kpi-trend.up-bad   { background: var(--cv-color-danger-soft);  color: #991b1b; }
.kpi-trend.down-bad { background: var(--cv-color-danger-soft);  color: #991b1b; }
.kpi-trend.up-good  { background: var(--cv-color-success-soft); color: #166534; }
.kpi-trend.neutral  { background: var(--cv-color-neutral-soft); color: var(--cv-color-text-muted); }

.kpi-compare        { font-size: .6875rem; color: var(--cv-color-text-muted); }
.kpi-sparkline-wrap { height: 36px; }

/* ── Gauge / radial indicator ────────────────────────── */

.gauge-center {
  position: absolute;
  bottom: .5rem;
  left: 0;
  right: 0;
  text-align: center;
  pointer-events: none;
}

.gauge-value  { font-size: 1.25rem; font-weight: 600; line-height: 1; color: var(--cv-color-text); }
.gauge-status { font-size: .625rem; color: var(--cv-color-text-muted); margin-top: .125rem; }

/* ── Heatmap / risk matrix ───────────────────────────── */

.heatmap-wrap {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.heatmap-col-labels {
  display: flex;
  padding-left: 58px;
  gap: 3px;
  margin-bottom: 3px;
  flex-shrink: 0;
}

.heatmap-col-label {
  text-align: center;
  font-size: .5625rem;
  font-weight: 600;
  color: var(--cv-color-text-muted);
  flex: 1;
}

.heatmap-body  { display: flex; flex: 1; min-height: 0; }

.heatmap-y-label {
  writing-mode: vertical-lr;
  transform: rotate(180deg);
  font-size: .5625rem;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--cv-color-text-muted);
  text-align: center;
  padding-right: 5px;
  flex-shrink: 0;
}

.heatmap-inner { display: flex; flex-direction: column; flex: 1; gap: 3px; }
.heatmap-row   { display: flex; gap: 3px; flex: 1; }

.heatmap-row-label {
  width: 48px;
  font-size: .5625rem;
  color: var(--cv-color-text-muted);
  display: flex;
  align-items: center;
  padding-right: 5px;
  justify-content: flex-end;
  flex-shrink: 0;
}

.heatmap-cells { display: flex; gap: 3px; flex: 1; }

.heatmap-cell {
  flex: 1;
  border-radius: var(--cv-radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  cursor: pointer;
  transition: opacity .15s;
}

.heatmap-cell:hover { opacity: .82; }

.heatmap-cell-count { font-size: .8125rem; font-weight: 700; color: rgba(255,255,255,.95); line-height: 1; }
.heatmap-cell-label { font-size: .5rem; color: rgba(255,255,255,.7); margin-top: 1px; }

.heatmap-x-label {
  text-align: center;
  font-size: .5625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--cv-color-text-muted);
  padding-top: 5px;
  padding-left: 58px;
  flex-shrink: 0;
}

.heatmap-legend {
  display: flex;
  gap: .75rem;
  margin-top: .375rem;
  font-size: .5625rem;
  color: var(--cv-color-text-muted);
  flex-shrink: 0;
}

/* ── Leaderboard ─────────────────────────────────────── */

.lb-wrap {
  height: 100%;
  overflow-y: auto;
}

.lb-wrap table {
  width: 100%;
  border-collapse: collapse;
}

.lb-wrap th {
  position: sticky;
  top: 0;
  background: var(--cv-color-bg-card);
  text-align: left;
  font-size: .5625rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--cv-color-text-muted);
  border-bottom: 1px solid var(--cv-color-border);
  padding: 0 5px 6px;
}

.lb-wrap td {
  padding: 7px 5px;
  border-bottom: 1px solid var(--cv-color-border);
  font-size: .6875rem;
  vertical-align: middle;
}

.lb-wrap tr:last-child td { border-bottom: none; }
.lb-wrap tr:hover td      { background: var(--cv-color-bg-alt); cursor: pointer; }

.rank-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: var(--cv-radius-full);
  font-size: .5625rem;
  font-weight: 700;
  background: var(--cv-color-bg-alt);
  color: var(--cv-color-text-muted);
}

.rank-badge.top { background: #c9a84c; color: var(--cv-navy); }

/* ── Severity badge (domain — risk register, leaderboards) ─ */
/* Subtle dot + plain text. Domain vocabulary: critical / high / medium /
   low maps directly to risk severity levels in the data model. Distinct
   from the abstract state vocabulary (danger / warning / success) used
   elsewhere — but visually consistent (same dot pattern, just domain
   labels rather than abstract role labels). */

.cv-sev-badge {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  font-size: .75rem;
  font-weight: 500;
  color: var(--cv-color-text);
  white-space: nowrap;
  line-height: 1.4;
}

.cv-sev-badge::before {
  content: '';
  display: inline-block;
  width: .5rem;
  height: .5rem;
  border-radius: var(--cv-radius-full);
  background: var(--cv-color-neutral);
  flex-shrink: 0;
}

.cv-sev-critical::before { background: var(--cv-color-danger); }
.cv-sev-high::before     { background: var(--cv-color-warning); }
.cv-sev-medium::before   { background: var(--cv-color-warning); opacity: .55; }
.cv-sev-low::before      { background: var(--cv-color-success); }

/* ── Donut breakdown (chart + legend) ────────────────── */

.donut-legend {
  font-size: .625rem;
  display: flex;
  flex-direction: column;
  gap: .375rem;
  justify-content: center;
}

.donut-legend-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: .375rem;
}

/* ── Ring (donut with centre value) ─────────────────── */

.ring-wrap {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.ring-chart-area {
  flex: 1;
  min-height: 0;
  position: relative;
  max-width: 180px;
  margin: 0 auto;
  width: 100%;
}

.ring-legend {
  display: flex;
  justify-content: center;
  gap: .75rem;
  font-size: .625rem;
  color: var(--cv-color-text-muted);
  margin-top: .375rem;
  flex-shrink: 0;
  flex-wrap: wrap;
}

/* ── Aging / timeline ────────────────────────────────── */

.aging-wrap {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.aging-chart {
  flex: 1;
  min-height: 0;
  position: relative;
}

.aging-oldest {
  margin-top: .5rem;
  font-size: .625rem;
  color: var(--cv-color-text-muted);
  padding: .375rem .625rem;
  background: var(--cv-color-danger-soft);
  border-left: 3px solid var(--cv-color-danger);
  border-radius: 0 var(--cv-radius-sm) var(--cv-radius-sm) 0;
  flex-shrink: 0;
}

.aging-oldest strong { color: var(--cv-color-danger); }

/* ── Utility ─────────────────────────────────────────── */

.chart-fill {
  width: 100% !important;
  height: 100% !important;
  display: block;
}

/* ── Readiness bar (stacked proportional) ───────────── */
/* Visually similar to .cv-progress-segmented BUT semantically different:
   - cv-progress-segmented: equal-width segments, one per stage, coloured by state
   - cv-readiness-bar:     proportional segments, sized by count, coloured by category

   Used on readiness pages and control-coverage rollups. Four states map
   to domain-specific colours (the only place teal is used as a state).

   Markup:
       <div class="cv-readiness-bar">
         <div class="cv-readiness-seg cv-readiness-evidenced"  style="flex: 31;" title="31 evidenced"></div>
         <div class="cv-readiness-seg cv-readiness-implemented" style="flex: 17;" title="17 implemented"></div>
         <div class="cv-readiness-seg cv-readiness-progress"    style="flex: 18;" title="18 in progress"></div>
         <div class="cv-readiness-seg cv-readiness-notstarted"  style="flex:  9;" title="9 not started"></div>
       </div>

   Size modifiers:
       .cv-readiness-bar-sm   — 6px tall, in-table rows
       (default)              — 10px tall, summary cards
       .cv-readiness-bar-lg   — 14px tall, hero context */

.cv-readiness-bar {
  display: flex;
  width: 100%;
  height: 10px;
  border-radius: var(--cv-radius-full);
  overflow: hidden;
  gap: 1px;
  background: var(--cv-color-border);
}

.cv-readiness-bar-sm { height: 6px; }
.cv-readiness-bar-lg { height: 14px; }

.cv-readiness-seg {
  height: 100%;
  min-width: 2px;
  background: var(--cv-color-neutral);
  opacity: .4;
}

.cv-readiness-seg.cv-readiness-evidenced   { background: var(--cv-color-success); opacity: .85; }
.cv-readiness-seg.cv-readiness-implemented { background: var(--cv-teal);          opacity: .75; }
.cv-readiness-seg.cv-readiness-progress    { background: var(--cv-color-primary); opacity: .65; }
.cv-readiness-seg.cv-readiness-notstarted  { background: var(--cv-color-neutral); opacity: .35; }

/* Legend dot — pairs with the readiness bar in summary contexts */
.cv-readiness-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: var(--cv-radius-sm);
  flex-shrink: 0;
}

.cv-readiness-dot.cv-readiness-evidenced   { background: var(--cv-color-success); opacity: .85; }
.cv-readiness-dot.cv-readiness-implemented { background: var(--cv-teal);          opacity: .75; }
.cv-readiness-dot.cv-readiness-progress    { background: var(--cv-color-primary); opacity: .65; }
.cv-readiness-dot.cv-readiness-notstarted  { background: var(--cv-color-neutral); opacity: .35; }

/* ── Control-health bar (stacked proportional) ─────── */
/* Same shape as cv-readiness-bar but uses STATE colours (green/amber/
   red/grey) because each segment IS a state, not a category.
   Used in process registers and control-coverage rollups.

   Markup:
       <div class="cv-control-bar">
         <div class="cv-control-seg cv-control-effective" style="flex: 3;"></div>
         <div class="cv-control-seg cv-control-degraded"  style="flex: 1;"></div>
         <div class="cv-control-seg cv-control-failed"    style="flex: 1;"></div>
         <div class="cv-control-seg cv-control-untested"  style="flex: 2;"></div>
       </div> */

.cv-control-bar {
  display: flex;
  width: 100%;
  height: 6px;
  border-radius: var(--cv-radius-full);
  overflow: hidden;
  gap: 1px;
  background: var(--cv-color-border);
}

.cv-control-bar-md { height: 10px; }
.cv-control-bar-lg { height: 14px; }

.cv-control-seg {
  height: 100%;
  min-width: 2px;
  background: var(--cv-color-neutral);
  opacity: .4;
}

.cv-control-seg.cv-control-effective { background: var(--cv-color-success); opacity: .85; }
.cv-control-seg.cv-control-degraded  { background: var(--cv-color-warning); opacity: .85; }
.cv-control-seg.cv-control-failed    { background: var(--cv-color-danger);  opacity: .9; }
.cv-control-seg.cv-control-untested  { background: var(--cv-color-neutral); opacity: .45; }

/* ── Health dot (small categorical signal) ─────────── */
/* Single coloured pip — for "currency" / "health" columns in
   tables where a tile/bar would be too heavy. Three states. */

.cv-health-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: var(--cv-radius-full);
  background: var(--cv-color-neutral);
  opacity: .4;
  flex-shrink: 0;
  vertical-align: middle;
}

.cv-health-dot.cv-health-good  { background: var(--cv-color-success); opacity: .9; }
.cv-health-dot.cv-health-watch { background: var(--cv-color-warning); opacity: .9; }
.cv-health-dot.cv-health-bad   { background: var(--cv-color-danger);  opacity: .9; }

/* ── Engagement fingerprint ──────────────────────────── */
/* Visual primitive: a single coloured square. The 2×2 layout inside the
   widget tile is built with Tailwind utilities in the partial:
       <div class="grid grid-cols-2 grid-rows-2 gap-2 h-full content-center">
         <div class="flex items-center gap-2 min-w-0">
           <div class="cv-fp-sq cv-fp-danger"></div>
           <div class="text-xs cv-muted truncate">Risk</div>
         </div>
         ...three more cells...
       </div>
   Use semantic state classes on .cv-fp-sq. No state class = transparent
   (clean signal). */

.cv-fp-sq {
  /* Default (no state class) = neutral fill — same visual as .cv-fp-neutral.
     Both communicate "nothing to worry about in this dimension":
     no signal (no incident exists) OR low signal (low risk, well-managed).
     A transparent square read as broken rather than intentional. */
  width: 14px;
  height: 14px;
  border-radius: var(--cv-radius-sm);
  border: 1px solid var(--cv-color-neutral);
  background: var(--cv-color-neutral);
  opacity: .35;
  flex-shrink: 0;
}

/* Semantic state fills.
   Note: NO cv-fp-success variant. Green is reserved for genuinely
   complete outcomes (closed CAPA, certification achieved) — a low-risk
   cell is "well-managed," not "complete." The view layer maps:
       critical → danger     (red)
       high     → warning    (amber)
       medium   → caution    (amber, dimmed)
       low      → neutral    (grey, dimmed)  ← same visual as no-class
       (n/a)    → no class   (grey, dimmed)
   See feedback-color-and-badge-semantics in memory. */
.cv-fp-sq.cv-fp-danger  { background: var(--cv-color-danger);  border-color: var(--cv-color-danger);  opacity: .85; }
.cv-fp-sq.cv-fp-warning { background: var(--cv-color-warning); border-color: var(--cv-color-warning); opacity: .85; }
.cv-fp-sq.cv-fp-caution { background: var(--cv-color-warning); border-color: var(--cv-color-warning); opacity: .55; }
.cv-fp-sq.cv-fp-neutral { background: var(--cv-color-neutral); border-color: var(--cv-color-neutral); opacity: .35; }
