/* ============================================================================
   Paddy — cashflow forecaster.
   Shell tokens come from /shared/porter-tokens.css (loaded first). This file
   holds Paddy's signature accents and its components, per the per-app
   icon-colour model (DESIGN.md).
   ============================================================================ */

:root {
  /* Paddy signature hues — green primary + spring-green support (the icon's
     stone ramp, dark→bright). */
  --accent:        #3fae6a;
  --accent-dim:    #2a7d4a;
  --accent-bright: #5fe88f;
  --accent-tint:   rgba(63, 174, 106, 0.15);
  --support:       #5fe88f;
  --support-dim:   #2f9e57;
  --support-tint:  rgba(95, 232, 143, 0.15);
  --hdr-h: 64px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { overflow-x: hidden; }
html { scrollbar-gutter: stable; -webkit-font-smoothing: antialiased; }
body {
  background: var(--bg); color: var(--text);
  font-family: var(--font-body); font-weight: 300;
  min-height: 100dvh; display: flex; flex-direction: column;
  padding-top: calc(var(--hdr-h) + env(safe-area-inset-top));
  font-size: var(--fs-base); -webkit-tap-highlight-color: transparent;
}
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
/* The app toggles visibility via the HTML `hidden` attribute; without this,
   any rule that sets `display` (modal scrims, flex panels) silently defeats
   the attribute and the element renders anyway. */
[hidden] { display: none !important; }

/* ── Header (shared chrome, DESIGN.md) ────────────────────────────────────── */
.app-header {
  background: var(--surface); border-bottom: 1px solid var(--border);
  padding-top: env(safe-area-inset-top);
  position: fixed; top: 0; left: 0; right: 0; z-index: var(--z-sticky);
}
.header-inner {
  max-width: var(--app-width); margin: 0 auto; height: var(--hdr-h);
  padding: 0 var(--app-pad); display: flex; align-items: center;
  justify-content: space-between; gap: var(--space-sm);
}
.app-title {
  display: flex; align-items: center; gap: 11px; min-width: 0;
  font-family: var(--font-display); font-weight: 500; font-size: var(--fs-lg);
  letter-spacing: 3px; text-transform: uppercase; color: var(--text);
}
.back-link {
  font-family: var(--font-mono); font-weight: 400; font-size: var(--fs-2xs);
  letter-spacing: 0.5px; text-transform: uppercase; color: var(--text-muted);
  text-decoration: none; transition: color var(--motion-base); flex-shrink: 0;
}
.back-link:hover { color: var(--steel); }
.header-divider { width: 1px; height: 1.2em; background: var(--border); flex-shrink: 0; }
.app-title-icon { display: block; width: 1.7em; height: 1.7em; flex-shrink: 0; }
.wordmark { display: inline-block; color: var(--text); }
.app-title .dot { color: var(--accent); margin-left: -1px; }

/* Header tabs — active takes the app hue, inactive steel (DESIGN.md). */
.header-tabs { display: flex; gap: var(--space-2xs); }
.header-tabs .tab {
  font-family: var(--font-mono); font-size: var(--fs-2xs); text-transform: uppercase;
  letter-spacing: var(--ls-label); color: var(--text-muted); white-space: nowrap;
  padding: var(--space-2xs) var(--space-sm); border-radius: var(--radius-sm);
  transition: color var(--motion-fast), background var(--motion-fast);
}
.header-tabs .tab:hover { color: var(--steel); }
.header-tabs .tab.active { color: var(--accent); background: var(--surface-2); }

/* ── Layout spine ─────────────────────────────────────────────────────────── */
.app-main {
  width: 100%; max-width: var(--app-width); margin: 0 auto;
  padding: var(--space-lg) var(--app-pad) var(--space-2xl);
  display: flex; flex-direction: column; gap: var(--space-md); flex: 1;
}
.view { display: none; flex-direction: column; gap: var(--space-md); }
.view.active { display: flex; }

/* ── Cards ────────────────────────────────────────────────────────────────── */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--space-md);
}
.card-title {
  font-family: var(--font-display); font-weight: 500; font-size: var(--fs-md);
  letter-spacing: var(--ls-title); text-transform: uppercase; color: var(--accent);
}
.card-title-row {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-sm);
}
.settings-card > .card-title:only-of-type { margin-bottom: var(--space-sm); }

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn {
  font-family: var(--font-body); font-weight: 400; font-size: var(--fs-sm);
  padding: var(--space-xs) var(--space-md); border-radius: var(--radius);
  transition: background var(--motion-fast), color var(--motion-fast),
              border-color var(--motion-fast);
  border: 1px solid transparent; white-space: nowrap;
}
.btn-primary { background: var(--accent); color: var(--bg); font-weight: 500; }
.btn-primary:hover { background: var(--accent-bright); }
.btn-secondary { border-color: var(--border); color: var(--text-muted); }
.btn-secondary:hover { color: var(--steel); border-color: var(--steel-dim); }
.btn-danger { border-color: var(--danger); color: var(--danger); }
.btn-danger:hover { background: var(--danger-tint); }
.link-btn { color: var(--accent); text-decoration: underline; font-size: inherit; }

