/* ==========================================================================
   Keuangan — Buku Besar / Editorial Ledger
   Deep ink canvas, hairline accounting rules, brass structure,
   jade for Masuk, vermilion for Keluar. Light counterpart: "Kertas".
   ========================================================================== */

/* ---------- 1. Tokens ---------------------------------------------------- */
:root {
  --ink-900: #0b0e13;
  --ink-800: #11151c;
  --ink-700: #171c25;
  --ink-600: #1f2632;
  --line: #2a323f;
  --line-soft: #1c222c;
  --text: #ede7da;
  --text-dim: #98a2b1;
  --brass: #d9a441;
  --brass-soft: #a87c26;
  --jade: #4fbf95;
  --vermilion: #e4572e;
  --paper: #f4efe4;
  --shadow: 0 18px 48px -24px rgba(0, 0, 0, .9);

  --font-display: "Instrument Serif", Georgia, "Times New Roman", serif;
  --font-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Code", monospace;

  --shell: 76rem;
  --gutter: clamp(1rem, 4vw, 2.75rem);
  --radius: 3px;
  --speed: 180ms;
}

[data-theme="kertas"] {
  --ink-900: #f4efe4;
  --ink-800: #fbf8f1;
  --ink-700: #efe8d9;
  --ink-600: #e4dbc8;
  --line: #d6cbb2;
  --line-soft: #e6ddcb;
  --text: #1b1a16;
  --text-dim: #6b6455;
  --brass: #8a6410;
  --brass-soft: #b8903a;
  --jade: #17715a;
  --vermilion: #b23c14;
  --paper: #f4efe4;
  --shadow: 0 14px 34px -22px rgba(60, 46, 20, .55);
}

@media (prefers-color-scheme: light) {
  [data-theme="gelap-pref"] {
    --ink-900: #f4efe4; --ink-800: #fbf8f1; --ink-700: #efe8d9; --ink-600: #e4dbc8;
    --line: #d6cbb2; --line-soft: #e6ddcb; --text: #1b1a16; --text-dim: #6b6455;
    --brass: #8a6410; --jade: #17715a; --vermilion: #b23c14;
  }
}

/* ---------- 2. Reset ----------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  font-size: clamp(17px, .5vw + 15.6px, 19px);
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  background: var(--ink-900);
  color: var(--text);
  font-family: var(--font-sans);
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: .002em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Paper grain — decorative, sits above the canvas, never above content. */
.grain {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: .5;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.36'/%3E%3C/svg%3E");
}

[data-theme="kertas"] .grain { opacity: .28; mix-blend-mode: multiply; }

img, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }

/* ---------- 3. Typography ------------------------------------------------ */
h1, h2, h3, h4 { font-weight: 500; line-height: 1.1; text-wrap: balance; }

h1, h2 {
  font-family: var(--font-display);
  letter-spacing: -.012em;
  scroll-margin-top: 6rem;
}

h1 { font-size: clamp(2.1rem, 5.5vw, 3.4rem); }
h2 { font-size: clamp(1.5rem, 3.4vw, 2.1rem); }
h3 { font-size: 1.06rem; letter-spacing: .01em; }

p { text-wrap: pretty; }

a { color: inherit; text-underline-offset: .22em; text-decoration-thickness: 1px; }
a:hover { text-decoration-color: var(--brass); }

.eyebrow {
  font-family: var(--font-mono);
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--brass);
}

.lede {
  max-width: 58ch;
  color: var(--text-dim);
  font-size: .96rem;
  line-height: 1.65;
}

.muted { color: var(--text-dim); }
.small { font-size: .8rem; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Money: always tabular so columns of figures align. */
.num, .money {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  letter-spacing: -.02em;
}

/* ---------- 4. Focus & skip --------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  top: -4rem;
  left: 1rem;
  z-index: 100;
  padding: .6rem 1rem;
  background: var(--brass);
  color: #0b0e13;
  font-weight: 600;
  text-decoration: none;
  transition: top var(--speed) ease;
}
.skip-link:focus { top: 1rem; }

/* ---------- 5. Shell & chrome ------------------------------------------- */
.shell {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding: clamp(1.5rem, 4vw, 3rem) var(--gutter) 5rem;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  background: color-mix(in srgb, var(--ink-900) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.topbar-inner {
  display: flex;
  align-items: center;
  gap: clamp(.75rem, 2vw, 1.75rem);
  max-width: var(--shell);
  margin-inline: auto;
  padding: .7rem var(--gutter);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  text-decoration: none;
  flex-shrink: 0;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  border: 1px solid var(--brass);
  color: var(--brass);
  font-family: var(--font-display);
  font-size: 1.02rem;
  line-height: 1;
  padding-bottom: .12em;
}

.brand-text {
  font-family: var(--font-display);
  font-size: 1.32rem;
  letter-spacing: -.01em;
}

.mainnav { margin-inline-start: auto; }
.mainnav ul {
  display: flex;
  gap: clamp(.5rem, 1.6vw, 1.35rem);
  list-style: none;
  padding: 0;
  margin: 0;
}

.mainnav a {
  position: relative;
  display: inline-block;
  padding: .3rem 0;
  font-size: .88rem;
  color: var(--text-dim);
  text-decoration: none;
  transition: color var(--speed) ease;
}
.mainnav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -.15rem;
  height: 1px;
  background: var(--brass);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--speed) ease;
}
.mainnav a:hover { color: var(--text); }
.mainnav a:hover::after,
.mainnav a[aria-current="page"]::after { transform: scaleX(1); }
.mainnav a[aria-current="page"] { color: var(--text); }

.theme-switch, .logout-form { flex-shrink: 0; }

.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .32rem .6rem;
  background: none;
  border: 1px solid var(--line);
  color: var(--text-dim);
  font-size: .78rem;
  text-decoration: none;
  cursor: pointer;
  transition: color var(--speed) ease, border-color var(--speed) ease;
}
.btn-ghost:hover { color: var(--brass); border-color: var(--brass); }
.theme-label { display: inline; }

