/* ==========================================================================
   Household Budget Tracker — design tokens, layout, components
   Calm, modern personal-finance feel. Single source of truth via CSS vars.
   ========================================================================== */

:root {
  /* Brand & palette */
  --c-bg: #f6f6fb;
  --c-bg-2: #ffffff;
  --c-surface: #ffffff;
  --c-surface-2: #fbfbff;
  --c-line: #e8e8f0;
  --c-line-2: #efeff6;
  --c-ink: #1a1b2e;
  --c-ink-2: #2a2c44;
  --c-ink-soft: #5b5d78;
  --c-ink-mute: #8a8da6;
  --c-accent: #7c5cff;
  --c-accent-soft: #efeaff;
  --c-accent-2: #00b894;
  --c-warn: #d97706;
  --c-warn-soft: #fff5e6;
  --c-danger: #dc2626;
  --c-danger-soft: #fde8e8;
  --c-success: #10b981;
  --c-success-soft: #e7f8f1;

  /* Pie swatches (used by chart) */
  --swatch-1: #7c5cff;
  --swatch-2: #00b894;
  --swatch-3: #f59e0b;
  --swatch-4: #ef4444;
  --swatch-5: #38bdf8;
  --swatch-6: #ec4899;
  --swatch-7: #14b8a6;
  --swatch-8: #a855f7;
  --swatch-9: #84cc16;
  --swatch-10: #f97316;

  /* Radii, shadow, motion */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 22px;
  --r-pill: 999px;
  --shadow-1: 0 1px 2px rgba(20, 22, 50, .04), 0 1px 1px rgba(20, 22, 50, .03);
  --shadow-2: 0 6px 24px rgba(40, 30, 90, .07), 0 1px 2px rgba(20, 22, 50, .04);
  --shadow-3: 0 18px 40px rgba(40, 30, 90, .12);
  --t-fast: 120ms cubic-bezier(.2,.7,.2,1);
  --t-med: 240ms cubic-bezier(.2,.7,.2,1);
  --t-slow: 420ms cubic-bezier(.2,.7,.2,1);

  /* Layout */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 28px;
  --space-7: 36px;
  --space-8: 48px;

  /* Type */
  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --fs-12: 12px;
  --fs-13: 13px;
  --fs-14: 14px;
  --fs-15: 15px;
  --fs-16: 16px;
  --fs-18: 18px;
  --fs-22: 22px;
  --fs-28: 28px;
  --fs-32: 32px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --c-bg: #0f1020;
    --c-bg-2: #161833;
    --c-surface: #181a36;
    --c-surface-2: #1e2143;
    --c-line: #292d54;
    --c-line-2: #232650;
    --c-ink: #f2f3ff;
    --c-ink-2: #d5d7f0;
    --c-ink-soft: #a4a8c8;
    --c-ink-mute: #7d80a3;
    --c-accent: #9a82ff;
    --c-accent-soft: #2a2456;
    --c-accent-2: #34d6a8;
    --c-warn: #fbbf24;
    --c-warn-soft: #3a2c14;
    --c-danger: #f87171;
    --c-danger-soft: #3a1d1d;
    --c-success: #34d399;
    --c-success-soft: #122e26;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-2: 0 8px 30px rgba(0, 0, 0, .35);
    --shadow-3: 0 18px 50px rgba(0, 0, 0, .45);
  }
}

* { box-sizing: border-box; }

html, body { height: 100%; }
body {
  margin: 0;
  background: radial-gradient(1200px 600px at 20% -10%, var(--c-accent-soft), transparent 60%),
              radial-gradient(900px 500px at 100% 0%, rgba(0, 184, 148, .08), transparent 60%),
              var(--c-bg);
  color: var(--c-ink);
  font-family: var(--font-sans);
  font-size: var(--fs-15);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding-bottom: var(--space-8);
}

h1, h2, h3 { margin: 0; color: var(--c-ink); letter-spacing: -0.01em; }
p { margin: 0; color: var(--c-ink-soft); }

