/* ============================================================================
   Control Freak — production stylesheet
   ----------------------------------------------------------------------------
   Adopted from the styling-phase design handoff (Y1,
   docs/superpowers/plans/2026-07-24-styling.md) as the web UI's single
   global stylesheet, replacing the earlier structural-only placeholder.
   Styles the existing markup by the class names in the design brief
   (§7). No external assets, no web fonts, no network calls — system
   font stacks plus an inline-SVG data-URI caret only. Light and dark
   via prefers-color-scheme; prefers-reduced-motion disables animation.

   This task (Y1) lands the stylesheet only — no markup changes, so the
   additions it targets (dashboard-logo, environment-cost-mtd, and the
   rest listed in the plan's Y2) are not yet present in the markup and
   render as no-ops until Y2 adds them. Every value below is the
   literal value from the approved design reference.
   ============================================================================ */

/* ---------- Design tokens ---------- */
:root {
  --cf-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --cf-mono: ui-monospace, "SF Mono", "SFMono-Regular", "Cascadia Code", "Roboto Mono", Menlo, Consolas, monospace;

  --cf-bg: #eceef2;
  --cf-panel: #ffffff;
  --cf-panel-inset: #f5f6f9;
  --cf-border: #dde1e8;
  --cf-border-strong: #c6ccd6;
  --cf-fg: #1a1f28;
  --cf-fg-dim: #5a6472;
  --cf-fg-faint: #8b93a1;

  --cf-accent: #2f66e0;      --cf-accent-fg: #ffffff;
  --cf-on: #1c8a4c;          --cf-on-soft: #e8f4ec;
  --cf-off: #77808e;         --cf-off-soft: #eef0f4;
  --cf-drift: #a86400;       --cf-drift-soft: #f9eed9;
  --cf-danger: #c1362a;      --cf-danger-soft: #fbe9e6;

  --cf-shadow: 0 1px 2px rgba(20,26,35,.05), 0 1px 3px rgba(20,26,35,.04);
  --cf-radius: 12px;

  /* Density — override the two vars to switch to compact */
  --cf-card-pad: 18px;
  --cf-row-gap: 15px;
  --cf-card-w: 340px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --cf-bg: #0b0f15;
    --cf-panel: #151b24;
    --cf-panel-inset: #101620;
    --cf-border: #232c39;
    --cf-border-strong: #33404f;
    --cf-fg: #e6edf5;
    --cf-fg-dim: #98a4b3;
    --cf-fg-faint: #68727f;

    --cf-accent: #4d87ff;    --cf-accent-fg: #0b0f15;
    --cf-on: #42b95a;        --cf-on-soft: #122a1b;
    --cf-off: #7d8898;       --cf-off-soft: #1a212b;
    --cf-drift: #d99320;     --cf-drift-soft: #2a2110;
    --cf-danger: #f0554c;    --cf-danger-soft: #2c1512;

    --cf-shadow: 0 1px 2px rgba(0,0,0,.45), 0 2px 8px rgba(0,0,0,.3);
  }
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; }
body {
  background: var(--cf-bg);
  color: var(--cf-fg);
  font-family: var(--cf-sans);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--cf-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

@keyframes cf-pulse { 0%,100% { opacity: .5; } 50% { opacity: 1; } }
@keyframes cf-fade { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes cf-progress { 0% { transform: translateX(-100%); } 100% { transform: translateX(280%); } }
@keyframes cf-body { from { opacity: .4; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; } }

/* ============================================================================
   LOGIN (§6.1) — bare elements styled by descendant selectors
   ============================================================================ */
.login-page {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.login-page form {
  width: 100%; max-width: 360px;
  display: flex; flex-direction: column; gap: 16px;
  background: var(--cf-panel);
  border: 1px solid var(--cf-border);
  border-radius: 14px;
  box-shadow: var(--cf-shadow);
  padding: 28px 26px;
}
.login-page .login-header {
  display: flex; align-items: center; gap: 11px;
}
.login-page h1 {
  margin: 0;
  font-family: var(--cf-mono);
  font-size: 19px; font-weight: 650; letter-spacing: .01em;
}
.login-page .login-subtitle {
  font-size: 12.5px; color: var(--cf-fg-faint); margin-top: -6px;
}
.login-page input {
  width: 100%;
  font-family: var(--cf-sans); font-size: 14px;
  color: var(--cf-fg);
  background: var(--cf-panel-inset);
  border: 1px solid var(--cf-border-strong);
  border-radius: 8px;
  padding: 11px 13px;
  outline: none;
}
.login-page input:focus { border-color: var(--cf-accent); }
.login-page button[type="submit"] {
  width: 100%;
  font-family: var(--cf-sans); font-size: 14px; font-weight: 650;
  padding: 11px 14px;
  border: 1px solid transparent; border-radius: 8px;
  background: var(--cf-accent); color: var(--cf-accent-fg);
  cursor: pointer;
}
/* Proposed submitting state (see README §Behavior) */
.login-page input:disabled,
.login-page button[type="submit"]:disabled { opacity: .55; cursor: progress; }

/* ============================================================================
   DASHBOARD SHELL (§6.2)
   ============================================================================ */
.dashboard-page { min-height: 100vh; }

.dashboard-header {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 24px;
  background: var(--cf-bg);
  border-bottom: 1px solid var(--cf-border);
}
.dashboard-title {
  font-family: var(--cf-mono);
  font-size: 15px; font-weight: 650; letter-spacing: .01em;
}
/* Optional status LED before the title — add <span class="dashboard-logo"> (see README) */
.dashboard-logo {
  width: 11px; height: 11px; border-radius: 3px;
  background: var(--cf-on); box-shadow: 0 0 0 3px var(--cf-on-soft);
  flex: none;
}
.dashboard-brand { display: flex; align-items: center; gap: 11px; }
.dashboard-actions { display: flex; align-items: center; gap: 14px; }
.dashboard-user {
  font-family: var(--cf-mono); font-size: 12.5px; color: var(--cf-fg-dim);
  white-space: nowrap;
}
/* Guards the "Signed in as " momentary gap (§6.2): username width never
   shifts the layout because the block is left-of-fixed order, not right-anchored. */
.dashboard-user strong,
.dashboard-user .dashboard-user-name { color: var(--cf-fg); font-weight: 600; }

.dashboard-body { display: flex; flex-direction: column; gap: 22px; animation: cf-body .35s ease; }

/* Content column */
.dashboard-page > main,
.dashboard-page .dashboard-main {
  max-width: 1160px; margin: 0 auto; padding: 22px 24px 40px;
  display: flex; flex-direction: column; gap: 22px;
}

/* ============================================================================
   BANNERS + EMPTY (§5.1, §5.2)
   ============================================================================ */
.banner {
  padding: 11px 15px; border-radius: 9px;
  font-size: 13px; display: flex; align-items: center; gap: 10px;
}
.banner.loading {
  background: var(--cf-panel-inset);
  border: 1px solid var(--cf-border);
  color: var(--cf-fg-dim);
  font-family: var(--cf-mono);
  animation: cf-pulse 1.4s ease-in-out infinite;
}
.banner.loading::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--cf-fg-faint); flex: none;
}
.banner.error {
  background: var(--cf-danger-soft);
  border: 1px solid var(--cf-danger);
  color: var(--cf-danger);
}
.banner.error::before { content: "\26A0"; font-weight: 700; } /* ⚠ */
/* Y5 addition: the delivered `.banner` family only ships `.loading`/`.error`;
   the history panel's partial-read note (malformed log entries, skipped
   server-side but never silent) needed a third, less severe register —
   extended from the existing family using the drift token already defined
   for "state is indeterminate/incomplete", not a new colour. */
.banner.warning {
  background: var(--cf-drift-soft);
  border: 1px solid var(--cf-drift);
  color: var(--cf-drift);
}
.banner.warning::before { content: "\26A0"; font-weight: 700; } /* ⚠ */

.empty-state {
  padding: 22px; text-align: center;
  border: 1px dashed var(--cf-border-strong); border-radius: 9px;
  color: var(--cf-fg-dim); font-size: 13px;
}

/* ============================================================================
   BURN-RATE PANEL (§6.3)
   ============================================================================ */
.burn-rate-panel {
  background: var(--cf-panel); border: 1px solid var(--cf-border);
  border-radius: var(--cf-radius); box-shadow: var(--cf-shadow);
  padding: 20px 22px;
  display: flex; flex-direction: column; gap: 16px;
}
.burn-rate-totals {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px;
}
.burn-rate-total {
  display: flex; flex-direction: column; gap: 4px;
  padding: 12px 14px; background: var(--cf-panel-inset); border-radius: 9px;
}
/* Cumulative "Month to date" total is visually distinguished from the rate totals */
.burn-rate-total-mtd { box-shadow: inset 3px 0 0 var(--cf-accent); }
.burn-rate-total-label {
  font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--cf-fg-faint);
}
.burn-rate-total-value {
  font-family: var(--cf-mono); font-size: 26px; font-weight: 650;
  color: var(--cf-fg); font-variant-numeric: tabular-nums; line-height: 1.1;
}
.burn-rate-split {
  display: flex; gap: 18px; font-family: var(--cf-mono); font-size: 13px;
  padding-top: 14px; border-top: 1px solid var(--cf-border);
}
.burn-rate-split-owned, .burn-rate-split-shared { color: var(--cf-fg-dim); }
.burn-rate-split-owned strong, .burn-rate-split-shared strong { color: var(--cf-fg); font-weight: 600; }