.topbar-spacer { margin-inline-start: auto; }

.user-chip {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .25rem .5rem .25rem .25rem;
  border: 1px solid var(--line);
  color: var(--text-dim);
  text-decoration: none;
  font-size: .8rem;
  transition: color var(--speed) ease, border-color var(--speed) ease;
}
.user-chip:hover { color: var(--text); border-color: var(--brass); }
.user-name { max-width: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.avatar {
  width: 1.65rem;
  height: 1.65rem;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.avatar-fallback {
  display: grid;
  place-items: center;
  border: 1px solid var(--brass);
  color: var(--brass);
  font-family: var(--font-display);
  font-size: .9rem;
  line-height: 1;
}

.foot {
  position: relative;
  z-index: 1;
  max-width: var(--shell);
  margin-inline: auto;
  padding: 1.5rem var(--gutter) 2rem;
  border-top: 1px solid var(--line-soft);
  color: var(--text-dim);
  font-size: .74rem;
}

.foot { display: grid; gap: .35rem; }
.foot-legal {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  align-items: center;
}
.foot-legal a, .legal-links a { color: var(--text-dim); text-decoration: none; }
.foot-legal a:hover, .legal-links a:hover { color: var(--brass); text-decoration: underline; }

/* ---------- 6. Buttons -------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  min-height: 2.75rem;
  padding: .55rem 1.15rem;
  border: 1px solid var(--brass);
  background: var(--brass);
  color: #0b0e13;
  font-size: .88rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: color-mix(in srgb, var(--brass) 30%, transparent);
  transition: background var(--speed) ease, color var(--speed) ease,
              border-color var(--speed) ease, transform var(--speed) ease;
}
.btn:hover { background: var(--brass-soft); border-color: var(--brass-soft); color: #0b0e13; }
.btn:active { transform: translateY(1px); }

.btn-quiet {
  background: none;
  color: var(--text);
  border-color: var(--line);
}
.btn-quiet:hover { background: var(--ink-700); border-color: var(--brass); color: var(--text); }

.btn-danger { background: var(--vermilion); border-color: var(--vermilion); color: #fff; }
.btn-danger:hover { background: color-mix(in srgb, var(--vermilion) 82%, #000); border-color: color-mix(in srgb, var(--vermilion) 82%, #000); color: #fff; }

/* Small row actions (ledger tables): real buttons, not plain links. */
.btn-sm {
  min-height: 2rem;
  padding: .3rem .7rem;
  font-size: .78rem;
  font-weight: 600;
}
.row-actions {
  gap: .4rem;
  flex-wrap: nowrap;
  justify-content: flex-end;
}
.row-actions form { margin: 0; }

.btn-google { background: var(--ink-700); border-color: var(--line); color: var(--text); }

/* The reveal toggle belongs to the input it controls, so it takes the
   input's height (2.6rem) rather than the button's (2.75rem) —
   otherwise a split field rows taller than a bare input beside it
   (e.g. "Ulangi Password Baru" under the split "Password Baru"). */
[data-toggle-password] { min-height: 2.6rem; }
.btn-google:hover { background: var(--ink-600); border-color: var(--brass); color: var(--text); }
.g-mark {
  display: grid;
  place-items: center;
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 50%;
  background: var(--paper);
  color: var(--ink-900);
  font-family: var(--font-display);
  font-size: .95rem;
  font-weight: 600;
  line-height: 1;
}
/* The ink scale inverts in the Kertas theme (--ink-900 becomes cream), which
   would leave a cream G on a cream disc. Flip the disc instead so the mark
   stays readable on both palettes. */
[data-theme="kertas"] .g-mark { background: var(--text); color: var(--paper); }

/* Agreement checkbox used on the registration form. */
.check {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .55rem;
  align-items: start;
  font-size: .82rem;
  line-height: 1.5;
  color: var(--text-dim);
}
.check input { margin-top: .18rem; width: 1.05rem; height: 1.05rem; accent-color: var(--brass); }
.check a { color: var(--brass); }

.btn-row { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; }

/* ---------- 7. Toasts ---------------------------------------------------- */
.toasts {
  position: relative;
  z-index: 25;
  display: grid;
  gap: .5rem;
  margin-bottom: 1.25rem;
}
.toasts:empty { display: none; }

.toast {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  padding: .7rem .9rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--jade);
  background: var(--ink-800);
  color: var(--text);
  font-size: .87rem;
  animation: toast-in 260ms cubic-bezier(.2, .7, .3, 1) both;
}
.toast-error { border-left-color: var(--vermilion); }
.toast p { min-width: 0; overflow-wrap: anywhere; }
.toast-icon { font-family: var(--font-mono); font-size: .8rem; line-height: 1.5; }
.toast-success .toast-icon { color: var(--jade); }
.toast-error .toast-icon { color: var(--vermilion); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}

.toasts-auth {
  position: fixed;
  top: 1rem;
  left: 50%;
  transform: translateX(-50%);
  width: min(26rem, calc(100vw - 2rem));
}
.toasts-top {
  position: fixed;
  top: 1rem;
  right: 1rem;
  width: min(30rem, calc(100vw - 2rem));
  z-index: 40;
}

/* ---------- 8. Cards & sections ----------------------------------------- */
.page-head { margin-bottom: 1.75rem; }
.page-head h1 { margin-bottom: .35rem; }

.card {
  border: 1px solid var(--line);
  background: var(--ink-800);
  padding: clamp(1rem, 2.4vw, 1.6rem);
}
.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.rule { height: 1px; background: var(--line); border: 0; margin: 1.5rem 0; }

/* Legal documents (Syarat & Ketentuan, Kebijakan Privasi, Penafian). */
.legal { max-width: 70ch; }
.legal section { margin-bottom: 1.6rem; }
.legal section:last-child { margin-bottom: 0; }
.legal h2 { font-size: 1.12rem; margin-bottom: .5rem; }
.legal p, .legal li { color: var(--text-dim); line-height: 1.72; }
.legal ul { margin: .4rem 0 0; padding-left: 1.2rem; display: grid; gap: .35rem; }
.legal a { color: var(--brass); }
.legal-links { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }

/* ---------- 9. Hero & stat figures ------------------------------------- */
.hero {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  grid-template-columns: 1fr;
  margin-bottom: 2rem;
}

@media (min-width: 62rem) {
  .hero { grid-template-columns: 1.55fr 1fr; align-items: stretch; }
}

.hero-figure {
  position: relative;
  border: 1px solid var(--line);
  background: var(--ink-800);
  padding: clamp(1.15rem, 3vw, 2rem);
  overflow: hidden;
}

/* Guilloché hairline texture behind the hero figure. */
.hero-figure::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(58deg, color-mix(in srgb, var(--brass) 11%, transparent) 0 1px, transparent 1px 9px),
    repeating-linear-gradient(-58deg, color-mix(in srgb, var(--brass) 8%, transparent) 0 1px, transparent 1px 13px);
  opacity: .55;
  pointer-events: none;
}