button, input, select, textarea {
  font: inherit; color: inherit;
}

/* Accessibility */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--c-accent); color: white; padding: 8px 12px;
  border-radius: var(--r-sm); z-index: 1000;
}
.skip-link:focus { left: 12px; top: 12px; }

/* ---------- Top bar ---------- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-4) var(--space-6);
  position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--c-bg) 80%, transparent);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--c-line);
}
.brand { display: flex; align-items: center; gap: var(--space-3); }
.brand-mark {
  width: 28px; height: 28px; border-radius: 8px;
  background: linear-gradient(135deg, var(--c-accent), var(--c-accent-2));
  box-shadow: var(--shadow-1);
}
.brand-title { font-size: var(--fs-18); font-weight: 700; }
.topnav { display: flex; gap: var(--space-2); }
.navlink {
  background: transparent; border: 0; padding: 8px 12px;
  border-radius: var(--r-md); color: var(--c-ink-soft);
  cursor: pointer; transition: background var(--t-fast), color var(--t-fast);
}
.navlink:hover { background: var(--c-line-2); color: var(--c-ink); }
.navlink:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }

/* ---------- Page ---------- */
.page {
  max-width: 1240px;
  margin: 0 auto;
  padding: var(--space-5) var(--space-5) var(--space-7);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* ---------- Month bar ---------- */
.month-bar {
  display: flex; flex-wrap: wrap; gap: var(--space-4);
  align-items: stretch; justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-1);
}
.month-switcher {
  display: flex; align-items: center; gap: var(--space-2);
}
.month-label {
  display: flex; flex-direction: column; align-items: center; min-width: 140px;
}
.month-name { font-size: var(--fs-22); font-weight: 700; }
.month-year { font-size: var(--fs-13); color: var(--c-ink-mute); }
.iconbtn {
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--c-line); background: var(--c-surface-2);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--c-ink-soft);
  transition: background var(--t-fast), color var(--t-fast), transform var(--t-fast);
}
.iconbtn:hover { background: var(--c-accent-soft); color: var(--c-accent); }
.iconbtn:active { transform: scale(0.96); }
.iconbtn:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--c-line);
  background: var(--c-surface-2);
  color: var(--c-ink-soft);
  padding: 6px 12px;
  border-radius: var(--r-pill);
  font-size: var(--fs-13);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
.chip:hover { color: var(--c-ink); border-color: var(--c-ink-mute); }
.chip.active { background: var(--c-accent); color: white; border-color: var(--c-accent); }
.chip:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }

.totals {
  display: grid; grid-template-columns: repeat(3, minmax(120px, 1fr));
  gap: var(--space-3);
  flex: 1; max-width: 720px; margin-left: auto;
}
.total-card {
  background: var(--c-surface-2);
  border: 1px solid var(--c-line-2);
  border-radius: var(--r-md);
  padding: var(--space-3) var(--space-4);
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
}
.total-label { font-size: var(--fs-12); color: var(--c-ink-mute); text-transform: uppercase; letter-spacing: 0.06em; }
.total-value { font-size: var(--fs-22); font-weight: 700; color: var(--c-ink); font-variant-numeric: tabular-nums; }
.total-card.over .total-value { color: var(--c-danger); }
.total-card.ok .total-value { color: var(--c-success); }

/* ---------- Grid layout ---------- */
.grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: var(--space-5);
  align-items: start;
}
.col { display: flex; flex-direction: column; gap: var(--space-5); min-width: 0; }

@media (max-width: 980px) {
  .grid { grid-template-columns: 1fr; }
  .totals { margin-left: 0; }
}
@media (max-width: 640px) {
  .month-bar { flex-direction: column; align-items: stretch; }
  .totals { grid-template-columns: 1fr 1fr; }
  .total-card:last-child { grid-column: 1 / -1; }
}