.environment-counts { display: flex; gap: 8px; }
.environment-count {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 650; font-variant-numeric: tabular-nums;
}
.environment-count-on      { color: var(--cf-on);    background: var(--cf-on-soft); }
.environment-count-off     { color: var(--cf-off);   background: var(--cf-off-soft); }
.environment-count-partial { color: var(--cf-drift); background: var(--cf-drift-soft); }
/* Redundant-with-color shape markers (§4) — prepend via ::before if the counts
   render as bare "2 on" text with no glyph in markup. */
.environment-count-on::before      { content: "\25CF "; }  /* ● */
.environment-count-off::before     { content: "\25CB "; }  /* ○ */
.environment-count-partial::before { content: "\25B2 "; }  /* ▲ */

.org-next-expiry { font-family: var(--cf-mono); font-size: 12.5px; color: var(--cf-fg-dim); }
.org-next-expiry strong,
.org-next-expiry .org-next-expiry-value { color: var(--cf-fg); }

/* ============================================================================
   ENVIRONMENT LIST + CARD (§6.4, §6.5)
   ============================================================================ */
.environment-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--cf-card-w), 1fr));
  gap: 16px; align-items: stretch;
}

.environment-card {
  position: relative;
  display: flex; flex-direction: column; gap: var(--cf-row-gap);
  padding: var(--cf-card-pad);
  border: 1px solid var(--cf-border);
  border-left: 3px solid var(--cf-border-strong);
  border-radius: var(--cf-radius);
  background: var(--cf-panel);
  box-shadow: var(--cf-shadow);
  /* Grid item: the .environment-list grid sizes the card, filling the row
     in equal columns at least --cf-card-w wide (owner preference over the
     brief's fixed-width cards, so the card row matches the burn-rate panel
     width above it). */
  min-width: 0;
}
/* Card-level state treatment (independent of the badge, §6.5) */
.environment-card-on      { border-left-color: var(--cf-on);    background: var(--cf-on-soft); }
.environment-card-partial { border-left-color: var(--cf-drift); background: var(--cf-drift-soft); }
.environment-card-off     { border-left-color: var(--cf-border-strong); background: var(--cf-panel); }
/* Off cards recede: greyed heading */
.environment-card-off .environment-title { color: var(--cf-fg-faint); }