/* ── Inputs ───────────────────────────────────────────────────────────────── */
input[type="text"], input[type="number"], input[type="date"], select {
  width: 100%; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); color: var(--text);
  font-family: var(--font-body); font-size: var(--fs-base);
  padding: var(--space-xs) var(--space-sm); color-scheme: dark;
  transition: border-color var(--motion-fast);
}
input:focus, select:focus { outline: none; border-color: var(--accent); }
input[inputmode="decimal"], input[type="number"], input[type="date"] {
  font-family: var(--font-mono);
}
label {
  display: flex; flex-direction: column; gap: var(--space-3xs);
  font-size: var(--fs-xs); color: var(--text-muted);
}

.money-input-wrap { position: relative; }
.money-input-wrap .money-prefix {
  position: absolute; left: var(--space-sm); top: 50%; transform: translateY(-50%);
  font-family: var(--font-mono); color: var(--text-dim); pointer-events: none;
}
.money-input-wrap input { padding-left: calc(var(--space-sm) + 1.1ch + var(--space-3xs)); }

/* ── Forecast control bar ─────────────────────────────────────────────────── */
.balance-label {
  font-family: var(--font-mono); font-size: var(--fs-2xs); text-transform: uppercase;
  letter-spacing: var(--ls-label); color: var(--text-muted);
  margin-bottom: var(--space-xs);
}
.control-row { display: flex; gap: var(--space-sm); align-items: stretch; }
.control-row .money-input-wrap { flex: 1; max-width: 16rem; }
#balance-input { font-size: var(--fs-lg); font-weight: 500; padding-top: var(--space-2xs); padding-bottom: var(--space-2xs); }

/* What-if panel — sandbox styling leans on the support (spring) hue with a
   dashed border: visibly "not the saved world". */
.whatif-panel {
  margin-top: var(--space-sm); padding: var(--space-sm);
  border: 1px dashed var(--support-dim); border-radius: var(--radius);
  background: var(--support-tint);
}
.whatif-head {
  font-family: var(--font-mono); font-size: var(--fs-2xs); text-transform: uppercase;
  letter-spacing: var(--ls-label); color: var(--support);
  margin-bottom: var(--space-xs);
}
.whatif-form { display: flex; gap: var(--space-xs); flex-wrap: wrap; }
.whatif-form input, .whatif-form select { width: auto; flex: 1; min-width: 7rem; }
.whatif-form .money-input-wrap { flex: 1; min-width: 8rem; }
.whatif-form .money-input-wrap input { width: 100%; }
.whatif-chips { display: flex; gap: var(--space-xs); flex-wrap: wrap; margin-top: var(--space-xs); }
.whatif-chips:empty { margin-top: 0; }
.chip {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  border: 1px solid var(--support-dim); border-radius: var(--radius-pill);
  padding: var(--space-3xs) var(--space-xs); color: var(--support);
}
.chip button { color: var(--text-muted); font-size: var(--fs-sm); line-height: 1; }
.chip button:hover { color: var(--danger); }

/* Drift chip — projected vs actual, shown after generate. */
.drift-chip {
  margin-top: var(--space-sm); display: inline-flex; align-items: baseline; gap: var(--space-xs);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-muted);
}
.drift-chip .delta { font-weight: 500; }
.drift-chip .delta.pos { color: var(--accent-bright); }
.drift-chip .delta.neg { color: var(--danger); }