/* ---------- Cards ---------- */
.card {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-1);
  padding: var(--space-5);
}
.card-head { margin-bottom: var(--space-4); }
.card-title { font-size: var(--fs-18); font-weight: 700; }
.card-sub { color: var(--c-ink-mute); font-size: var(--fs-13); margin-top: 2px; }
.row-between { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--space-4); flex-wrap: wrap; }

/* ---------- Forms ---------- */
.expense-form { display: flex; flex-direction: column; gap: var(--space-3); }
.row.two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
@media (max-width: 480px) { .row.two { grid-template-columns: 1fr; } }
.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.field-label { font-size: var(--fs-13); color: var(--c-ink-soft); font-weight: 600; }
.field input, .field select {
  width: 100%;
  border: 1px solid var(--c-line);
  background: var(--c-surface-2);
  border-radius: var(--r-md);
  padding: 10px 12px;
  color: var(--c-ink);
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
  outline: none;
}
.field input:hover, .field select:hover { border-color: var(--c-ink-mute); }
.field input:focus, .field select:focus {
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-soft);
  background: var(--c-surface);
}
.field input::placeholder { color: var(--c-ink-mute); }
.amount-wrap {
  position: relative;
  display: flex; align-items: center;
  border: 1px solid var(--c-line);
  background: var(--c-surface-2);
  border-radius: var(--r-md);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.amount-wrap:focus-within {
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-soft);
}
.amount-wrap input {
  border: 0 !important; background: transparent !important;
  box-shadow: none !important; padding-left: 0;
  flex: 1;
}
.amount-prefix {
  padding: 0 8px 0 12px;
  color: var(--c-ink-mute);
  font-weight: 600;
}
.cat-select { display: flex; gap: var(--space-2); align-items: center; }
.cat-select select { flex: 1; }
.add-cat-inline { white-space: nowrap; }
.field-msg { font-size: var(--fs-12); color: var(--c-warn); min-height: 14px; }
.form-msg {
  font-size: var(--fs-13);
  min-height: 18px;
  color: var(--c-ink-soft);
}
.form-msg.warn { color: var(--c-warn); }
.form-msg.danger { color: var(--c-danger); }
.form-msg.ok { color: var(--c-success); }
.muted { color: var(--c-ink-mute); }
.small { font-size: var(--fs-12); }

.form-actions {
  display: flex; gap: var(--space-2); margin-top: var(--space-1);
  align-items: center;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid var(--c-line);
  background: var(--c-surface-2);
  color: var(--c-ink);
  padding: 10px 16px;
  border-radius: var(--r-md);
  cursor: pointer;
  font-weight: 600;
  transition: transform var(--t-fast), background var(--t-fast), border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-fast);
}
.btn:hover { background: var(--c-line-2); border-color: var(--c-ink-mute); }
.btn:active { transform: scale(0.98); }
.btn:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.btn.primary {
  background: var(--c-accent); color: white; border-color: var(--c-accent);
  box-shadow: 0 4px 14px rgba(124, 92, 255, .25);
}
.btn.primary:hover { background: color-mix(in srgb, var(--c-accent) 85%, black); }
.btn.ghost { background: transparent; border-color: var(--c-line); }
.btn.danger { color: var(--c-danger); border-color: var(--c-danger-soft); background: var(--c-danger-soft); }
.btn.danger:hover { background: color-mix(in srgb, var(--c-danger) 12%, var(--c-surface)); }
.btn.small { padding: 6px 10px; font-size: var(--fs-13); }