/* Y5 note: `justify-content: space-between` was correct for the delivered
   2-child header (title, badge); the card's own "History" button (spec
   addendum §1, plan O3/Y2) is a third child the design never anticipated.
   Giving the title `flex: 1 1 auto` so it absorbs the free space keeps the
   badge and the new button tight together at the right edge instead of
   space-between spreading three items evenly across the row. */
.environment-card-header {
  display: flex; align-items: flex-start; gap: 8px;
}
.environment-title {
  flex: 1 1 auto; min-width: 0;
  margin: 0; font-family: var(--cf-mono);
  font-size: 14px; font-weight: 650; color: var(--cf-fg); word-break: break-word;
}

/* -- State badge (§6.5.1) -- */
.environment-state-badge, .resource-state-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 650; line-height: 1.4; white-space: nowrap;
}
.environment-state-badge-on,  .resource-state-badge-on  { color: var(--cf-on);    background: var(--cf-on-soft); }
.environment-state-badge-off, .resource-state-badge-off { color: var(--cf-off);   background: var(--cf-off-soft); }
.environment-state-badge-partial { color: var(--cf-drift); background: var(--cf-drift-soft); white-space: normal; }
/* Shape markers so state survives desaturation (§4). Drift already carries the
   full words "Drift — resources disagree", so no glyph is forced on it. */