.hero-figure > * { position: relative; }

.hero-lede {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.15rem;
}
.hero-month {
  font-family: var(--font-display);
  font-size: clamp(1.65rem, 4.6vw, 2.6rem);
  line-height: 1;
}
.hero-net-label { font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }

/* The hero value owns its own row: label above, big number, then the
   surplus/deficit tag — a 3.5rem figure never shares a line with its label. */
.hero-net { display: block; margin-bottom: 1.35rem; }
.hero-net .amount {
  display: block;
  margin-bottom: .4rem;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.1rem, 6.4vw, 3.5rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.03em;
  overflow-wrap: anywhere;
}
.hero-net .amount.pos { color: var(--jade); }
.hero-net .amount.neg { color: var(--vermilion); }
.hero-net .type-tag { font-size: .74rem; }

.hero-split {
  display: grid;
  gap: 1.15rem;
  grid-template-columns: 1fr;
  padding-top: 1.15rem;
  border-top: 1px solid var(--line);
}
@media (min-width: 30rem) { .hero-split { grid-template-columns: 1fr 1fr; } }

.stat-label {
  font-family: var(--font-mono);
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.stat-label.in { color: var(--jade); }
.stat-label.ex { color: var(--vermilion); }

.stat-value {
  display: block;
  margin-top: .3rem;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.35rem, 3.6vw, 1.85rem);
  font-weight: 600;
  letter-spacing: -.025em;
  line-height: 1.1;
}

/* Compact chip row reused across pages. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
  align-items: center;
}
.chip {
  display: inline-flex;
  align-items: baseline;
  gap: .35rem;
  padding: .22rem .6rem;
  border: 1px solid var(--line);
  font-size: .82rem;
}
.chip .k { color: var(--text-dim); font-size: .76rem; }
.chip .v { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.chip.in { border-color: color-mix(in srgb, var(--jade) 45%, var(--line)); }
.chip.in .v { color: var(--jade); }
.chip.ex { border-color: color-mix(in srgb, var(--vermilion) 45%, var(--line)); }
.chip.ex .v { color: var(--vermilion); }

/* ---------- 10. Sparkline ----------------------------------------------- */
.spark {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 3px;
  align-items: end;
  height: 7.5rem;
  padding-top: .5rem;
}

.spark-col {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: .25rem;
  height: 100%;
  text-decoration: none;
  color: var(--text-dim);
}
.spark-bar {
  min-height: 2px;
  background: color-mix(in srgb, var(--brass) 42%, var(--ink-600));
  transition: background var(--speed) ease, transform var(--speed) ease;
  transform-origin: bottom;
}
.spark-col:hover .spark-bar { background: var(--brass); transform: scaleY(1.03); }
.spark-col.is-current .spark-bar { background: var(--brass); }
.spark-label {
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .06em;
  text-align: center;
  text-transform: uppercase;
}
.spark-col.is-current .spark-label { color: var(--brass); }

.spark-legend {
  display: flex;
  justify-content: space-between;
  margin-top: .5rem;
  font-size: .68rem;
  color: var(--text-dim);
}

/* ---------- 11. Category bars ------------------------------------------- */
.bars { display: grid; gap: .7rem; }
.bar-row { display: grid; gap: .3rem; }

.bar-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
  font-size: .86rem;
}
.bar-head .name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bar-head .val {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: .84rem;
}

.bar-track {
  position: relative;
  height: 6px;
  background: var(--ink-700);
  overflow: hidden;
}
.bar-fill {
  height: 100%;
  background: var(--brass);
  transform-origin: left;
  animation: bar-grow 620ms cubic-bezier(.2, .8, .25, 1) both;
}
.bar-fill.ex { background: var(--vermilion); }
.bar-fill.in { background: var(--jade); }

@keyframes bar-grow {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

/* ---------- 12. Toolbar & filters -------------------------------------- */
.toolbar {
  display: grid;
  gap: .75rem;
  margin-bottom: 1.25rem;
}

/* Export links get their own row so the buttons never get squeezed into a
   narrow column next to the date pickers. */
.export-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem .9rem;
  margin: -.5rem 0 1.4rem;
  padding: .85rem 0;
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
}
@media (min-width: 48rem) {
  .toolbar { grid-template-columns: repeat(12, 1fr); align-items: end; }
  .toolbar > .f { grid-column: span 3; }
  /* Pemilih bulan butuh min. 3 kolom: teks "October 2026" + ikon kalender
     bawaan browser meluap dan menumpuk kolom Cari bila hanya 2 kolom. */
  .toolbar > .f-month { grid-column: span 3; }
  .toolbar > .f-search { grid-column: span 3; }
  .toolbar > .f-actions { grid-column: span 3; justify-content: flex-end; }
  /* Rentang laporan: dua pemilih bulan butuh ruang min. 11rem agar teks
     "October 2026" + ikon kalender tidak meluap dan bertumpuk. */
  .toolbar.toolbar-range { grid-template-columns: minmax(11rem, 1fr) minmax(11rem, 1fr) auto; }
  .toolbar.toolbar-range > .f-month,
  .toolbar.toolbar-range > .f-actions { grid-column: auto; }
}

