
/* /src/shared/design-system/tokens.css */
/* Cozero design system — canonical tokens + utility classes for the Control app.
   Ported from control-module/apps/web/src/styles/tokens.css (OKLCH navy
   #272C5F primary, finance indigo accent, AI green, Inter-first font stack). This file is the
   single source of styling; it is imported directly in __root.tsx. */

:root {
  /* Core */
  --background: 96.5% 0.004 286; /* #F4F4F6 */
  --white: 100% 0 0;
  --white-foreground: 27% 0.085 269; /* #272C5F */

  --primary: 27% 0.085 269; /* navy #272C5F */
  --primary-foreground: 100% 0 0;
  --primary-active: 27% 0.085 269;

  --secondary: 64% 0.04 276; /* #888BAA */
  --secondary-foreground: 100% 0 0;

  --accent: 44% 0.05 269; /* #4F5484 */
  --accent-foreground: 100% 0 0;

  --muted-bg: 91% 0.01 276; /* #E0E2EB */
  --muted: 37% 0.025 275; /* #46475C */
  --muted-2: 55% 0.025 275; /* lighter muted text */

  --input: 91% 0.01 276;
  --ring: 44% 0.05 269;
  --radius: 0.625rem;

  /* Sidebar (uses primary navy in this build) */
  --sidebar-background: 27% 0.085 269;
  --sidebar-foreground: 100% 0 0;
  --sidebar-accent: 44% 0.05 269;

  /* AI green #5CC63C */
  --ai: 70% 0.19 138;
  --ai-foreground: 100% 0 0;

  /* Action blue #2871FF */
  --action: 55% 0.22 258;
  --action-foreground: 100% 0 0;

  /* Brand green #28A003 */
  --brand: 56% 0.17 142;
  --brand-foreground: 100% 0 0;

  /* Scope colors */
  --scope-1: 62% 0.13 285; /* purple */
  --scope-2: 55% 0.09 148; /* sage */
  --scope-3: 61% 0.12 66; /* amber */

  /* Semantic */
  --green-bg: 91% 0.03 140;
  --green: 53% 0.17 141;
  --orange-bg: 94% 0.04 70;
  --orange: 71% 0.16 60;
  --error-bg: 90% 0.03 20;
  --error: 59% 0.2 26;

  /* CONTROL-specific finance accent (deep indigo with warmth) */
  --finance: 38% 0.1 270;
  --finance-soft: 95% 0.015 270;

  /* Tables */
  --table-header: 64% 0.04 276;
  --table-row-hover: 96.77% 0.0027 286.35;
  --table-row-selected: 91% 0.01 276;

  /* Surface radii */
  --radius-sm: 8px;
  --radius-surface: 16px;
}