.environment-state-badge-on::before,  .resource-state-badge-on::before  { content: "\25CF"; }  /* ● */
.environment-state-badge-off::before, .resource-state-badge-off::before { content: "\25CB"; }  /* ○ */

/* -- Session row (§6.5.2) -- */
.environment-session-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.environment-countdown {
  font-family: var(--cf-mono); font-variant-numeric: tabular-nums;
  font-size: 15px; font-weight: 600; color: var(--cf-fg);
}
.environment-countdown-indefinite {
  font-family: var(--cf-mono); font-size: 14px; font-weight: 500; color: var(--cf-fg-dim);
}
/* Resolve the Indefinite ambiguity (§6.5.2) purely in CSS: on an OFF card the
   row is irrelevant, so it recedes; it only draws the eye on an ON card. */
.environment-card-off .environment-countdown-indefinite {
  font-size: 13px; font-weight: 400; font-style: italic; color: var(--cf-fg-faint);
}
.environment-countdown-flagged {
  color: var(--cf-drift); font-weight: 600; font-size: 14px;
}
.environment-countdown-flagged::before { content: "\2691 "; } /* ⚑ */
.environment-attribution { font-family: var(--cf-mono); font-size: 12px; color: var(--cf-fg-faint); }

/* -- Cost block (§6.5 item 3) -- */
.environment-cost {
  display: flex; flex-direction: column; gap: 3px;
  padding: 11px 12px; background: var(--cf-panel-inset); border-radius: 8px;
}
.environment-cost-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.environment-cost-label { font-size: 12.5px; color: var(--cf-fg-dim); }
.environment-cost-value {
  font-family: var(--cf-mono); font-size: 13px; font-weight: 600;
  color: var(--cf-fg); font-variant-numeric: tabular-nums;
}
/* Cumulative "Spent this month" row (NEW — needs a data field, see README) */
.environment-cost-mtd { margin-top: 6px; padding-top: 9px; border-top: 1px solid var(--cf-border); }
.environment-cost-mtd .environment-cost-label { font-weight: 600; }
.environment-cost-mtd .environment-cost-value { font-size: 14.5px; font-weight: 700; }