/* f-actions memakai .btn-row (flex) sekaligus .field (grid); tanpa ini
   .field yang menang sehingga tombol menumpuk vertikal. */
.toolbar > .f-actions.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  align-items: flex-end;
}
.toolbar > .f-actions.btn-row .btn { flex-shrink: 0; }

/* Varian toolbar transaksi: tombol aksi (Terapkan Filter) rata kiri,
   bukan kanan mengikuti default .toolbar > .f-actions. */
.toolbar-start > .f-actions { justify-content: flex-start; }

/* Sabuk pengaman: input/select tidak boleh melukis di luar track grid-nya
   walau konten intrinsik (ikon kalender bawaan browser) lebih lebar. */
.toolbar input, .toolbar select { min-width: 0; max-width: 100%; }

.field {
  display: grid;
  gap: .3rem;
  min-width: 0;
  /* Grid's default align-content (normal→stretch) would share a
     stretched field's spare space across its rows — pushing the input
     down and inflating it when a side-by-side field has a footnote
     or hint beneath its input. Pack rows at the top instead. */
  align-content: start;
}

.field > label, .field-label {
  font-family: var(--font-mono);
  font-size: .66rem;
  font-weight: 500;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--text-dim);
}

input[type="text"], input[type="password"], input[type="search"],
input[type="date"], input[type="month"], input[type="number"],
input[type="file"], select, textarea {
  width: 100%;
  min-height: 2.6rem;
  padding: .5rem .7rem;
  background: var(--ink-700);
  border: 1px solid var(--line);
  color: var(--text);
  /* 16px floor prevents iOS zoom-on-focus without shrinking desktop type. */
  font-size: max(1rem, 16px);
  transition: border-color var(--speed) ease, background var(--speed) ease;
}
input::placeholder, textarea::placeholder { color: color-mix(in srgb, var(--text-dim) 78%, transparent); }
input:hover, select:hover, textarea:hover { border-color: color-mix(in srgb, var(--brass) 55%, var(--line)); }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  border-color: var(--brass);
  background: var(--ink-600);
}
select {
  appearance: none;
  /* Explicit colors so native select stays readable in Windows dark mode. */
  background-color: var(--ink-700);
  color: var(--text);
  padding-right: 2rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-dim) 50%),
                    linear-gradient(135deg, var(--text-dim) 50%, transparent 50%);
  background-position: right 1rem center, right .72rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
select option { background: var(--ink-800); color: var(--text); }

/* Windows high-contrast: force explicit select colors. */
@media (forced-colors: active) {
  select { background: Canvas; color: CanvasText; }
}

.check {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-height: 2.6rem;
  font-size: .86rem;
  cursor: pointer;
  touch-action: manipulation;
}
.check input[type="checkbox"], .check input[type="radio"] {
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--brass);
  flex-shrink: 0;
  cursor: pointer;
}

/* Segmented radio group — one hit target, no dead zones. */
.seg {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: .4rem;
  margin-bottom: 1.1rem;
}
.seg label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  min-height: 2.9rem;
  padding: .5rem .35rem;
  border: 1px solid var(--line);
  font-size: .85rem;
  font-weight: 500;
  cursor: pointer;
  touch-action: manipulation;
  transition: border-color var(--speed) ease, background var(--speed) ease, color var(--speed) ease;
}
.seg input { position: absolute; opacity: 0; pointer-events: none; }
.seg label:hover { border-color: var(--brass); }
.seg label:has(input:checked) {
  border-color: var(--brass);
  background: color-mix(in srgb, var(--brass) 14%, transparent);
  color: var(--text);
}
.seg label:has(input:focus-visible) { outline: 2px solid var(--brass); outline-offset: 2px; }
.seg .arrow { font-family: var(--font-mono); font-weight: 600; }

/* ---------- 13. Amount input ------------------------------------------- */
.amount-big {
  display: grid;
  gap: .35rem;
  margin-bottom: 1.1rem;
  padding: .9rem 1rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--brass);
  background: var(--ink-700);
}
.amount-big label {
  font-family: var(--font-mono);
  font-size: .66rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.amount-big input {
  min-height: 3.4rem;
  padding: .25rem 0;
  border: 0;
  background: none;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.55rem, 5.4vw, 2.15rem);
  font-weight: 600;
  letter-spacing: -.03em;
  text-align: right;
}
.amount-big input:focus-visible { background: none; }

/* ---------- 14. Suggest badge ------------------------------------------ */
.suggest {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  min-height: 2rem;
  padding: .25rem .65rem;
  border: 1px dashed var(--line);
  font-size: .82rem;
  color: var(--text-dim);
}
.suggest[data-state="ready"] {
  border-style: solid;
  border-color: color-mix(in srgb, var(--brass) 50%, var(--line));
  color: var(--text);
}
.suggest .tag {
  padding: .05rem .4rem;
  background: var(--ink-600);
  font-family: var(--font-mono);
  font-size: .74rem;
}
.suggest .tag.in { color: var(--jade); }
.suggest .tag.ex { color: var(--vermilion); }

/* ---------- 15. Tables (ledger) ---------------------------------------- */
.table-wrap { overflow-x: auto; overscroll-behavior-x: contain; }

table.ledger {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  font-size: .92rem;
}

.ledger caption {
  margin-bottom: .6rem;
  text-align: left;
  color: var(--text-dim);
  font-size: .8rem;
}

.ledger th, .ledger td {
  padding: .6rem .55rem;
  border-bottom: 1px solid var(--line-soft);
  text-align: left;
  vertical-align: baseline;
}

/* Sticky only inside a scrolling table container. On a short card (like the
   dashboard's 6-row preview) a page-sticky header would float free and
   overlap the rows beneath it. */
