/* ==========================================================================
   AceBudget: app shell layout.
   Loaded after base.css. Reuses its tokens/components only: no new colors,
   no new button styles. Sidebar nav collapses to a bottom tab bar < 720px.
   ========================================================================== */

/* --- small utilities not in base.css --- */
.hook-caption {
  color: var(--brand-600);
  font-weight: 600;
  font-size: var(--fs-sm);
  margin-top: -4px;
}
:root[data-theme="dark"] .hook-caption { color: var(--brand-300); }
.fs-xs { font-size: var(--fs-xs); }
.fs-sm { font-size: var(--fs-sm); }
.fs-lg { font-size: var(--fs-lg); }
.text-bad { color: var(--bad); }
.field-error { color: var(--bad); font-size: var(--fs-xs); min-height: 1.2em; }
.form-actions { flex-wrap: wrap; }
.plain-list { list-style: none; }
.plain-list li { padding: var(--sp-2) 0; border-bottom: 1px solid var(--line-soft); }
.plain-list li:last-child { border-bottom: none; }

/* --- app shell --- */
.app-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas: "topbar topbar" "nav main";
  min-height: 100vh;
}

.app-topbar {
  grid-area: topbar;
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-3) var(--sp-5);
  background: var(--surface); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 20;
}
.brand-mark { font-size: 1.2em; }
/* Keep the top bar on one line: badges and buttons never wrap, the household
   name shortens with an ellipsis and steps aside on the narrowest phones. */
.app-topbar { gap: var(--sp-2); }
.app-topbar > .row:first-child { min-width: 0; }
.app-topbar .pill, .app-topbar .btn, .app-topbar select { white-space: nowrap; flex-shrink: 0; }
.topbar-household { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 420px) { .topbar-household { display: none; } }

.app-nav {
  grid-area: nav;
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--sp-4) var(--sp-3);
  background: var(--surface-2); border-right: 1px solid var(--line);
  align-self: stretch;
}
.nav-link {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 10px 12px; border-radius: var(--r-md);
  color: var(--text-soft); text-decoration: none; font-weight: 600; font-size: var(--fs-sm);
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.nav-link:hover { background: var(--surface-3); color: var(--ink); }
.nav-link-active { background: var(--ok-bg); color: var(--ok); }
.nav-icon { font-size: 1.1em; width: 1.4em; text-align: center; }

.app-main { grid-area: main; padding: var(--sp-5); min-width: 0; }
.app-content { max-width: var(--maxw); }

@media (max-width: 720px) {
  .app-shell { grid-template-columns: 1fr; grid-template-areas: "topbar" "main" "nav"; }
  .app-nav {
    flex-direction: row; justify-content: space-between; overflow-x: auto;
    border-right: none; border-top: 1px solid var(--line);
    position: sticky; bottom: 0; padding: var(--sp-2);
  }
  .nav-link { flex-direction: column; gap: 2px; padding: 6px 8px; font-size: var(--fs-xs); white-space: nowrap; }
  .app-main { padding: var(--sp-3); padding-bottom: var(--sp-8); }
}

/* --- onboarding --- */
.onboard-screen { min-height: 100vh; display: flex; flex-direction: column; background: var(--canvas); }
.onboard-body { flex: 1 1 auto; display: flex; align-items: center; padding: var(--sp-5) 0; }
.onboard-wrap { max-width: 480px; }
.onboard-form { padding: var(--sp-6); }

/* Brand band across the top of the welcome and lock screens. 192px tall
   (about 2in at 96dpi) at every width, with the text centred on both axes.
   On narrow screens the text wraps to two or three lines and still sits
   inside the 192px band, so the height stays constant. */
.brand-banner {
  min-height: 192px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6) var(--sp-5);
  background: var(--brand-600);
  color: #fff;
  text-align: center;
}
.brand-banner-text {
  max-width: var(--maxw);
  font-size: var(--fs-md);
  font-weight: 700;
  line-height: 1.6;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* --- dashboard grid --- */
.grid { display: grid; gap: var(--sp-4); }
.dashboard-grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); align-items: start; }
.runway-card { grid-column: span 1; }
.runway-number { font-size: var(--fs-4xl); font-weight: 800; letter-spacing: -0.02em; color: var(--ink); line-height: 1; margin-top: var(--sp-2); }
.spark { line-height: 0; }
.legend { list-style: none; display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-sm); }
.legend li { display: flex; align-items: center; gap: 8px; }
.legend .dot { border-radius: 50%; }

/* --- dashboard layout (hero / charts / cards rows) --- */
.dashboard-stack > * + * { margin-top: var(--sp-4); }
.dashboard-hero { grid-template-columns: 1.15fr 1fr; align-items: stretch; }
.dashboard-charts { grid-template-columns: 1.6fr 1fr; align-items: stretch; }
.dashboard-cards { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); align-items: start; }
@media (max-width: 900px) {
  .dashboard-hero, .dashboard-charts { grid-template-columns: 1fr; }
}
.dashboard-stack .card { transition: box-shadow .2s var(--ease), transform .2s var(--ease); }
.dashboard-stack .card:hover { box-shadow: var(--sh-2); transform: translateY(-2px); }