/* ── Empty state ──────────────────────────────────────────────────────────── */
.forecast-empty {
  text-align: center; color: var(--text-muted); padding: var(--space-2xl) var(--space-md);
  display: flex; flex-direction: column; gap: var(--space-sm);
}
.forecast-empty .hint { font-size: var(--fs-sm); color: var(--text-dim); }

/* ── Verdict hero ─────────────────────────────────────────────────────────── */
.forecast-result { display: flex; flex-direction: column; gap: var(--space-md); }
.verdict { padding: var(--space-md) var(--space-2xs); }
.verdict-line {
  font-family: var(--font-display); font-weight: 500; font-size: var(--fs-xl);
  line-height: 1.25; letter-spacing: var(--ls-title);
}
.verdict-line .ok { color: var(--accent-bright); }
.verdict-line .bad { color: var(--danger); }
.verdict-line .figure { font-family: var(--font-mono); font-weight: 500; }
.verdict-stats {
  display: flex; gap: var(--space-lg); flex-wrap: wrap; margin-top: var(--space-sm);
}
.vstat { display: flex; flex-direction: column; gap: var(--space-3xs); }
.vstat .k {
  font-family: var(--font-mono); font-size: var(--fs-2xs); text-transform: uppercase;
  letter-spacing: var(--ls-label); color: var(--text-dim);
}
.vstat .v { font-family: var(--font-mono); font-size: var(--fs-base); color: var(--text); }
.vstat .v.neg { color: var(--danger); }

/* ── Chart ────────────────────────────────────────────────────────────────── */
.chart-card { padding: var(--space-sm) var(--space-sm) var(--space-xs); }
.chart-wrap { height: 300px; position: relative; }

/* ── Ledger table — the dense zone. Compact opt-in: a running statement is
   read in long vertical sweeps, so rows tighten to keep months on screen. ── */
.ledger-card { padding: var(--space-2xs) 0; overflow: hidden; }
.ledger { width: 100%; border-collapse: collapse; font-family: var(--font-mono); }
.ledger th {
  font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: var(--ls-label);
  color: var(--text-dim); font-weight: 400; text-align: right;
  padding: var(--space-xs) var(--space-sm); border-bottom: 1px solid var(--border);
}
.ledger th:first-child, .ledger th:nth-child(2) { text-align: left; }
.ledger td {
  font-size: var(--fs-xs); padding: var(--space-2xs) var(--space-sm);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 45%, transparent);
  text-align: right; white-space: nowrap;
}
.ledger td.date { color: var(--text-dim); text-align: left; width: 5.5rem; }
.ledger td.name {
  font-family: var(--font-body); font-weight: 400; color: var(--text);
  text-align: left; max-width: 0; width: 50%;
  overflow: hidden; text-overflow: ellipsis;
}
.ledger td.amt.pos { color: var(--accent-bright); }
.ledger td.amt.neg { color: var(--text-muted); }
.ledger td.bal { font-weight: 500; }
.ledger tr.below td.bal { color: var(--danger); }
.ledger tr.below { background: var(--danger-tint); }
.ledger tr.start td { color: var(--text-muted); font-style: italic; }
.ledger tr.whatif td.name { color: var(--support); font-style: italic; }
.ledger tr.whatif { background: var(--support-tint); }
.ledger tr.month-sep td {
  font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: var(--ls-label);
  color: var(--accent); text-align: left; background: var(--surface-2);
  padding-top: var(--space-2xs); padding-bottom: var(--space-2xs); font-style: normal;
}
/* Per-occurrence skip control — visible on hover (desktop); always-on at
   reduced opacity on touch (no hover). */
.skip-btn {
  color: var(--text-dim); font-size: var(--fs-xs); padding: 0 var(--space-3xs);
  opacity: 0; transition: opacity var(--motion-fast), color var(--motion-fast);
}
.ledger tr:hover .skip-btn { opacity: 1; }
.skip-btn:hover { color: var(--warn); }
@media (hover: none) { .skip-btn { opacity: 0.5; } }