.table-scroll {
  max-height: 70vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.table-scroll .ledger thead th { position: sticky; top: 0; z-index: 2; }

.ledger thead th {
  background: var(--ink-900);
  border-bottom: 1px solid var(--brass-soft);
  font-family: var(--font-mono);
  font-size: .64rem;
  font-weight: 500;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--text-dim);
  white-space: nowrap;
}

.ledger .col-date { width: 7.5rem; }
.ledger .col-amount { width: 12.5rem; text-align: right; }
.ledger .col-type { width: 5.5rem; }
/* Cukup untuk tombol Edit + Hapus (.btn-sm) dalam satu baris. */
.ledger .col-act { width: 9rem; text-align: right; }

.ledger td.desc {
  overflow-wrap: anywhere;
  word-break: break-word;
}
/* content-visibility only makes sense for rows of a fixed height in normal
   flow; the mobile stacked layout below changes display, so it opts out. */
.ledger tbody tr { content-visibility: auto; contain-intrinsic-size: auto 2.6rem; }
.ledger tbody tr:hover { background: color-mix(in srgb, var(--brass) 6%, transparent); }

.ledger td.amount {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
  font-size: .95rem;
}
.ledger td.date {
  font-family: var(--font-mono);
  font-size: .82rem;
  color: var(--text-dim);
  white-space: nowrap;
}

/* Signed pills: icon + sign + colour, never colour alone. */
.pill {
  display: inline-flex;
  align-items: baseline;
  gap: .3rem;
  padding: .1rem .45rem;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: .82rem;
  font-weight: 500;
  white-space: nowrap;
}
.pill.income { color: var(--jade); background: color-mix(in srgb, var(--jade) 13%, transparent); }
.pill.expense { color: var(--vermilion); background: color-mix(in srgb, var(--vermilion) 13%, transparent); }
.pill.neutral { color: var(--text-dim); background: var(--ink-700); }

.type-tag {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.type-tag.in { color: var(--jade); }
.type-tag.ex { color: var(--vermilion); }

tr.is-highlight { outline: 2px solid var(--brass); outline-offset: -2px; }
tr.is-highlight td { background: color-mix(in srgb, var(--brass) 9%, transparent); }

/* ---------- 16. Category groups ---------------------------------------- */
.group {
  border: 1px solid var(--line);
  background: var(--ink-800);
  margin-bottom: .8rem;
}

.group > summary {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .75rem .9rem;
  cursor: pointer;
  list-style: none;
  font-size: .95rem;
  scroll-margin-top: 6rem;
  transition: background var(--speed) ease;
}
.group > summary::-webkit-details-marker { display: none; }
.group > summary:hover { background: var(--ink-700); }
.group > summary::before {
  content: "▸";
  font-size: .7rem;
  color: var(--brass);
  transition: transform var(--speed) ease;
  flex-shrink: 0;
}
.group[open] > summary::before { transform: rotate(90deg); }

.group-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}
.group-count {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: .7rem;
  color: var(--text-dim);
}
.group-totals {
  display: flex;
  gap: .4rem;
  margin-left: auto;
  flex-shrink: 0;
  align-items: center;
}
.group-body { border-top: 1px solid var(--line); }

/* ---------- 17. Empty state -------------------------------------------- */
.empty {
  display: grid;
  gap: .55rem;
  justify-items: start;
  padding: clamp(1.5rem, 5vw, 3rem);
  border: 1px dashed var(--line);
  color: var(--text-dim);
}
.empty h2, .empty h3 { color: var(--text); }
.empty .glyph { font-family: var(--font-display); font-size: 2.2rem; color: var(--brass); }

/* ---------- 18. Pagination --------------------------------------------- */
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  flex-wrap: wrap;
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  font-size: .84rem;
  color: var(--text-dim);
}
.pager-links { display: flex; gap: .4rem; align-items: center; }

/* ---------- 19. Dialog -------------------------------------------------- */
dialog.sheet {
  width: min(30rem, calc(100vw - 2rem));
  padding: 0;
  border: 1px solid var(--brass-soft);
  background: var(--ink-800);
  color: var(--text);
  box-shadow: var(--shadow);
  overscroll-behavior: contain;
}
dialog.sheet::backdrop { background: color-mix(in srgb, var(--ink-900) 78%, transparent); }
.sheet-head, .sheet-body, .sheet-foot { padding: 1rem 1.15rem; }
.sheet-head { border-bottom: 1px solid var(--line); }
.sheet-foot {
  display: flex;
  gap: .6rem;
  justify-content: flex-end;
  flex-wrap: wrap;
  border-top: 1px solid var(--line);
}

/* ---------- 20. Forms: add / edit -------------------------------------- */
.form-card {
  display: grid;
  gap: 1rem;
  border: 1px solid var(--line);
  background: var(--ink-800);
  padding: clamp(1rem, 3vw, 1.75rem);
}
.form-grid {
  display: grid;
  gap: .9rem;
  grid-template-columns: 1fr;
}
@media (min-width: 44rem) {
  .form-grid { grid-template-columns: 1fr 1fr; }
  .form-grid .span-2 { grid-column: 1 / -1; }
}

.hint { font-size: .78rem; color: var(--text-dim); line-height: 1.5; }
.error-text { font-size: .78rem; color: var(--vermilion); }
[aria-invalid="true"] { border-color: var(--vermilion); }

.month-strip {
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
  align-items: center;
  margin-bottom: 1.25rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--line);
}

/* Navigator bulan: bulan sebelumnya | bulan aktif (highlight) | bulan berikut. */
.month-nav {
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
  align-items: stretch;
}
.month-current {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  padding: .55rem 1.15rem;
  border: 1px solid var(--brass);
  background: var(--brass);
  color: #0b0e13;
  font-size: .88rem;
  font-weight: 600;
  white-space: nowrap;
}

/* ---------- 21. Auth ----------------------------------------------------- */
.app-auth {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 1.5rem;
}
.auth-wrap { position: relative; z-index: 1; width: min(24rem, 100%); }