/* ---------- Categories list ---------- */
.cat-toolbar { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.sort select, .filter select {
  border: 1px solid var(--c-line);
  background: var(--c-surface-2);
  border-radius: var(--r-md);
  padding: 6px 10px;
  font-size: var(--fs-13);
  color: var(--c-ink);
  cursor: pointer;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.sort select:focus, .filter select:focus {
  outline: none; border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-soft);
}
.cat-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.cat-row {
  display: grid;
  grid-template-columns: 18px 1fr auto;
  align-items: center;
  gap: var(--space-3);
  padding: 12px 14px;
  background: var(--c-surface-2);
  border: 1px solid var(--c-line-2);
  border-radius: var(--r-md);
  transition: background var(--t-fast), border-color var(--t-fast), transform var(--t-fast);
  cursor: pointer;
}
.cat-row:hover { background: var(--c-bg-2); border-color: var(--c-line); }
.cat-row.active { border-color: var(--c-accent); background: var(--c-accent-soft); }
.cat-row.focused { box-shadow: 0 0 0 2px var(--c-accent); }
.cat-swatch {
  width: 14px; height: 14px; border-radius: 4px;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.08);
}
.cat-name {
  display: flex; align-items: baseline; gap: 8px; min-width: 0;
  font-weight: 600; color: var(--c-ink);
}
.cat-name small {
  color: var(--c-ink-mute); font-weight: 500; font-size: var(--fs-12);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cat-amount {
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
  font-variant-numeric: tabular-nums;
}
.cat-amount .amt { font-weight: 700; }
.cat-amount .pct { font-size: var(--fs-12); color: var(--c-ink-mute); }
.cat-cap {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: var(--space-2);
  margin-top: 6px;
  font-size: var(--fs-12); color: var(--c-ink-soft);
}
.cap-bar {
  position: relative;
  flex: 1; height: 6px;
  background: var(--c-line-2);
  border-radius: 999px;
  overflow: hidden;
}
.cap-bar > span {
  display: block; height: 100%;
  background: var(--c-accent-2);
  border-radius: 999px;
  transition: width var(--t-med), background var(--t-fast);
}
.cap-bar.warn > span { background: var(--c-warn); }
.cap-bar.danger > span { background: var(--c-danger); }
.cap-meta { font-variant-numeric: tabular-nums; min-width: 110px; text-align: right; }
.cap-meta.danger { color: var(--c-danger); font-weight: 600; }
.cap-meta.warn { color: var(--c-warn); font-weight: 600; }

/* ---------- Chart ---------- */
.chart-wrap {
  position: relative;
  display: grid; grid-template-columns: minmax(260px, 320px) 1fr;
  gap: var(--space-5);
  align-items: center;
  min-height: 280px;
}
@media (max-width: 760px) {
  .chart-wrap { grid-template-columns: 1fr; }
}
.pie { width: 100%; max-width: 320px; aspect-ratio: 1 / 1; justify-self: center; }
.pie-slice {
  transition: opacity var(--t-med), transform var(--t-med), filter var(--t-med);
  transform-origin: 0 0;
  cursor: pointer;
  pointer-events: visiblePainted;
}
.pie-slice:focus { outline: none; }
.pie.has-focus .pie-slice:not(.focus) { opacity: 0.28; }
.pie-slice:hover, .pie-slice.focus { filter: drop-shadow(0 4px 14px rgba(0,0,0,.18)); }
.pie-center {
  position: absolute;
  pointer-events: none;
  inset: 0;
  display: grid; place-items: center;
}
.pie-center {
  /* center over the pie area; only on wider screens */
}
.chart-wrap { position: relative; }
.pie-center-label {
  display: block; text-align: center;
  font-size: var(--fs-12); color: var(--c-ink-mute);
  text-transform: uppercase; letter-spacing: 0.06em;
  font-weight: 600;
}
.pie-center-value {
  display: block; text-align: center;
  font-size: var(--fs-22); font-weight: 700; color: var(--c-ink);
  font-variant-numeric: tabular-nums;
}
@media (min-width: 761px) {
  .pie-center { left: 0; width: 320px; max-width: 100%; }
}

.pie-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--c-ink);
  color: white;
  padding: 10px 12px;
  border-radius: var(--r-md);
  font-size: var(--fs-13);
  box-shadow: var(--shadow-3);
  transform: translate(-50%, calc(-100% - 12px));
  white-space: nowrap;
  z-index: 5;
}
.pie-tooltip strong { display: block; margin-bottom: 4px; }
.pie-tooltip .row { display: flex; gap: 8px; color: rgba(255,255,255,.85); }
.pie-tooltip .row b { color: white; font-variant-numeric: tabular-nums; }