/* ── History ──────────────────────────────────────────────────────────────── */
.history-list { display: flex; flex-direction: column; gap: var(--space-sm); }
.snap-card {
  display: flex; align-items: center; gap: var(--space-md);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--space-sm) var(--space-md);
  text-align: left; transition: border-color var(--motion-fast);
}
.snap-card:hover { border-color: var(--accent-dim); }
.snap-when { display: flex; flex-direction: column; gap: var(--space-3xs); min-width: 7rem; }
.snap-when .d { font-family: var(--font-display); font-size: var(--fs-base); color: var(--text); }
.snap-when .t { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--text-dim); }
.snap-meta { display: flex; gap: var(--space-lg); flex-wrap: wrap; flex: 1; }
.snap-verdict { font-family: var(--font-mono); font-size: var(--fs-xs); }
.snap-verdict.ok { color: var(--accent-bright); }
.snap-verdict.bad { color: var(--danger); }
.snap-del { color: var(--text-dim); font-size: var(--fs-base); padding: var(--space-2xs); }
.snap-del:hover { color: var(--danger); }
.snapshot-banner {
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-muted);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--space-xs) var(--space-sm);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-sm); flex-wrap: wrap;
}
.snapshot-banner .banner-actions { display: flex; gap: var(--space-xs); }
.history-empty { color: var(--text-dim); text-align: center; padding: var(--space-xl); }

/* ── Settings ─────────────────────────────────────────────────────────────── */
.settings-grid { display: flex; gap: var(--space-md); flex-wrap: wrap; margin-top: var(--space-sm); }
.settings-grid label { flex: 1; min-width: 10rem; max-width: 14rem; }
.settings-save-row { margin-top: var(--space-sm); display: flex; justify-content: flex-end; }

/* Recurring + one-time side by side on desktop (tightened Settings). */
.settings-cols {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md);
  align-items: start;
}

.rule-list, .oneoff-list, .skip-list { display: flex; flex-direction: column; }
.rule-row, .oneoff-row, .skip-row {
  display: flex; align-items: center; gap: var(--space-sm);
  padding: var(--space-xs) 0; border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}
.rule-row:last-child, .oneoff-row:last-child, .skip-row:last-child { border-bottom: none; }
.rule-row.inactive { opacity: 0.45; }
.rule-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-md); }
.rule-name .sub {
  display: block; font-family: var(--font-mono); font-size: var(--fs-2xs);
  color: var(--text-dim); text-transform: uppercase; letter-spacing: var(--ls-label);
  margin-top: 2px;
}
.rule-name .sub .pending-change { color: var(--warn); text-transform: none; letter-spacing: 0; }
.rule-amt { font-family: var(--font-mono); font-size: var(--fs-md); white-space: nowrap; }
.rule-amt.pos { color: var(--accent-bright); }
.rule-amt.neg { color: var(--text-muted); }
.row-edit, .row-del {
  font-family: var(--font-mono); font-size: var(--fs-2xs); text-transform: uppercase;
  letter-spacing: var(--ls-label); color: var(--text-dim);
  padding: var(--space-2xs) var(--space-xs); border: 1px solid var(--border);
  border-radius: var(--radius-sm); transition: color var(--motion-fast), border-color var(--motion-fast);
}
.row-edit:hover { color: var(--steel); border-color: var(--steel-dim); }
.row-del:hover { color: var(--danger); border-color: var(--danger); }
.list-empty { color: var(--text-dim); font-size: var(--fs-sm); padding: var(--space-sm) 0; }

/* ── Modals (shared shapes, DESIGN.md) ────────────────────────────────────── */
.modal-scrim {
  position: fixed; inset: 0; background: rgba(0, 0, 0, 0.75);
  z-index: var(--z-overlay); display: flex; align-items: center; justify-content: center;
  padding: var(--space-md);
}
.modal-box {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-modal);
  width: 100%; max-width: 480px; max-height: 90dvh; overflow-y: auto;
  animation: modal-in var(--motion-base);
}
@keyframes modal-in { from { opacity: 0; transform: translateY(10px); } }
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-md); border-bottom: 1px solid var(--border);
}
.modal-title {
  font-family: var(--font-display); font-weight: 500; font-size: var(--fs-md);
  letter-spacing: var(--ls-title); text-transform: uppercase; color: var(--text);
}
.modal-close { color: var(--text-muted); font-size: var(--fs-lg); line-height: 1; }
.modal-close:hover { color: var(--text); }
.modal-body { padding: var(--space-md); display: flex; flex-direction: column; gap: var(--space-sm); }
.field-row { display: flex; gap: var(--space-sm); }
.field-row label { flex: 1; }
.modal-foot {
  display: flex; justify-content: flex-end; gap: var(--space-sm);
  padding: var(--space-md); border-top: 1px solid var(--border);
}
.modal-foot .btn-danger { margin-right: auto; }
/* Lightweight confirm: small box, message + two actions; the danger button is
   the confirm here (not destructive-left) so it reads as the primary choice. */