/* Theme switcher floats in the corner of the bare login/register shell. */
.theme-switch-auth {
  position: fixed;
  top: 1rem;
  right: var(--gutter);
  z-index: 5;
}
.auth-card {
  display: grid;
  gap: 1.1rem;
  border: 1px solid var(--line);
  border-top: 2px solid var(--brass);
  background: var(--ink-800);
  padding: clamp(1.25rem, 4vw, 2rem);
  box-shadow: var(--shadow);
}
.auth-card h1 { font-size: clamp(1.7rem, 6vw, 2.2rem); }
.auth-mark {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--brass);
  color: var(--brass);
  font-family: var(--font-display);
  font-size: 1.3rem;
  padding-bottom: .1em;
}

.auth-sep {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin: .15rem 0;
  color: var(--text-dim);
  font-size: .74rem;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.auth-sep::before, .auth-sep::after { content: ""; height: 1px; background: var(--line); flex: 1; }

.auth-alt { font-size: .84rem; color: var(--text-dim); text-align: center; }
.auth-alt a { color: var(--brass); }

.auth-legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .35rem .9rem;
  padding-top: .9rem;
  border-top: 1px solid var(--line-soft);
  font-size: .74rem;
}
.auth-legal a { color: var(--text-dim); text-decoration: none; }
.auth-legal a:hover { color: var(--brass); text-decoration: underline; }

/* ---------- 22. Installer ------------------------------------------------ */
.app-install { padding: clamp(1.25rem, 4vw, 3rem); }
.install-wrap {
  position: relative;
  z-index: 1;
  width: min(58rem, 100%);
  margin-inline: auto;
}
.install-head { margin-bottom: 1.5rem; }
.install-head h1 { margin: .3rem 0 .5rem; }

.stepper {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  list-style: none;
  padding: 0;
  margin: 0 0 1.75rem;
  border-bottom: 1px solid var(--line);
  padding-bottom: 1rem;
}
.stepper-item { flex: 1 1 8rem; min-width: 0; }
.stepper-item > a, .stepper-item > span {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-height: 2.5rem;
  padding: .35rem .55rem;
  color: var(--text-dim);
  font-size: .82rem;
  text-decoration: none;
}
.stepper-num {
  display: grid;
  place-items: center;
  width: 1.55rem;
  height: 1.55rem;
  flex-shrink: 0;
  border: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: .72rem;
}
.stepper-item.is-done { color: var(--text); }
.stepper-item.is-done .stepper-num { border-color: var(--jade); color: var(--jade); }
.stepper-item.is-active { color: var(--text); }
.stepper-item.is-active .stepper-num { border-color: var(--brass); background: var(--brass); color: #0b0e13; }
.stepper-item.is-todo { opacity: .55; }

.install-panel {
  display: grid;
  gap: 1.25rem;
  border: 1px solid var(--line);
  background: var(--ink-800);
  padding: clamp(1.1rem, 3vw, 1.9rem);
}
.panel-grid { display: grid; gap: 1rem; }
/* A shorter column stretches to its sibling's height; pack its form rows at
   the top so a lone control (e.g. the per-page select) doesn't hang in the
   vertical center of the spare space. */
.panel-grid > form { align-content: start; }
@media (min-width: 46rem) { .panel-grid { grid-template-columns: 1fr 1fr; } }
.span-2 { grid-column: 1 / -1; }

.notice {
  display: flex;
  gap: .6rem;
  padding: .7rem .9rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--brass);
  background: var(--ink-700);
  font-size: .85rem;
}
.notice.is-danger { border-left-color: var(--vermilion); }
.notice.is-ok { border-left-color: var(--jade); }
.notice .glyph { font-family: var(--font-mono); flex-shrink: 0; }
.notice p { min-width: 0; overflow-wrap: anywhere; }

.checks { display: grid; gap: .4rem; }
.check-row {
  display: grid;
  grid-template-columns: 1.5rem 1fr;
  gap: .6rem;
  align-items: start;
  padding: .55rem .7rem;
  border: 1px solid var(--line-soft);
  background: var(--ink-700);
}
.check-row .mark {
  font-family: var(--font-mono);
  font-size: .82rem;
  line-height: 1.5;
}
.check-row.ok .mark { color: var(--jade); }
.check-row.no .mark { color: var(--vermilion); }
.check-row .name { font-size: .87rem; }
.check-row .detail { display: block; color: var(--text-dim); font-size: .76rem; overflow-wrap: anywhere; }
.check-row.no { border-left: 3px solid var(--vermilion); }
.check-row.ok { border-left: 3px solid color-mix(in srgb, var(--jade) 55%, transparent); }

.check-group-title {
  margin: 1.1rem 0 .5rem;
  font-family: var(--font-mono);
  font-size: .64rem;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.method-picker { display: grid; gap: .55rem; }
.radio-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .7rem;
  align-items: start;
  padding: .75rem .85rem;
  border: 1px solid var(--line);
  cursor: pointer;
  touch-action: manipulation;
  transition: border-color var(--speed) ease, background var(--speed) ease;
}
.radio-card:hover { border-color: var(--brass); }
.radio-card:has(input:checked) {
  border-color: var(--brass);
  background: color-mix(in srgb, var(--brass) 9%, transparent);
}
.radio-card input { margin-top: .18rem; accent-color: var(--brass); width: 1.05rem; height: 1.05rem; }
.radio-card .t { font-size: .9rem; font-weight: 500; }
.radio-card .d { display: block; color: var(--text-dim); font-size: .78rem; margin-top: .15rem; }
.method-body { display: grid; gap: .7rem; padding: .5rem .2rem 0; }
.method-body[hidden] { display: none; }

.done-panel { display: grid; gap: 1rem; }
.done-stamp {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  align-self: start;
  padding: .45rem .9rem;
  border: 2px solid var(--jade);
  color: var(--jade);
  font-family: var(--font-mono);
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}

dl.facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .4rem 1rem;
  font-size: .86rem;
  margin: 0;
}
dl.facts dt { color: var(--text-dim); }
dl.facts dd { margin: 0; font-family: var(--font-mono); overflow-wrap: anywhere; }