/* -- Shared resources (§6.5 item 4) -- */
.shared-resource-list { display: flex; flex-direction: column; gap: 6px; }
.shared-resource-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; background: var(--cf-panel-inset);
  border: 1px solid var(--cf-border); border-radius: 7px;
}
.shared-resource-name {
  font-family: var(--cf-mono); font-size: 12.5px; color: var(--cf-fg);
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.shared-resource-cost {
  font-family: var(--cf-mono); font-size: 12.5px; font-weight: 600;
  color: var(--cf-fg-dim); font-variant-numeric: tabular-nums;
}
.shared-resource-state-unknown {
  padding: 3px 9px; border-radius: 999px; font-size: 11px; font-weight: 650;
  color: var(--cf-fg-faint); background: var(--cf-panel);
  border: 1px dashed var(--cf-border-strong); white-space: nowrap;
}
.shared-resource-state-unknown::before { content: "? "; }

/* -- Expandable resource section (plan R5, owner decision 4) --
   Not in the delivered design handoff at all (it predates this phase) —
   built entirely from the system's own primitives rather than a new
   visual language, the same instruction plan Y5 already applied to the
   history panel and cost provenance below: a plain <details>/<summary>
   disclosure (native browser affordance, no JS state to manage), styled
   as a slim inset strip that opens into `.shared-resource-item`'s own
   flex-row card-inset row shape, and `.resource-state-badge` (already
   styled above) for each row's live state — no new colour vocabulary. */
.environment-resource-panel {
  padding: 9px 12px; background: var(--cf-panel-inset); border-radius: 8px;
}
.environment-resource-summary {
  font-family: var(--cf-sans); font-size: 12.5px; font-weight: 600; color: var(--cf-fg-dim);
  cursor: pointer; list-style: none;                 /* the marker below replaces the native triangle */
}
.environment-resource-summary::-webkit-details-marker { display: none; }
.environment-resource-summary::before {
  content: "\25B8"; display: inline-block; margin-right: 6px;   /* ▸ */
  transition: transform .15s ease;
}
.environment-resource-panel[open] > .environment-resource-summary::before { transform: rotate(90deg); }
.resource-detail-list {
  list-style: none; margin: 9px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
}
/* Two lines, deliberately: the kind takes the first row on its own and the
   name, any shared tag, and the state badge share the second. On one row
   the kind and a fully-qualified service name crowded each other out and
   the name ellipsised almost immediately (owner feedback, 2026-07-26). */
.resource-detail-item {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px;
  padding: 7px 10px; background: var(--cf-panel);
  border: 1px solid var(--cf-border); border-radius: 7px;
}
.resource-detail-kind {
  flex: 0 0 100%;
  font-family: var(--cf-sans); font-size: 11px; color: var(--cf-fg-faint); white-space: nowrap;
}
.resource-detail-name {
  font-family: var(--cf-mono); font-size: 12.5px; color: var(--cf-fg);
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.resource-detail-shared-tag {
  font-family: var(--cf-sans); font-size: 10.5px; font-weight: 650;
  text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 999px;
  color: var(--cf-fg-dim); background: var(--cf-panel-inset); border: 1px solid var(--cf-border-strong);
}

/* ============================================================================
   ACTION PANEL (§6.6)
   ============================================================================ */
.environment-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  justify-content: flex-end;                 /* single control (On / Refresh) sits right */
  margin-top: auto;                          /* pin to card bottom, aligning across cards */
  padding-top: 13px; border-top: 1px solid var(--cf-border);
}
.environment-action { display: flex; align-items: center; gap: 6px; }
.environment-action-extend { margin-right: auto; }  /* Extend left, Off right on ON cards */

/* Duration dropdowns — never disabled during in-flight (§6.6) */
.action-duration-select {
  font-family: var(--cf-mono); font-size: 12.5px; color: var(--cf-fg);
  background-color: var(--cf-panel-inset);
  border: 1px solid var(--cf-border-strong); border-radius: 6px;
  padding: 6px 26px 6px 10px; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238b93a1' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 9px center;
}

/* Buttons */
.environment-action-button {
  font-family: var(--cf-sans); font-size: 13px; font-weight: 600;
  padding: 7px 14px; border-radius: 7px; border: 1px solid transparent;
  line-height: 1; cursor: pointer; transition: filter .12s, opacity .12s;
}
.environment-action-on-button      { background: var(--cf-on);     color: #fff; }
.environment-action-extend-button  { background: var(--cf-accent); color: var(--cf-accent-fg); }
/* Green reads as "start this up", which is only what the control does on an
   environment that is actually off. On a running one it sets an auto-off
   timer, and on a drifted one it forces a state — both adjustments to
   something already running, so they take the accent colour that Extend
   (the other adjust-in-place action) already uses. */
.environment-action-on-button.environment-action-adjust-button {
  background: var(--cf-accent); color: var(--cf-accent-fg);
}
.environment-action-button.danger  { background: var(--cf-danger); color: #fff; }  /* Off + confirm */
.environment-action-off-cancel-button {
  background: transparent; color: var(--cf-fg-dim);
  border-color: var(--cf-border-strong); font-size: 12.5px; padding: 6px 11px;
}
.environment-action-button:hover:not(:disabled) { filter: brightness(1.06); }
/* In-flight disabled (§6.6) — unambiguous */
.environment-action-button:disabled { opacity: .4; cursor: not-allowed; filter: saturate(.4); }

/* Armed off-confirmation (§6.6) */
.environment-action-confirm-group {
  display: flex; align-items: center; gap: 7px;
  padding: 4px 5px 4px 10px;
  background: var(--cf-danger-soft); border: 1px solid var(--cf-danger); border-radius: 8px;
}
.environment-action-confirm-prompt { font-size: 12.5px; font-weight: 650; color: var(--cf-danger); }

/* Per-card in-flight progress bar — needs a <div class="environment-card-progress">
   as the card's first child while a request is in flight (see README). */
.environment-card-progress {
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  overflow: hidden; border-radius: var(--cf-radius) var(--cf-radius) 0 0;
}
.environment-card-progress::after {
  content: ""; display: block; width: 36%; height: 100%;
  background: var(--cf-accent); animation: cf-progress 1.1s ease-in-out infinite;
}

/* Header buttons */
.dashboard-refresh-button {
  font-family: var(--cf-sans); font-size: 13px; font-weight: 600;
  padding: 7px 14px; border-radius: 7px; border: 1px solid transparent;
  background: var(--cf-accent); color: var(--cf-accent-fg); cursor: pointer;
}
.dashboard-logout-button {
  font-family: var(--cf-sans); font-size: 13px; font-weight: 600;
  padding: 7px 14px; border-radius: 7px;
  background: transparent; color: var(--cf-fg-dim);
  border: 1px solid var(--cf-border-strong); cursor: pointer;
}
/* Y5 addition: the design handoff never mentions history at all (see this
   file's own `HISTORY VIEW AND COST PROVENANCE` section below) — styled
   as a neutral secondary action, the same visual weight as Log out, since
   it is a read-only lookup rather than a mutating or navigational one. */
.dashboard-history-button {
  font-family: var(--cf-sans); font-size: 13px; font-weight: 600;
  padding: 7px 14px; border-radius: 7px;
  background: transparent; color: var(--cf-fg-dim);
  border: 1px solid var(--cf-border-strong); cursor: pointer;
}
.dashboard-history-button:hover { color: var(--cf-fg); border-color: var(--cf-fg-dim); }

/* ============================================================================
   TOASTS (§5.3)
   ============================================================================ */
.toast-list {
  position: fixed; top: 16px; right: 16px; z-index: 60;
  display: flex; flex-direction: column; gap: 10px;
  width: min(380px, calc(100vw - 32px));
}
.toast {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 13px;
  background: var(--cf-panel); border: 1px solid var(--cf-border);
  border-left: 3px solid var(--cf-danger); border-radius: 9px;
  box-shadow: var(--cf-shadow); animation: cf-fade .18s ease;
}
.toast-message {
  flex: 1; font-size: 13px; line-height: 1.45; color: var(--cf-fg);
  word-break: break-word; white-space: pre-wrap;   /* multi-line refusals wrap, never truncate */
}
.toast-dismiss {
  flex: none; width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; line-height: 1; color: var(--cf-fg-dim);
  background: transparent; border: 1px solid var(--cf-border); border-radius: 6px;
  cursor: pointer;
}
.toast-dismiss:hover { color: var(--cf-fg); border-color: var(--cf-border-strong); }

/* ============================================================================
   HISTORY VIEW AND COST PROVENANCE (plan task Y5)
   ----------------------------------------------------------------------------
   Genuine design gap, not an oversight to second-guess: the delivered
   handoff (control-freak.css / the .dc.html reference / its README) never
   mentions the action-history view, the per-card "History" link, or any
   provenance label at all — no class name, no screen, no token. Everything
   below is built ONLY from primitives the delivered system already
   defines (panel chrome, badge/pill colour+shape semantics, the
   `.banner`/`.empty-state` family, the auto-fit responsive technique
   `.burn-rate-totals` already uses), per plan task Y5's own instruction
   to extend rather than invent a parallel visual language.

   Recorded gap for a design follow-up: the delivered system has no
   genuine multi-column TABLE pattern to map the history list onto (the
   plan's own wording assumes one exists). The closest analogue is
   `.shared-resource-list`/`.shared-resource-item`'s flex-row shape, which
   is what `.history-event` below extends — a real design pass may want a
   purpose-built dense table treatment instead, especially once history
   lists grow long enough to want sortable/sticky column headers.
   ============================================================================ */

/* -- Per-card "History" link (spec addendum §1, plan O3) --
   Sized and pill-shaped to sit beside the state badge in the card header
   as a matching pair, but kept neutral (never on/off/drift-coloured) since
   it carries no state of its own — see the `.environment-card-header`
   layout note above for why the header no longer uses space-between. */
.environment-history-button {
  font-family: var(--cf-sans); font-size: 11px; font-weight: 650;
  padding: 3px 9px; border-radius: 999px; line-height: 1.4; white-space: nowrap;
  background: transparent; color: var(--cf-fg-faint);
  border: 1px solid var(--cf-border-strong); cursor: pointer;
}
.environment-history-button:hover { color: var(--cf-fg-dim); border-color: var(--cf-fg-dim); }

/* -- Cost block: the "no rate at all" case (spec addendum §2) --
   The delivered CSS styles the three known-rate rows and the mtd row but
   never this one — the paragraph that stands in for them all when the
   provenance is unknown. Faint and italic, matching the same "recede,
   don't alarm" treatment the off-card indefinite-session row already uses
   for its own de-emphasised case. */
.environment-cost-unknown {
  margin: 0; font-size: 12.5px; color: var(--cf-fg-faint); font-style: italic;
}

/* -- Cost-provenance caption --
   "Provenance maps onto its badge patterns" (plan Y5): a small coloured
   chip rather than plain text, reusing the exact soft-background/border
   pairing `.environment-state-badge`'s colour tokens already define per
   source, plus `.shared-resource-state-unknown`'s own dashed-border
   "unknown" treatment for the unknown case. Not pill-shaped (`border-
   radius: 999px`) like the state badges — this caption's text is prose
   (it can carry a full observation-window timestamp range), which wraps
   badly inside a fully-rounded pill; a soft rounded box reads as the same
   badge family without that failure mode. */
.environment-cost-provenance {
  margin: 6px 0 0; padding: 4px 8px;
  border-radius: 6px; border: 1px solid var(--cf-border);
  background: var(--cf-panel); font-size: 10.5px; line-height: 1.4;
  color: var(--cf-fg-dim);
}
.environment-cost-provenance-observed { color: var(--cf-fg-dim); }
.environment-cost-provenance-averaged {
  color: var(--cf-drift); background: var(--cf-drift-soft); border-color: var(--cf-drift);
}
.environment-cost-provenance-override {
  color: var(--cf-accent); background: var(--cf-panel-inset); border-color: var(--cf-border-strong);
}
.environment-cost-provenance-unknown {
  color: var(--cf-fg-faint); font-style: italic; background: transparent; border-style: dashed;
}

/* -- Org-wide "some figures have no known cost" note --
   Reuses the drift/amber token already meaning "indeterminate, don't
   trust the total blindly" for `.environment-card-partial`/
   `.environment-count-partial`, plus that badge's own shape-marker
   convention (§4: state is never colour-only) via the same ▲ glyph. */
.burn-rate-unpriced {
  margin: 0; font-size: 12px; color: var(--cf-drift);
}
.burn-rate-unpriced::before { content: "\25B2 "; } /* ▲ */

/* -- History panel --
   A fixed viewport-anchored drawer: not a new idea (`.toast-list` is
   already fixed-positioned chrome floating over the page), just applied
   at panel scale using `.burn-rate-panel`'s own panel/border/shadow look
   instead of inventing a modal/backdrop treatment the delivered system
   has no example of at all. `top: 64px` is an approximation of the
   sticky header's own rendered height, not a measured constant. */
.history-panel {
  position: fixed; top: 64px; right: 16px; bottom: 16px;
  width: min(480px, calc(100vw - 32px));
  z-index: 40; /* below .toast-list (60), above page content */
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--cf-panel); border: 1px solid var(--cf-border);
  border-radius: var(--cf-radius); box-shadow: var(--cf-shadow);
  animation: cf-fade .18s ease;
}
.history-panel-header {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 16px; border-bottom: 1px solid var(--cf-border); flex: none;
}
.history-panel-title {
  margin: 0; font-family: var(--cf-mono); font-size: 14px; font-weight: 650; color: var(--cf-fg);
}
.history-panel-close {
  font-family: var(--cf-sans); font-size: 12.5px; font-weight: 600;
  padding: 6px 11px; border-radius: 6px;
  background: transparent; color: var(--cf-fg-dim);
  border: 1px solid var(--cf-border-strong); cursor: pointer;
}
.history-panel-close:hover { color: var(--cf-fg); border-color: var(--cf-fg-dim); }
.history-panel-body {
  flex: 1; overflow-y: auto; padding: 14px 16px;
  display: flex; flex-direction: column; gap: 10px;
}
/* The partial-read note (malformed log entries) — a `.banner.warning`. */
.history-malformed-note { margin: 0; }

/* -- History event list --
   The delivered system's own closest thing to a table row: extends
   `.shared-resource-item`'s flex row (panel-inset background, bordered,
   rounded) rather than a genuine `<table>` treatment (see this section's
   own header comment for that recorded gap). `flex-wrap` plus giving the
   outcome column `flex-basis: 100%` lets a long refusal/failure detail
   drop to its own line with no breakpoint needed — the same auto-fit-
   without-a-breakpoint idea `.burn-rate-totals` already uses. */
.history-event-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.history-event {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px;
  padding: 8px 10px;
  background: var(--cf-panel-inset); border: 1px solid var(--cf-border); border-radius: 7px;
  font-size: 12.5px;
}
.history-event-time {
  font-family: var(--cf-mono); font-size: 11.5px; color: var(--cf-fg-faint); white-space: nowrap;
}
.history-event-actor {
  font-family: var(--cf-mono); font-size: 12px; color: var(--cf-fg-dim);
}
.history-event-action {
  font-family: var(--cf-mono); font-size: 11px; font-weight: 650; color: var(--cf-fg);
  text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 999px;
  background: var(--cf-panel); border: 1px solid var(--cf-border);
}
.history-event-target {
  font-family: var(--cf-mono); font-size: 12px; color: var(--cf-fg);
}
/* Full-width so a long "refused: ..."/"failed: ..." detail wraps on its
   own line rather than squeezing the metadata fields above it. Coloured
   text with a redundant glyph, not a pill — see this section's own header
   comment on why prose content doesn't take the fully-rounded badge
   shape. */
.history-event-outcome {
  flex: 1 1 100%; font-size: 12px; font-weight: 600; word-break: break-word;
}
.history-event-outcome-success { color: var(--cf-on); }
.history-event-outcome-success::before { content: "\25CF "; } /* ● */
.history-event-outcome-refused { color: var(--cf-drift); }
.history-event-outcome-refused::before { content: "\25B2 "; } /* ▲ */
.history-event-outcome-failed { color: var(--cf-danger); }
.history-event-outcome-failed::before { content: "\26A0 "; } /* ⚠ */

/* ============================================================================
   RESPONSIVE (down to tablet, §3)
   ============================================================================ */
@media (max-width: 820px) {
  :root { --cf-card-w: 100%; }
  .environment-card { flex-basis: 100%; }
  .dashboard-header { flex-wrap: wrap; }
  /* Y5: the fixed-width drawer would be cramped or clipped below tablet
     width — pin it edge-to-edge instead of a fixed right-anchored width. */
  .history-panel { left: 16px; right: 16px; width: auto; }
}