.confirm-box { max-width: 380px; }
.confirm-box .modal-body { font-size: var(--fs-base); color: var(--text); }
.confirm-box .modal-foot { border-top: none; padding-top: 0; }
.confirm-box .modal-foot .btn-danger { margin-right: 0; }

/* Scheduled-changes block inside the rule modal. */
.changes-block {
  border-top: 1px solid var(--border); padding-top: var(--space-sm);
  display: flex; flex-direction: column; gap: var(--space-xs);
}
.changes-head {
  font-family: var(--font-mono); font-size: var(--fs-2xs); text-transform: uppercase;
  letter-spacing: var(--ls-label); color: var(--text-muted);
}
.changes-list { display: flex; flex-direction: column; gap: var(--space-2xs); }
.change-row {
  display: flex; align-items: center; gap: var(--space-sm);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text);
}
.change-row .when { color: var(--warn); }
.change-row button { color: var(--text-dim); margin-left: auto; }
.change-row button:hover { color: var(--danger); }
.changes-form { display: flex; gap: var(--space-xs); }
.changes-form input { flex: 1; min-width: 0; }

/* ── Toast — top-center, just below the header, where the eye already is
   (bottom snackbars sink out of view on sparse pages — Nick, 2026-06-10). ── */
.toast {
  position: fixed; top: calc(var(--hdr-h) + env(safe-area-inset-top) + var(--space-sm));
  left: 50%; transform: translateX(-50%); z-index: var(--z-toast);
  background: var(--surface-3); border: 1px solid var(--accent-dim);
  border-radius: var(--radius); padding: var(--space-xs) var(--space-md);
  font-size: var(--fs-sm); box-shadow: var(--shadow-pop); max-width: 90vw;
  animation: toast-in var(--motion-base);
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, -6px); } }
.toast.error { border-color: var(--danger); color: var(--danger); }

/* ── Footer (shared chrome, DESIGN.md) ────────────────────────────────────── */
.app-footer {
  margin-top: auto; text-align: center;
  font-family: var(--font-mono); font-size: var(--fs-2xs); letter-spacing: 0.4px;
  color: var(--text-dim); opacity: 0.7;
  padding: 24px 16px calc(24px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border);
}
.app-footer .sep { opacity: 0.5; margin: 0 7px; }

/* ── Mobile ───────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
  html { font-size: 15px; }
  /* Phone header matches Castor's: the inner spine wraps to two rows —
     identity (back · icon · title), then a full-width tab row — and --hdr-h
     grows to reserve the taller bar. Same silhouette in every tabbed app. */
  :root { --hdr-h: 98px; }
  .header-inner { flex-wrap: wrap; gap: 8px 0; height: auto; padding: 12px 14px; }
  .app-title { font-size: var(--fs-lg); letter-spacing: 2px; flex: 1 1 100%; min-width: 0; }
  .header-tabs {
    flex: 1 1 100%; gap: 4px; overflow-x: auto; -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap; scrollbar-width: none;
  }
  .header-tabs::-webkit-scrollbar { display: none; }
  .header-tabs .tab { padding: 7px 12px; flex-shrink: 0; }
  .app-main { padding-left: 14px; padding-right: 14px; }
  .control-row { flex-wrap: wrap; }
  .control-row .money-input-wrap { max-width: none; width: 100%; flex-basis: 100%; }
  .control-row .btn { flex: 1; }
  .chart-wrap { height: 220px; }
  .verdict-line { font-size: var(--fs-lg); }
  .verdict-stats { gap: var(--space-md); }
  .ledger td.date { width: 4.2rem; }
  .field-row { flex-direction: column; }
  .snap-meta { gap: var(--space-sm); }
  .settings-cols { grid-template-columns: 1fr; }
}