/* ---------- 23. Keyword / category lists -------------------------------- */
.kw-table td:first-child { font-family: var(--font-mono); font-size: .84rem; }
.kw-arrow { color: var(--brass); }
.scroll-y { max-height: 24rem; overflow-y: auto; overscroll-behavior: contain; }

.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
}
.tag {
  padding: .15rem .5rem;
  border: 1px solid var(--line);
  font-size: .78rem;
  color: var(--text-dim);
}

/* ---------- 24. Bottom nav (mobile) ------------------------------------ */
.bottomnav { display: none; }

@media (max-width: 52rem) {
  .mainnav { display: none; }
  .theme-label { display: none; }
  .logout-form { margin-left: auto; }

  .foot { padding-bottom: 5rem; }
  .shell { padding-bottom: 6rem; }

  /* Below ~44rem a 5-column ledger cannot fit: date, type and amount all
     compete for width while the description — the thing you actually read —
     collapses to one character per line. So each row becomes a stacked card:
     the amount leads, the description follows, and metadata sits underneath. */
  .ledger { table-layout: auto; }
  .ledger thead { display: none; }
  /* Nested scrollers on touch are disorienting — let the page scroll instead. */
  .table-scroll { max-height: none; overflow-y: visible; }
  /* Rows become grid cards here, so the desktop contain-intrinsic-size
     optimisation must be switched off or rows collapse to nothing. */
  .ledger tbody tr { content-visibility: visible; contain-intrinsic-size: none; }
  .ledger tbody tr {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "amount amount"
      "desc  desc"
      "meta  act";
    gap: .25rem .6rem;
    padding: .75rem .8rem;
    border-bottom: 1px solid var(--line-soft);
    align-items: center;
  }
  .ledger tbody tr:hover { background: color-mix(in srgb, var(--brass) 6%, transparent); }

  .ledger td { display: block; padding: 0; border: 0; }

  .ledger td.amount {
    grid-area: amount;
    text-align: left;
    font-size: 1.05rem;
  }
  .ledger td.amount .pill { font-size: .95rem; }

  .ledger td.desc {
    grid-area: desc;
    order: 2;
    font-size: .95rem;
    line-height: 1.4;
  }

  .ledger td.date {
    grid-area: meta;
    font-size: .76rem;
    color: var(--text-dim);
    white-space: nowrap;
  }

  .ledger td:last-child {
    grid-area: act;
    text-align: right;
  }
  .ledger td:last-child .split { gap: .55rem; }

  .ledger .col-date,
  .ledger .col-amount,
  .ledger .col-type,
  .ledger .col-act { width: auto; }

  /* The type column duplicates the ↑/↓ already in the amount pill. */
  .ledger td[data-col="type"] { display: none; }
  .ledger td.date::after { content: " ·"; }

  .ledger tbody tr.is-highlight { outline-offset: -2px; }

  .group-body { border-top: 1px solid var(--line); }
  .group > summary { padding: .7rem .75rem; flex-wrap: wrap; }
  .group-totals { width: 100%; margin-left: 0; justify-content: flex-start; padding-top: .35rem; }

  .bottomnav {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 30;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    background: color-mix(in srgb, var(--ink-900) 94%, transparent);
    backdrop-filter: blur(12px);
    border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .bottomnav a {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .1rem;
    padding: .55rem .25rem .5rem;
    min-height: 3.1rem;
    justify-content: center;
    color: var(--text-dim);
    font-size: 1.05rem;
    text-decoration: none;
    touch-action: manipulation;
    -webkit-tap-highlight-color: color-mix(in srgb, var(--brass) 26%, transparent);
  }
  .bottomnav a span:last-child { font-size: .64rem; letter-spacing: .02em; }
  .bottomnav a[aria-current="page"] { color: var(--brass); }
  .bottomnav a:hover { color: var(--text); }
}

@media (max-width: 30rem) {
  .brand-text { display: none; }
  .seg { font-size: .78rem; }
  .toasts-top { right: .5rem; left: .5rem; width: auto; }
}

/* ---------- 25. Motion --------------------------------------------------- */
.reveal { animation: reveal-in 460ms cubic-bezier(.2, .75, .25, 1) both; }
.reveal-1 { animation-delay: 60ms; }
.reveal-2 { animation-delay: 130ms; }
.reveal-3 { animation-delay: 200ms; }
.reveal-4 { animation-delay: 270ms; }

@keyframes reveal-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* Count-up figures animate via JS (data-countup) and fall back to the
   server-rendered value when JS is off or motion is reduced. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .bar-fill { animation: none; }
  .reveal { opacity: 1; transform: none; }
}

/* ---------- 26. Utilities ------------------------------------------------ */
.stack { display: grid; gap: 1rem; }
.stack-sm { display: grid; gap: .5rem; }
.stack-lg { display: grid; gap: 2rem; }
.split {
  display: flex;
  gap: .75rem;
  align-items: center;
  flex-wrap: wrap;
}
.push { margin-left: auto; }
.hide-sm { display: initial; }
.text-brass { color: var(--brass); }
.text-jade { color: var(--jade); }
.text-vermilion { color: var(--vermilion); }

@media (max-width: 40rem) {
  .hide-sm { display: none; }
}

/* ---------- 27. Print ---------------------------------------------------- */
@media print {
  .topbar, .bottomnav, .foot, .toasts, .btn, .toolbar, .pager { display: none !important; }
  body { background: #fff; color: #000; }
  .grain { display: none; }
  .ledger thead th { position: static; }
}

/* ---------- 28. Landing page ------------------------------------------ */
/* Editorial landing shown to guests at "/". Motion lives in landing.js
   (vendored GSAP); CSS only holds the no-JS baseline. */

.l-hero {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  padding-top: clamp(2rem, 5vw, 3.5rem);
}
@media (min-width: 62rem) {
  .l-hero { grid-template-columns: 1.05fr .95fr; }
}

.l-eyebrow {
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--brass);
  margin-bottom: 1.1rem;
}

.l-hero h1 { font-size: clamp(2.5rem, 5.4vw, 4rem); }