.chart-toolbar { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- Transactions list ---------- */
.tx-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.tx-row {
  display: grid;
  grid-template-columns: 8px 1fr auto auto auto;
  align-items: center;
  gap: var(--space-3);
  padding: 10px 14px;
  background: var(--c-surface-2);
  border: 1px solid var(--c-line-2);
  border-radius: var(--r-md);
  transition: background var(--t-fast), border-color var(--t-fast);
}
.tx-row:hover { background: var(--c-bg-2); border-color: var(--c-line); }
.tx-row.dim { opacity: 0.45; }
.tx-row .swatch { width: 8px; height: 8px; border-radius: 50%; }
.tx-row .desc { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tx-row .desc .note { font-weight: 600; color: var(--c-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tx-row .desc .meta { font-size: var(--fs-12); color: var(--c-ink-mute); }
.tx-row .amount { font-variant-numeric: tabular-nums; font-weight: 700; }
.tx-row button {
  background: transparent; border: 0; cursor: pointer;
  padding: 6px 8px; border-radius: var(--r-sm);
  color: var(--c-ink-soft);
  transition: background var(--t-fast), color var(--t-fast);
}
.tx-row button:hover { background: var(--c-line-2); color: var(--c-ink); }
.tx-row button.danger:hover { background: var(--c-danger-soft); color: var(--c-danger); }
.tx-row button:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }

/* ---------- Empty states ---------- */
.empty {
  display: flex; flex-direction: column; gap: var(--space-2);
  align-items: center; justify-content: center;
  text-align: center;
  padding: var(--space-6) var(--space-4);
  color: var(--c-ink-soft);
  background: var(--c-surface-2);
  border: 1px dashed var(--c-line);
  border-radius: var(--r-md);
}
[hidden] { display: none !important; }
.empty h3 { color: var(--c-ink); font-size: var(--fs-16); }
.empty p { max-width: 380px; }
.empty-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; justify-content: center; margin-top: var(--space-2); }
.empty-month { grid-column: 1 / -1; }

/* ---------- Data panel ---------- */
.data-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
#data-msg { margin-top: var(--space-3); min-height: 16px; }

/* ---------- Dialog ---------- */
.cat-dialog {
  border: 0;
  padding: 0;
  border-radius: var(--r-xl);
  background: transparent;
}
.cat-dialog::backdrop {
  background: rgba(15, 16, 32, 0.4);
  backdrop-filter: blur(2px);
}
.cat-form {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-xl);
  padding: var(--space-5);
  width: min(92vw, 480px);
  display: flex; flex-direction: column; gap: var(--space-3);
  box-shadow: var(--shadow-3);
}
.swatches {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 8px;
}
.swatch-btn {
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform var(--t-fast), border-color var(--t-fast);
  outline: none;
}
.swatch-btn:hover { transform: scale(1.08); }
.swatch-btn:focus-visible { border-color: var(--c-ink); }
.swatch-btn.selected { border-color: var(--c-ink); }

/* ---------- Toast ---------- */
.toast {
  position: fixed; left: 50%; bottom: 24px;
  transform: translateX(-50%) translateY(8px);
  background: var(--c-ink);
  color: white;
  padding: 10px 16px;
  border-radius: var(--r-pill);
  font-size: var(--fs-13);
  box-shadow: var(--shadow-3);
  opacity: 0;
  transition: opacity var(--t-med), transform var(--t-med);
  z-index: 100;
  pointer-events: none;
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ---------- Count-up & state animations ---------- */
@keyframes pulseWarn {
  0% { box-shadow: 0 0 0 0 var(--c-warn-soft); }
  100% { box-shadow: 0 0 0 8px transparent; }
}
.pulse-warn { animation: pulseWarn 700ms ease-out; }

@keyframes floatIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
.fade-in { animation: floatIn var(--t-med) ease-out both; }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}