* {
  box-sizing: border-box;
  border-color: oklch(var(--muted-bg));
}
html,
body,
#root {
  height: 100%;
}
body {
  margin: 0;
  font-family:
    'Inter',
    ui-sans-serif,
    system-ui,
    -apple-system,
    sans-serif;
  background: oklch(var(--background));
  color: oklch(var(--primary));
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
button {
  font-family: inherit;
}

/* Reset all <button>s to behave like an unstyled action surface.
   Each custom button restyles itself. */
button {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: inherit;
}

a {
  color: inherit;
  text-decoration: none;
}

/* Typography */
.h0 {
  font-size: 2rem;
  line-height: 2.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.h1 {
  font-size: 1.5rem;
  line-height: 2rem;
  font-weight: 600;
  letter-spacing: -0.005em;
}
.h2 {
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 600;
}
.h3 {
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.body-bold {
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
}
.body {
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 400;
}
.caption {
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 400;
}
.caption-bold {
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
}
.eyebrow {
  font-size: 0.6875rem;
  line-height: 0.875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: oklch(var(--muted) / 0.7);
}
.tabular {
  font-variant-numeric: tabular-nums;
}

/* Color utility classes */
.text-primary {
  color: oklch(var(--primary));
}
.text-accent {
  color: oklch(var(--accent));
}
.text-secondary {
  color: oklch(var(--secondary));
}
.text-muted {
  color: oklch(var(--muted));
}
.text-muted-2 {
  color: oklch(var(--muted-2));
}
.text-white {
  color: white;
}
.text-action {
  color: oklch(var(--action));
}
.text-ai {
  color: oklch(var(--ai));
}
.text-brand {
  color: oklch(var(--brand));
}
.text-green {
  color: oklch(var(--green));
}
.text-error {
  color: oklch(var(--error));
}
.text-orange {
  color: oklch(var(--orange));
}
.text-finance {
  color: oklch(var(--finance));
}

.bg-background {
  background: oklch(var(--background));
}
.bg-white {
  background: white;
}
.bg-primary {
  background: oklch(var(--primary));
}
.bg-accent {
  background: oklch(var(--accent));
}
.bg-action {
  background: oklch(var(--action));
}
.bg-ai {
  background: oklch(var(--ai));
}
.bg-brand {
  background: oklch(var(--brand));
}
.bg-muted-bg {
  background: oklch(var(--muted-bg));
}
.bg-finance-soft {
  background: oklch(var(--finance-soft));
}
.bg-green-bg {
  background: oklch(var(--green-bg));
}
.bg-orange-bg {
  background: oklch(var(--orange-bg));
}
.bg-error-bg {
  background: oklch(var(--error-bg));
}

.border {
  border: 1px solid oklch(var(--muted-bg));
}
.border-b {
  border-bottom: 1px solid oklch(var(--muted-bg));
}
.border-t {
  border-top: 1px solid oklch(var(--muted-bg));
}
.border-r {
  border-right: 1px solid oklch(var(--muted-bg));
}
.border-l {
  border-left: 1px solid oklch(var(--muted-bg));
}
.divide-y > * + * {
  border-top: 1px solid oklch(var(--muted-bg));
}

.rounded-md {
  border-radius: 8px;
}
.rounded-lg {
  border-radius: 10px;
}
.rounded-xl {
  border-radius: 16px;
}
.rounded-2xl {
  border-radius: 20px;
}
.rounded-full {
  border-radius: 9999px;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  transition:
    background-color 150ms,
    border-color 150ms,
    opacity 150ms;
  white-space: nowrap;
}
button:focus-visible,
[role='button']:focus-visible,
[role='radio']:focus-visible,
a:focus-visible {
  outline: 2px solid oklch(var(--action));
  outline-offset: 2px;
}
.btn-primary {
  background: oklch(var(--primary));
  color: white;
}
.btn-primary:hover {
  background: oklch(var(--primary) / 0.92);
}
.btn-action {
  background: oklch(var(--action));
  color: white;
}
.btn-action:hover {
  background: oklch(var(--action) / 0.92);
}
.btn-outline {
  background: white;
  color: oklch(var(--primary));
  border: 1px solid oklch(var(--muted-bg));
}
.btn-outline:hover {
  border-color: oklch(var(--muted));
}
.btn-ghost {
  background: transparent;
  color: oklch(var(--primary));
}
.btn-ghost:hover {
  background: oklch(var(--muted-bg) / 0.6);
}
.btn-sm {
  padding: 6px 10px;
  font-size: 13px;
}
.btn-pill {
  border-radius: 9999px;
  padding: 6px 12px;
  font-size: 13px;
}

/* Card */
.card {
  background: white;
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 16px;
}
.card-stat {
  background: white;
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 16px;
  padding: 16px 18px;
}
.card-stat-accent {
  border-left: 4px solid oklch(var(--primary));
  padding-left: 14px;
}

/* Status badges */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 9999px;
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
  white-space: nowrap;
}
.badge-success {
  background: oklch(var(--green-bg));
  color: oklch(var(--green));
}
.badge-warning {
  background: oklch(var(--orange-bg));
  color: oklch(var(--orange));
}
.badge-error {
  background: oklch(var(--error-bg));
  color: oklch(var(--error));
}
.badge-info {
  background: oklch(0.93 0.04 258);
  color: oklch(var(--action));
}
.badge-neutral {
  background: oklch(var(--muted-bg));
  color: oklch(var(--muted));
}
.badge-finance {
  background: oklch(var(--finance-soft));
  color: oklch(var(--finance));
}

/* Status dots */
.dot {
  width: 8px;
  height: 8px;
  border-radius: 9999px;
  display: inline-block;
}
.dot-success {
  background: oklch(var(--green));
}
.dot-warning {
  background: oklch(var(--orange));
}
.dot-error {
  background: oklch(var(--error));
}
.dot-info {
  background: oklch(var(--action));
}
.dot-ai {
  background: oklch(var(--ai));
}

.shadow-sm {
  box-shadow:
    0 1px 2px rgba(20, 20, 40, 0.04),
    0 1px 1px rgba(20, 20, 40, 0.04);
}
.shadow-panel {
  box-shadow:
    0 30px 60px -10px rgba(20, 20, 40, 0.18),
    0 8px 20px -8px rgba(20, 20, 40, 0.08);
}
.shadow-pill {
  box-shadow: 8px 8px 12px 0px oklch(var(--muted-bg));
}

/* Flex / grid utils */
.flex {
  display: flex;
}
.flex-col {
  flex-direction: column;
}
.items-center {
  align-items: center;
}
.items-start {
  align-items: flex-start;
}
.items-stretch {
  align-items: stretch;
}
.items-end {
  align-items: flex-end;
}
.items-baseline {
  align-items: baseline;
}
.justify-center {
  justify-content: center;
}
.justify-between {
  justify-content: space-between;
}
.justify-end {
  justify-content: flex-end;
}
.flex-1 {
  flex: 1 1 0;
  min-width: 0;
  min-height: 0;
}
.flex-wrap {
  flex-wrap: wrap;
}
.flex-shrink-0 {
  flex-shrink: 0;
}
.grid {
  display: grid;
}
.gap-1 {
  gap: 4px;
}
.gap-2 {
  gap: 8px;
}
.gap-3 {
  gap: 12px;
}
.gap-4 {
  gap: 16px;
}
.gap-5 {
  gap: 20px;
}
.gap-6 {
  gap: 24px;
}
.gap-8 {
  gap: 32px;
}

/* Sidebar floating pill enter */
@keyframes slideInLeft {
  from {
    opacity: 0;
    transform: translateX(-6px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
.anim-slide-in-left {
  animation: slideInLeft 150ms ease-out;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}
.anim-pulse {
  animation: pulse 2s ease-in-out infinite;
}

@keyframes popIn {
  from {
    opacity: 0;
    transform: translateY(4px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* Overlay (Modal/Drawer) enter — see src/shared/ui/overlay.tsx */
@keyframes overlayFade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes slideInRight {
  from {
    opacity: 0;
    transform: translateX(12px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
.anim-slide-in-right {
  animation: slideInRight 200ms ease-out;
}
/* Inline row editor expand — see ledger-catalogs RowEditor */
@keyframes expandDown {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Scrollbar (subtle) */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: oklch(var(--muted-bg));
  border-radius: 9999px;
  border: 2px solid oklch(var(--background));
}
::-webkit-scrollbar-thumb:hover {
  background: oklch(var(--secondary) / 0.5);
}

/* The Strategy-Builder view navigation scrolls sideways rather than wrapping,
   and a visible track would cost as much height as the row it protects. */
.sb-viewnav::-webkit-scrollbar {
  display: none;
}

/* Page transition (opacity-only on purpose) */
@keyframes pageFade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.page-fade {
  animation: pageFade 200ms ease-out;
}

/* Subtle hover lift for clickable cards */
.hover-lift {
  transition:
    border-color 150ms,
    transform 150ms,
    box-shadow 150ms;
}
.hover-lift:hover {
  border-color: oklch(var(--muted) / 0.5);
}

/* Glow for finance-related highlight */
.finance-glow {
  box-shadow:
    0 0 0 1px oklch(var(--finance) / 0.2),
    0 8px 24px -8px oklch(var(--finance) / 0.25);
}

/* Planning exposure-slider thumb / track */
.planning-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 9999px;
  background: white;
  border: 2px solid oklch(var(--finance));
  box-shadow: 0 1px 3px rgba(20, 20, 40, 0.18);
  cursor: pointer;
  margin-top: 0;
}
.planning-range::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 9999px;
  background: white;
  border: 2px solid oklch(var(--finance));
  box-shadow: 0 1px 3px rgba(20, 20, 40, 0.18);
  cursor: pointer;
}
.planning-range::-webkit-slider-runnable-track {
  background: transparent;
  height: 4px;
}
.planning-range::-moz-range-track {
  background: transparent;
  height: 4px;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}


/* /src/shared/design-system/components.css */
/* Cozero design system — form and band components, as classes.
   Companion to tokens.css; imported next to it in __root.tsx.

   These are the recipes that were previously written inline at every call site
   — an input's border and radius, a segmented toggle, the four coloured
   explanation bands — expressed once. A rule here may reference only tokens
   from tokens.css, never a literal colour, so a token change moves every
   component with it.

   Font family is deliberately absent: tokens.css sets the stack on `body` and
   `button`, and `input`/`select`/`textarea` do NOT inherit it by default, so
   `font: inherit` below is load-bearing rather than redundant. */

/* ---- inputs ---- */
.input,
.select,
.textarea {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 8px;
  background: white;
  font: inherit;
  font-size: 13px;
  color: oklch(var(--primary));
  outline: none;
}
.input:focus,
.select:focus,
.textarea:focus {
  border-color: oklch(var(--ring));
}
.textarea {
  min-height: 70px;
  resize: vertical;
  line-height: 1.45;
}
/* The chevron is a data: URI rather than an overlaid element so a <select> stays
   one focusable node. Its stroke is #6D7181 — the one literal colour in this
   file, because a url() cannot read a CSS variable. It matches --muted-2. */
.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236D7181' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
  padding-right: 28px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}
.field > .caption-bold {
  color: oklch(var(--muted));
}
/* A unit or currency inside the input's right edge. The suffix is
   pointer-events:none so clicking it still focuses the field. */
.input-suffix {
  position: relative;
}
/* The room reserved for the suffix FOLLOWS THE SUFFIX. It was a flat 64px,
   which a long unit overruns — "kgCO₂e/t·km" printed straight over the
   placeholder. `SuffixedInput` sets `--suffix-pad` from the suffix's own
   length; the fallback keeps hand-written markup working. */
.input-suffix .input {
  padding-right: var(--suffix-pad, 64px);
}
.input-suffix > span {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  color: oklch(var(--muted-2));
  pointer-events: none;
}
.money {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---- segmented toggle ---- */
.seg {
  display: inline-flex;
  gap: 2px;
  background: oklch(var(--muted-bg) / 0.5);
  padding: 3px;
  border-radius: 10px;
}
.seg > button {
  padding: 6px 12px;
  border-radius: 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: oklch(var(--muted));
  transition: background-color 120ms;
}
.seg > button.on {
  background: white;
  color: oklch(var(--primary));
  box-shadow:
    0 1px 2px rgba(20, 20, 40, 0.06),
    0 0 0 1px oklch(var(--muted-bg));
}

/* ---- inline add action ---- */
.add-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 600;
  color: oklch(var(--action));
  padding: 6px 4px;
  border-radius: 7px;
}
.add-link:hover {
  background: oklch(var(--muted-bg) / 0.4);
}

/* ---- separator ---- */
.hr {
  height: 1px;
  background: oklch(var(--muted-bg));
  border: 0;
  margin: 18px 0;
}

/* ---- explanation bands ----
   Four tones for one shape. The tone carries the meaning, so the copy never
   has to say "warning:" — success states a resolved fact, warn states an
   incomplete answer, error states a refusal, info states how something
   composes. */
.success-line,
.warn-line,
.error-line,
.info-line {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
  color: oklch(var(--muted));
  margin-top: 14px;
}
.success-line {
  background: oklch(var(--green-bg) / 0.55);
  border: 1px solid oklch(var(--green) / 0.25);
}
.warn-line {
  background: oklch(var(--orange-bg) / 0.7);
  border: 1px solid oklch(var(--orange) / 0.3);
}
.error-line {
  background: oklch(var(--error-bg) / 0.7);
  border: 1px solid oklch(var(--error) / 0.3);
}
.info-line {
  background: oklch(var(--finance-soft));
  border: 1px solid oklch(var(--finance) / 0.18);
  font-size: 12.5px;
}

/* A read-only strip of figures the author is working against — the starting
   emissions above an editor, the operating position below one. */
.baseline-strip {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  background: oklch(var(--muted-bg) / 0.35);
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 12px;
  padding: 11px 14px;
  margin-bottom: 16px;
  font-size: 13px;
  color: oklch(var(--muted));
}

/* ---- small chips ---- */
/* Names the per-year shape a section's values carry — "Discrete payments",
   "Step and hold". The three shapes must never be confused, so each section
   says which one it is. */
.sem-chip {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 5px;
  padding: 2px 7px;
  background: oklch(var(--muted-bg) / 0.8);
  color: oklch(var(--muted));
}
/* Where a picked thing came from. The author never needs to care, but seeing
   it makes "we already measure this" legible at a glance. */
.src-chip {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 5px;
  padding: 2px 6px;
}
.src-ccf {
  background: oklch(var(--green-bg));
  color: oklch(var(--green));
}
.src-core {
  background: oklch(0.93 0.04 258);
  color: oklch(var(--action));
}
.src-new {
  background: oklch(var(--orange-bg));
  color: oklch(var(--orange));
}
.scope-pill {
  width: 22px;
  height: 22px;
  border-radius: 6px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 10px;
  font-weight: 700;
}
.new-chip {
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
  background: oklch(0.93 0.04 258);
  color: oklch(var(--action));
  border-radius: 4px;
  padding: 1px 5px;
}

/* ---- card padding ---- */
.pane {
  padding: 22px 24px;
}


/* /src/features/simulate-action/wizard/wizard-components.css */
/* Simulate Action wizard — the components only this flow has.
   Imported once, from wizard-shell.tsx.

   The generic half (inputs, .seg, .field, the four explanation bands, the
   chips) lives in shared/design-system/components.css, because those recipes
   are not specific to authoring a reduction measure. What is here is: the
   pickers on steps 2-4, the two adjustment shapes on step 5, the phase-in row
   on step 6, the line-item editor on steps 7-8, and the result tiles and
   cash-flow table on step 9.

   Same rule as the shared file: tokens only, no literal colours. */

/* ---- Cobot bubble and step heading ---- */
.bubble {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 18px;
}
.bubble .avatar {
  width: 32px;
  height: 32px;
  border-radius: 9999px;
  background: oklch(var(--ai));
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  margin-top: 2px;
}
/* The square corner points at the avatar, which is what makes it read as
   speech rather than as a card. */
.bubble .say {
  background: white;
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 4px 14px 14px 14px;
  padding: 10px 14px;
  font-size: 14px;
  line-height: 1.5;
  color: oklch(var(--muted));
  max-width: 620px;
}
.step-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.step-title .ico {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  flex: none;
}

/* A step that cannot be left yet says why, in the footer next to the button
   rather than as a band above the form. */
.gate-msg {
  font-size: 12.5px;
  color: oklch(var(--orange));
  display: flex;
  align-items: center;
  gap: 6px;
}

/* ---- steps 2-4: pickable rows ---- */
.pick-row {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  text-align: left;
  padding: 9px 12px;
  border-radius: 9px;
  border: 1px solid oklch(var(--muted-bg));
  background: white;
  margin-bottom: 6px;
  transition:
    border-color 120ms,
    background-color 120ms;
  font-size: 13px;
}
.pick-row:hover {
  border-color: oklch(var(--secondary));
}
.pick-row.sel {
  border-color: oklch(var(--finance));
  background: oklch(var(--finance-soft));
  box-shadow: 0 0 0 1px oklch(var(--finance) / 0.35);
}
.pick-row .amt {
  margin-left: auto;
  font-size: 11.5px;
  color: oklch(var(--muted-2));
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---- step 4: narrowing ---- */
.narrow-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 11px 0 4px;
  color: oklch(var(--muted));
  font-size: 13px;
  font-weight: 600;
}
.narrow-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-top: 10px;
}
.narrow-card {
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 12px;
  padding: 11px 12px;
  background: white;
}
.narrow-card .hint {
  font-size: 11px;
  color: oklch(var(--muted-2));
  margin: 2px 0 8px;
}
.narrow-opt {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 6px;
  border-radius: 7px;
  width: 100%;
  text-align: left;
  font-size: 12.5px;
  color: oklch(var(--muted));
}
.narrow-opt:hover {
  background: oklch(var(--muted-bg) / 0.4);
}
.narrow-opt .cb {
  width: 15px;
  height: 15px;
  border-radius: 5px;
  border: 1.5px solid oklch(var(--secondary));
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}
.narrow-opt.on .cb {
  background: oklch(var(--finance));
  border-color: oklch(var(--finance));
}
.narrow-opt .sub {
  margin-left: auto;
  font-size: 10.5px;
  color: oklch(var(--muted-2));
  font-variant-numeric: tabular-nums;
}

/* ---- step 4: the switch's receiving activities ---- */
.recv-row {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 8px;
  background: white;
}
/* One wide panel: search, a grouped list, and create-new in its footer. Three
   sources of a receiving activity are presented as one picker on purpose —
   the author never needs to know which of the three they used. */
.picker-pop {
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 12px;
  background: white;
  box-shadow:
    0 30px 60px -10px rgba(20, 20, 40, 0.18),
    0 8px 20px -8px rgba(20, 20, 40, 0.08);
  padding: 10px;
  margin-top: 8px;
}
.picker-pop .grp {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: oklch(var(--muted-2));
  padding: 8px 8px 4px;
}
.picker-opt {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 7px 8px;
  border-radius: 8px;
  font-size: 13px;
}
.picker-opt:hover {
  background: oklch(var(--muted-bg) / 0.45);
}
.picker-opt .sub {
  margin-left: auto;
  font-size: 11px;
  color: oklch(var(--muted-2));
  font-variant-numeric: tabular-nums;
}

/* ---- step 5: the two adjustment shapes ---- */
.adj-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.adj-card {
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 12px;
  padding: 14px 15px;
  background: white;
  position: relative;
}
/* `.live` marks the adjustments the author has actually authored. Either alone
   is a complete measure, so neither card can be styled as the primary one. */
.adj-card.live {
  border-color: oklch(var(--finance) / 0.45);
  box-shadow: 0 0 0 1px oklch(var(--finance) / 0.2);
}
.delta-badge {
  position: absolute;
  top: 12px;
  right: 12px;
}
/* Claims against the donor activity, which are validated together against
   100% — an initiative cannot switch away more than it has. */
.total-bar {
  height: 8px;
  border-radius: 9999px;
  background: oklch(var(--muted-bg));
  overflow: hidden;
  margin-top: 6px;
}
.total-bar > div {
  height: 100%;
  border-radius: 9999px;
  background: oklch(var(--finance));
  transition: width 200ms;
}
.total-bar.over > div {
  background: oklch(var(--error));
}

/* ---- step 6: the phase-in ----
   One cell per year of the lifetime, all on one row, so each year lines up
   with its bar in the preview below. Long lifetimes scroll horizontally
   rather than wrapping, which would break that alignment.

   ONE SCROLLER AROUND BOTH the cells and the preview, which is what keeps
   that alignment true past ~13 years: with a scrollbar on the cells alone, a
   15-year lifetime scrolled the cells while the bars stayed put, so the year
   under a bar was not the year in the cell above it. Both tracks share
   `flex: 1 1 0` and the same min-width, so a column is one year wide in both. */
.phase-scroll {
  overflow-x: auto;
  padding-bottom: 4px;
}
.phase-grid {
  display: flex;
  gap: 6px;
  margin-top: 12px;
}
.phase-cell {
  flex: 1 1 0;
  min-width: 58px;
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 9px;
  padding: 6px 7px;
  background: white;
}
.phase-cell .yr {
  font-size: 10.5px;
  font-weight: 600;
  color: oklch(var(--muted-2));
  display: flex;
  justify-content: space-between;
}
.phase-cell input {
  width: 100%;
  border: 0;
  outline: none;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: oklch(var(--primary));
  padding: 2px 0 0;
  background: transparent;
  font-variant-numeric: tabular-nums;
}
.phase-preview {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 54px;
  margin-top: 14px;
}
.phase-preview .pb {
  flex: 1 1 0;
  min-width: 58px;
  background: oklch(var(--finance) / 0.75);
  border-radius: 3px 3px 0 0;
  min-height: 2px;
  position: relative;
}
.phase-preview .pb span {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  font-size: 8.5px;
  color: oklch(var(--muted-2));
  padding-bottom: 2px;
  white-space: nowrap;
}

/* ---- steps 7-8: the line-item editor ----
   One shape for capex, opex and revenue. A name, a value, and the period it
   applies to — the per-year semantics differ, and the section's .sem-chip
   says which, but the editor does not. */
.line-item {
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 12px;
  padding: 13px 14px;
  margin-bottom: 10px;
  background: white;
}
.li-head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.li-head .input {
  flex: 1;
}
.li-del {
  color: oklch(var(--muted-2));
  padding: 6px;
  border-radius: 7px;
  flex: none;
}
.li-del:hover {
  color: oklch(var(--error));
  background: oklch(var(--error-bg) / 0.5);
}
.li-body {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: flex-end;
  margin-top: 10px;
}
.sched-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 7px;
}

/* ---- step 9: the metric tiles ---- */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
.kpi {
  background: white;
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 16px;
  padding: 14px 16px;
  position: relative;
}
.kpi .lbl {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: oklch(var(--muted-2));
  display: flex;
  align-items: center;
  gap: 6px;
}
.kpi .val {
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-top: 5px;
  font-variant-numeric: tabular-nums;
}
.kpi .hint {
  font-size: 10.5px;
  color: oklch(var(--muted-2));
  margin-top: 3px;
}
/* The two tiles the cash-flow table's cumulative columns reconcile to. The
   lift is the visual claim that nothing is unaccounted for between them. */
.kpi.reconciled {
  box-shadow:
    0 0 0 1px oklch(var(--finance) / 0.2),
    0 8px 24px -8px oklch(var(--finance) / 0.25);
}

/* ---- step 9: the working ---- */
.cf-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.cf-table th {
  text-align: right;
  padding: 9px 10px;
  background: oklch(var(--muted-bg) / 0.25);
  border-bottom: 1px solid oklch(var(--muted-bg));
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: oklch(var(--table-header));
  white-space: nowrap;
}
.cf-table th:first-child,
.cf-table td:first-child {
  text-align: left;
}
.cf-table td {
  text-align: right;
  padding: 8px 10px;
  border-bottom: 1px solid oklch(var(--muted-bg) / 0.6);
  font-variant-numeric: tabular-nums;
  color: oklch(var(--muted));
  white-space: nowrap;
}
.cf-table tr:last-child td {
  border-bottom: 0;
  font-weight: 600;
  color: oklch(var(--primary));
  background: oklch(var(--finance-soft) / 0.6);
}
.legend {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 8px;
}
.legend .li {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: oklch(var(--muted));
}
.legend .box {
  width: 11px;
  height: 11px;
  border-radius: 2px;
}
.chart-tip {
  position: fixed;
  z-index: 90;
  background: white;
  border: 1px solid oklch(var(--muted-bg));
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(20, 20, 40, 0.12);
  padding: 9px 12px;
  min-width: 170px;
  max-width: 280px;
  pointer-events: none;
  display: none;
}
.jump-links {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  margin-top: 16px;
}
.jump-links button {
  font-size: 12.5px;
  font-weight: 600;
  color: oklch(var(--action));
  display: inline-flex;
  gap: 5px;
  align-items: center;
}

/* Two columns rather than four once four will not fit, then one. The
   adjustment pair collapses on the same breakpoints. */
@media (max-width: 900px) {
  .adj-grid,
  .kpi-grid {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 560px) {
  .adj-grid,
  .kpi-grid {
    grid-template-columns: 1fr;
  }
}