/* --- runway gauge --- */
.gauge-host { display: flex; justify-content: center; padding: var(--sp-2) 0; }
.gauge { position: relative; display: flex; justify-content: center; width: 100%; }
.gauge-svg { display: block; width: 100%; max-width: 240px; height: auto; }
.gauge-center {
  position: absolute; top: 58%; left: 50%; transform: translate(-50%, -50%);
  text-align: center; pointer-events: none;
}
.gauge-number { font-size: var(--fs-4xl); font-weight: 800; letter-spacing: -0.02em; color: var(--ink); line-height: 1; }
.gauge-caption { margin-top: 2px; }

/* --- month-over-month comparison --- */
.compare-grid { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: var(--sp-4) var(--sp-3); margin-top: var(--sp-3); }
.compare-stat { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.compare-stat .row { flex-wrap: wrap; row-gap: 4px; }
.compare-stat .num { white-space: nowrap; }
.delta { font-size: var(--fs-xs); font-weight: 700; padding: 2px 7px; border-radius: var(--r-full); white-space: nowrap; }
.delta-good { background: var(--ok-bg); color: var(--ok); }
.delta-bad  { background: var(--bad-bg); color: var(--bad); }
.delta-flat { background: var(--surface-3); color: var(--text-mute); }

/* --- interactive charts (ui/render.js interactiveLineChart / interactiveDonut) --- */
.chart-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.flow-chart-wrap { position: relative; }
.flow-chart { display: block; width: 100%; }
.chart-dot { transition: r .15s var(--ease); }
.chart-dot-active { stroke: var(--surface); stroke-width: 1.5; }
.chart-tooltip {
  position: absolute; transform: translate(-50%, -100%);
  background: var(--ink); color: var(--surface); padding: 6px 10px;
  border-radius: var(--r-md); font-size: var(--fs-xs); line-height: 1.5;
  box-shadow: var(--sh-2); pointer-events: none; white-space: nowrap;
  opacity: 0; transition: opacity .15s var(--ease); z-index: 10;
}
:root[data-theme="dark"] .chart-tooltip { background: var(--surface-3); color: var(--text); border: 1px solid var(--line); }

.legend-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; }
.legend-item { cursor: pointer; border-radius: var(--r-sm); padding: 3px 4px; transition: background-color .15s var(--ease); }
.legend-item:hover, .legend-item:focus-visible { background: var(--surface-3); }

.donut-row { align-items: center; gap: var(--sp-5); flex-wrap: wrap; }
.donut-host { flex: 0 0 auto; }
.donut-seg { cursor: pointer; transition: stroke-width .18s var(--ease), opacity .18s var(--ease); }

.breakdown-list { max-height: 220px; overflow-y: auto; }
.breakdown-row { transition: background-color .6s var(--ease); border-radius: var(--r-sm); padding: var(--sp-2) var(--sp-1); }
.breakdown-row-flash { background: var(--ok-bg); }

/* --- forms --- */
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--sp-3); }
/* Labels vary in length ("Target" vs "Planned monthly contribution") and wrap
   to different line counts. Reserving a fixed two-line height, with the label
   text bottom-aligned inside it, keeps every input in the row on the same
   line regardless of how its own label wraps. */
.form-row .field > label {
  min-height: calc(var(--fs-sm) * 1.4 * 2);
  line-height: 1.4;
  display: flex;
  align-items: flex-end;
}
.month-nav { justify-content: flex-end; }

/* --- progress bars (used by ui/render.js barRow) --- */
.bar-row { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-sm); }
.bar-track { height: 8px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.bar-fill { height: 100%; border-radius: var(--r-full); transition: width .3s var(--ease); }
.budget-row { align-items: center; gap: var(--sp-4); }
.budget-row input[type="number"] { width: 110px; }

/* --- coach insights --- */
.insight { padding: var(--sp-3) 0; }
.insight-critical { border-left: 3px solid var(--bad); padding-left: var(--sp-4); }
.insight-warning { border-left: 3px solid var(--warn); padding-left: var(--sp-4); }
.insight-opportunity { border-left: 3px solid var(--info); padding-left: var(--sp-4); }
.insight-positive { border-left: 3px solid var(--ok); padding-left: var(--sp-4); }
.qa-log { max-height: 480px; overflow-y: auto; }

/* --- goal cards --- */
.goal-card { display: flex; flex-direction: column; gap: var(--sp-3); }

/* --- toasts --- */
.toast-stack {
  position: fixed; right: var(--sp-4); bottom: var(--sp-4); z-index: 999;
  display: flex; flex-direction: column; gap: var(--sp-2); max-width: 320px;
}
.toast {
  padding: 12px 16px; border-radius: var(--r-md); background: var(--ink); color: var(--surface);
  box-shadow: var(--sh-3); font-size: var(--fs-sm); cursor: pointer;
  opacity: 0; transform: translateY(8px); transition: opacity .22s var(--ease), transform .22s var(--ease);
}
.toast-in { opacity: 1; transform: none; }
.toast-ok { background: var(--brand-700); }
.toast-warn { background: var(--gold-700); color: #fff; }
.toast-bad { background: var(--coral-700); }