.l-sub {
  margin-top: 1.1rem;
  max-width: 33rem;
  color: var(--text-dim);
  font-size: 1.02rem;
}

.l-cta {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  align-items: center;
  margin-top: 1.9rem;
}
/* Google sign-in is the only CTA wrapped in a <form> (plain GET submit,
   no JS). Take the wrapper out of layout so the submit button sits on the
   same flex footing — and the same height — as the anchor buttons. */
.l-cta > form { display: contents; }
.l-cta-note {
  width: 100%;
  margin-top: .7rem;
  font-size: .8rem;
  color: var(--text-dim);
}
.l-cta-note a { color: var(--brass); }
.l-hero .chips { margin-top: 1.7rem; }

/* Sample ledger card — decorative, aria-hidden in the view. */
.l-ledger-wrap { position: relative; }

/* Mascot peeking from behind the sample ledger. Static no-JS baseline —
   landing.js layers scroll parallax (transform-only) on top. DOM order
   keeps it painted beneath the ledger without a z-index. */
.l-mascot {
  position: absolute;
  top: -3.6rem;
  left: -0.6rem;
  width: clamp(6.5rem, 17vw, 10rem);
  height: auto;
  pointer-events: none;
  /* Face the hero copy: mirror the art. Standalone `scale` composes with
     the `transform` that GSAP drives for parallax — neither clobbers it. */
  scale: -1 1;
}
@media (min-width: 62rem) {
  .l-mascot { top: -4.6rem; left: -1.2rem; }
}

.l-ledger {
  position: relative;
  border: 1px solid var(--line);
  background: var(--ink-800);
  box-shadow: var(--shadow);
  padding: clamp(1.1rem, 2.6vw, 1.7rem);
  transform: rotate(-.6deg);
}

/* Guilloché hairline texture, same motif as the dashboard hero. */
.l-ledger::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(58deg, color-mix(in srgb, var(--brass) 11%, transparent) 0 1px, transparent 1px 9px),
    repeating-linear-gradient(-58deg, color-mix(in srgb, var(--brass) 8%, transparent) 0 1px, transparent 1px 13px);
  opacity: .55;
  pointer-events: none;
}
.l-ledger > * { position: relative; }

.l-ledger-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
  padding-bottom: .7rem;
  border-bottom: 1px solid var(--line);
}
.l-ledger-title { font-family: var(--font-display); font-size: 1.15rem; }
.l-ledger-month {
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.l-row {
  display: grid;
  grid-template-columns: 3.4rem 1fr auto;
  gap: .75rem;
  align-items: baseline;
  padding: .55rem 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: .88rem;
}
.l-row .d { font-family: var(--font-mono); font-size: .76rem; color: var(--text-dim); }
.l-row .cat { display: block; font-size: .72rem; color: var(--text-dim); }

.l-amt {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.l-amt.pos { color: var(--jade); }
.l-amt.neg { color: var(--vermilion); }

.l-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
  padding-top: .85rem;
}
.l-total-label { font-size: .78rem; color: var(--text-dim); }
.l-total .l-amt { font-size: 1.3rem; font-weight: 600; }

/* Brass coins drifting beside the ledger — a gentle "float". */
.l-coin {
  position: absolute;
  display: grid;
  place-items: center;
  width: 3.1rem;
  height: 3.1rem;
  border: 1px solid var(--brass);
  border-radius: 50%;
  background: var(--ink-800);
  color: var(--brass);
  font-family: var(--font-display);
  font-size: 1rem;
  box-shadow: var(--shadow);
  animation: l-float 4.4s ease-in-out infinite alternate;
}
.l-coin-a { top: -1.4rem; right: 8%; }
.l-coin-b {
  bottom: -1.1rem;
  left: -4%;
  width: 2.3rem;
  height: 2.3rem;
  font-size: .8rem;
  animation-duration: 5.6s;
}
@keyframes l-float {
  from { transform: translateY(-7px); }
  to   { transform: translateY(7px); }
}

/* Features */
.l-features {
  padding: clamp(3rem, 8vw, 5.5rem) 0;
  border-top: 1px solid var(--line-soft);
}
.l-sec-head { max-width: 46rem; margin-bottom: clamp(1.8rem, 4vw, 3rem); }
.l-sec-head h2 { font-size: clamp(1.9rem, 3.6vw, 2.7rem); }
.l-rule { display: block; width: 4.5rem; height: 1px; background: var(--brass); margin-top: 1.1rem; }

.l-grid {
  display: grid;
  gap: clamp(.9rem, 2vw, 1.25rem);
  list-style: none;
  padding: 0;
}
@media (min-width: 48rem) {
  .l-grid { grid-template-columns: 1fr 1fr; }
}

.l-card {
  border: 1px solid var(--line);
  background: var(--ink-800);
  padding: clamp(1.2rem, 3vw, 1.8rem);
  transition: border-color var(--speed) ease, transform var(--speed) ease;
}
@media (hover: hover) and (pointer: fine) {
  .l-card:hover { border-color: var(--brass); transform: translateY(-3px); }
}
.l-num {
  display: block;
  margin-bottom: .8rem;
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .18em;
  color: var(--brass);
}
.l-card h3 { font-size: 1.28rem; margin-bottom: .5rem; }
.l-card p { color: var(--text-dim); font-size: .92rem; }

/* Closing band */
.l-cta-band {
  background: var(--ink-800);
  padding: clamp(3rem, 8vw, 5rem) 0;
  text-align: center;
}
.l-cta-inner { max-width: 44rem; margin-inline: auto; }
.l-cta-band h2 { font-size: clamp(1.9rem, 4vw, 2.8rem); margin-bottom: .7rem; }
.l-cta-band p { color: var(--text-dim); margin-bottom: 1.6rem; }
.l-cta-band .btn-row { justify-content: center; }

/* Reduced motion: keep opacity/colour cues, drop movement. */
@media (prefers-reduced-motion: reduce) {
  .l-coin { animation: none; }
  .l-card { transition: none; }
}

