/* ===========================================================
   LEDGER — Monthly Planner
   Warm paper ledger aesthetic, ink-stamp totals, mono numerals
   Themeable via [data-theme] on <html>; see THEMES section below.
=========================================================== */

:root{
  /* Core surfaces */
  --paper:        #FFFFFF;
  --paper-edge:   #EDEDED;
  --card:         #FFFFFF;

  /* Text */
  --ink:          #111111;
  --ink-soft:     #5C5C5C;

  /* Borders */
  --line:         #D6D6D6;
  --line-soft:    #E6E6E6;

  /* Amount accent colors — reserved for actual income/expense values */
  --green:        #1E7A4C;
  --red:          #B23B3B;
  --stamp-positive: #4ADE94;
  --stamp-negative: #F08A8A;

  /* Status accent — recurring bills only. Kept separate from green/red
     since those are reserved for income/expense amounts, not status. */
  --blue:         #3568C2;

  /* The "ink stamp" block (header buttons, bill icons, Net Amount stamp,
     Bill Totals cards) — a deliberately fixed dark surface so the stamp
     motif reads consistently even in light themes. Dark theme adjusts
     this to a slightly lighter near-black so it still stands out. */
  --stamp-bg:     #111111;
  --stamp-ink:    #FFFFFF;

  /* Quiet supporting tones (placeholders, hints, hover states, scrollbar) */
  --placeholder:      #B0B0B0;
  --placeholder-soft: #D2D2D2;
  --hint:             #C2C2C2;
  --hover-bg:         #FAFAFA;
  --hover-border:     #A8A8A8;
  --weekend-bg:       #FAFAFA;
  --synced-bg:        #F4F4F4;
  --scrollbar-thumb:       #D6D6D6;
  --scrollbar-thumb-hover: #B8B8B8;
  --save-dot:         #8A8A8A;
  --save-dot-saving:  #BFBFBF;
  --focus-ring: rgba(17,17,17,0.10);
  --bg-dot: rgba(0,0,0,0.035);

  --serif: 'Fraunces', Georgia, serif;
  --mono:  'IBM Plex Mono', ui-monospace, monospace;
  --sans:  'Inter', -apple-system, BlinkMacSystemFont, sans-serif;

  --radius-lg: 14px;
  --radius-md: 10px;
  --radius-sm: 7px;
}

/* ============================================================
   THEMES
   Applied via <html data-theme="...">. "classic" is the default
   and matches :root above exactly (kept separate for clarity).
============================================================ */

/* Classic — mono black & white (default) */
[data-theme="classic"]{
  --paper: #FFFFFF; --paper-edge: #EDEDED; --card: #FFFFFF;
  --ink: #111111; --ink-soft: #5C5C5C;
  --line: #D6D6D6; --line-soft: #E6E6E6;
  --stamp-bg: #111111; --stamp-ink: #FFFFFF;
  --placeholder: #B0B0B0; --placeholder-soft: #D2D2D2; --hint: #C2C2C2;
  --hover-bg: #FAFAFA; --hover-border: #A8A8A8;
  --weekend-bg: #FAFAFA; --synced-bg: #F4F4F4;
  --scrollbar-thumb: #D6D6D6; --scrollbar-thumb-hover: #B8B8B8;
  --save-dot: #8A8A8A; --save-dot-saving: #BFBFBF;
  --focus-ring: rgba(17,17,17,0.10);
  --bg-dot: rgba(0,0,0,0.035);
  --blue: #3568C2;
}

/* Ledger Sepia — warm paper, walnut ink; the original design's first draft tone */
[data-theme="sepia"]{
  --paper: #FBF6EC; --paper-edge: #EFE6D3; --card: #FFFDF8;
  --ink: #2B2017; --ink-soft: #6B5A45;
  --line: #DDCBA8; --line-soft: #EBE0C8;
  --stamp-bg: #2B2017; --stamp-ink: #FBF6EC;
  --placeholder: #BFA980; --placeholder-soft: #E1D3AE; --hint: #CBB78F;
  --hover-bg: #F5ECD8; --hover-border: #C7AF82;
  --weekend-bg: #F5EEDD; --synced-bg: #F0E5CB;
  --scrollbar-thumb: #DDCBA8; --scrollbar-thumb-hover: #C7AF82;
  --save-dot: #8A7858; --save-dot-saving: #C7AF82;
  --green: #2F6B3F; --red: #A8472E;
  --blue: #3D62A8;
  --focus-ring: rgba(43,32,23,0.12);
  --bg-dot: rgba(43,32,23,0.05);
}

/* Slate — cool blue-gray, quiet office tone */
[data-theme="slate"]{
  --paper: #F4F6F8; --paper-edge: #E4E8EC; --card: #FFFFFF;
  --ink: #1B2430; --ink-soft: #5B6B7C;
  --line: #CDD6DE; --line-soft: #E2E8ED;
  --stamp-bg: #1B2430; --stamp-ink: #FFFFFF;
  --placeholder: #A9B5C0; --placeholder-soft: #D6DEE5; --hint: #B7C2CB;
  --hover-bg: #EBF0F4; --hover-border: #A0AEBB;
  --weekend-bg: #ECF1F5; --synced-bg: #E6ECF1;
  --scrollbar-thumb: #CDD6DE; --scrollbar-thumb-hover: #A0AEBB;
  --save-dot: #6E7E8C; --save-dot-saving: #A0AEBB;
  --green: #1E7A6C; --red: #B23B4E;
  --blue: #3C63B0;
  --focus-ring: rgba(27,36,48,0.12);
  --bg-dot: rgba(27,36,48,0.045);
}

/* Forest — deep green ink on soft sage paper */
[data-theme="forest"]{
  --paper: #F3F6F1; --paper-edge: #E3EBE0; --card: #FFFFFF;
  --ink: #1C2B1E; --ink-soft: #51624F;
  --line: #CBDAC6; --line-soft: #E1EADD;
  --stamp-bg: #1C2B1E; --stamp-ink: #F3F6F1;
  --placeholder: #A7BCA1; --placeholder-soft: #D4E2CF; --hint: #B7C9B1;
  --hover-bg: #EAF1E7; --hover-border: #9DB596;
  --weekend-bg: #ECF2E9; --synced-bg: #E4EDE1;
  --scrollbar-thumb: #CBDAC6; --scrollbar-thumb-hover: #9DB596;
  --save-dot: #5E7259; --save-dot-saving: #9DB596;
  --green: #2C7A4B; --red: #A8432E;
  --blue: #3568C2;
  --focus-ring: rgba(28,43,30,0.12);
  --bg-dot: rgba(28,43,30,0.05);
}

/* Dark — true dark mode */
[data-theme="dark"]{
  --paper: #16181C; --paper-edge: #0F1013; --card: #1D2025;
  --ink: #ECECEC; --ink-soft: #9AA0A8;
  --line: #34383F; --line-soft: #282C32;
  --stamp-bg: #050607; --stamp-ink: #F5F5F5;
  --placeholder: #565C64; --placeholder-soft: #3A3F46; --hint: #4D525A;
  --hover-bg: #24282E; --hover-border: #4A5057;
  --weekend-bg: #1A1D22; --synced-bg: #24282E;
  --scrollbar-thumb: #3A3F46; --scrollbar-thumb-hover: #4D525A;
  --save-dot: #7A8088; --save-dot-saving: #4D525A;
  --green: #3FCB82; --red: #E2685F;
  --blue: #5C8FE0;
  --stamp-positive: #3FCB82; --stamp-negative: #E2685F;
  --focus-ring: rgba(236,236,236,0.14);
  --bg-dot: rgba(255,255,255,0.035);
}

*{ box-sizing:border-box; }

html,body{
  margin:0;
  padding:0;
  background: var(--paper-edge);
  font-family: var(--sans);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

body{
  min-height:100vh;
  display:flex;
  justify-content:center;
  padding: 28px 20px 60px;
  background-image:
    radial-gradient(circle at 1px 1px, var(--bg-dot) 1px, transparent 0);
  background-size: 22px 22px;
}
body.scroll-locked{
  overflow: hidden;
  position: fixed;
  left: 0;
  right: 0;
  /* top is set inline by lockScroll() to preserve the current scroll position */
}

.paper{
  width:100%;
  max-width: 1320px;
  background: var(--paper);
  border-radius: 20px;
  border: 1px solid var(--line);
  box-shadow:
    0 1px 2px rgba(26,26,26,0.04),
    0 18px 40px -20px rgba(26,26,26,0.22),
    0 2px 0 rgba(255,255,255,0.6) inset;
  padding: 34px 38px 38px;
  position:relative;
}

.paper::before{
  content:"";
  position:absolute;
  top:0; left:48px; right:48px;
  height:1px;
  background: linear-gradient(90deg, transparent, var(--ink), transparent);
  opacity:0.3;
}

/* ---------- HEADER ---------- */

.head{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap: 28px;
  margin-bottom: 26px;
  flex-wrap: wrap;
}

.head-left{ flex: 0 0 auto; }

.brand-logo{
  max-height: 52px;
  max-width: 200px;
  width: auto;
  object-fit: contain;
  object-position: left center;
}
/* Show light logo by default; hide dark logo */
.brand-logo-light{ display: block; }
.brand-logo-dark { display: none;  }
/* Swap when dark theme is active */
[data-theme="dark"] .brand-logo-light{ display: none;  }
[data-theme="dark"] .brand-logo-dark { display: block; }

.title{
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 34px;
  margin: 0;
  letter-spacing: -0.01em;
  line-height: 1;
}

.subtitle{
  margin: 6px 0 0;
  font-size: 12.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 500;
}

.head-mid{ flex: 1 1 260px; display:flex; justify-content:center; }

.opening-balance{
  display:flex;
  align-items:stretch;
  background: var(--stamp-bg);
  border-radius: 10px;
  overflow:hidden;
  box-shadow: 0 6px 16px -8px rgba(0,0,0,0.5);
}

.ob-label{
  color: var(--stamp-ink);
  font-family: var(--sans);
  font-weight: 600;
  font-size: 13px;
  display:flex;
  align-items:center;
  padding: 0 16px;
  white-space:nowrap;
}

.ob-input-wrap{
  background: var(--card);
  display:flex;
  align-items:center;
  padding: 0 14px;
  gap: 2px;
}

.ob-dollar{ font-family: var(--mono); color: var(--ink-soft); font-size:14px; }

.ob-input{
  border:none;
  outline:none;
  background:transparent;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 15px;
  width: 110px;
  padding: 10px 4px;
  color: var(--ink);
}

.head-right{
  flex: 0 0 auto;
  display:flex;
  flex-direction:column;
  align-items:flex-end;
  gap:8px;
}

.month-nav{
  display:flex;
  align-items:center;
  gap: 4px;
}

.month-nav-arrow{
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--ink-soft);
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:0;
  flex-shrink:0;
  transition: border-color .15s ease, color .15s ease, transform .1s ease;
}
.month-nav-arrow svg{ width:14px; height:14px; }
.month-nav-arrow:hover{ border-color: var(--hover-border); color: var(--ink); }
.month-nav-arrow:active{ transform: scale(0.92); }

.month-field{
  position:relative;
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
}

.month-nav-label{
  font-family: var(--serif);
  font-size: 16px;
  font-style: italic;
  font-weight: 500;
  text-align:center;
  color: var(--ink-soft);
  border-bottom: 1.5px solid var(--ink);
  padding: 2px 4px 4px;
  min-width: 132px;
  white-space:nowrap;
}

/* The real <input type="month"> is visually invisible but sits directly
   over the label and stays fully interactive — clicking anywhere on the
   label opens the native month/year picker, while updateMonthNavLabel()
   keeps the friendly "July 2026" text in sync with state.currentMonth. */
.month-input{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  opacity:0;
  border:none;
  background:transparent;
  cursor:pointer;
  padding:0;
  margin:0;
}

.head-actions{ display:flex; align-items:center; gap:12px; }

/* "Copy Previous Month" — same circular shape/border as the theme
   trigger right next to it, so the two read as a matched pair of icon
   buttons in the toolbar. Hidden entirely via JS (not just disabled)
   when the previous calendar month has no data to offer, rather than
   sitting there as a control that can never do anything; not
   destructive on its own — the confirm dialog only appears when it
   would actually overwrite something. */
.icon-circle-btn{
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--placeholder);
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:0;
  flex-shrink:0;
  transition: border-color .15s ease, color .15s ease, transform .1s ease;
}
.icon-circle-btn svg{ width:15px; height:15px; }
.icon-circle-btn:hover{ border-color: var(--hover-border); color: var(--ink); }
.icon-circle-btn:active{ transform: scale(0.94); }
.icon-circle-btn[hidden]{ display:none; }
.icon-circle-btn:disabled{
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

/* Theme picker */
.theme-picker{ position:relative; }

.theme-trigger{
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: var(--card);
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:0;
  transition: border-color .15s ease, transform .1s ease;
}
.theme-trigger:hover{ border-color: var(--hover-border); }
.theme-trigger:active{ transform: scale(0.94); }

.theme-trigger-swatch{
  width: 18px; height: 18px;
  border-radius: 50%;
  display:block;
  background: conic-gradient(var(--stamp-bg) 0deg 180deg, var(--paper) 180deg 360deg);
  border: 1px solid var(--line);
}

.theme-menu{
  position:absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 28px -12px rgba(0,0,0,0.28);
  padding: 6px;
  display:flex;
  flex-direction:column;
  gap: 2px;
  min-width: 168px;
  z-index: 20;
}
.theme-menu[hidden]{ display:none; }

.theme-option{
  display:flex;
  align-items:center;
  gap: 10px;
  width:100%;
  background:none;
  border:none;
  border-radius: 7px;
  padding: 7px 8px;
  cursor:pointer;
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
  text-align:left;
}
.theme-option:hover{ background: var(--hover-bg); }
.theme-option.active{ font-weight: 700; }

.theme-option-swatch{
  width: 18px; height: 18px;
  border-radius: 50%;
  flex-shrink:0;
  border: 1px solid rgba(0,0,0,0.12);
}

.theme-option-check{
  margin-left:auto;
  width: 14px; height: 14px;
  color: var(--ink);
  flex-shrink:0;
  visibility:hidden;
}
.theme-option.active .theme-option-check{ visibility:visible; }

/* Export dropdown — same trigger+absolute-menu pattern as the theme
   picker, but the trigger is a labeled pill button (matches the old
   "Export PDF" button) rather than a circular swatch, and the menu
   holds two labeled options instead of a list of swatches. */
.export-picker{ position:relative; }

.export-trigger{
  display:flex;
  align-items:center;
  gap: 6px;
}
.export-trigger-caret{
  width: 13px; height: 13px;
  flex-shrink:0;
  transition: transform .15s ease;
}
.export-trigger[aria-expanded="true"] .export-trigger-caret{ transform: rotate(180deg); }

.export-menu{
  position:absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 28px -12px rgba(0,0,0,0.28);
  padding: 6px;
  display:flex;
  flex-direction:column;
  gap: 2px;
  min-width: 200px;
  z-index: 20;
}
.export-menu[hidden]{ display:none; }

.export-option{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap: 1px;
  width:100%;
  background:none;
  border:none;
  border-radius: 7px;
  padding: 7px 9px;
  cursor:pointer;
  text-align:left;
}
.export-option:hover{ background: var(--hover-bg); }

.export-option-label{
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
}
.export-option-sub{
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 500;
  color: var(--placeholder);
}

.icon-btn{
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-soft);
  border-radius: 7px;
  padding: 6px 12px;
  cursor:pointer;
  transition: all .15s ease;
}
.icon-btn:hover{ background: var(--hover-bg); border-color: var(--hover-border); color: var(--ink); }

.icon-btn.primary{
  background: var(--stamp-bg);
  border-color: var(--stamp-bg);
  color: var(--stamp-ink);
}
.icon-btn.primary:hover{
  background: var(--stamp-bg);
  border-color: var(--stamp-bg);
  color: var(--stamp-ink);
  opacity: 0.85;
}

.save-indicator{
  font-size: 11px;
  color: var(--save-dot);
  font-weight: 500;
  display:flex;
  align-items:center;
  gap:5px;
}
.save-indicator::before{
  content:"";
  width:6px; height:6px;
  border-radius:50%;
  background: var(--ink);
  display:inline-block;
  transition: background .2s;
}
.save-indicator.saving::before{ background: var(--save-dot-saving); }

/* ---------- BOARD: bill list + calendar ---------- */

.board{
  display:grid;
  grid-template-columns: 250px 1fr;
  gap: 18px;
  margin-bottom: 22px;
  align-items:start;
}

.board-right{
  display:flex;
  flex-direction:column;
  gap: 18px;
  min-width:0;
}

.section-label{
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 10px;
}

/* Bill list */
.bill-list{ display:flex; flex-direction:column; min-width:0; }

.bill-list-head{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:8px;
  margin-bottom: 10px;
}
.bill-list-head .section-label{ margin:0; }

/* "Remove All" — sits opposite the section title in both the Bill List
   and Income List headers. Quiet by default (placeholder-toned text, no
   border) so it doesn't compete with the title; only turns red on hover
   to signal it's destructive, matching the footer Reset button. */
.list-remove-all{
  border:none;
  background:transparent;
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--placeholder);
  cursor:pointer;
  padding: 3px 7px;
  border-radius: 6px;
  flex-shrink:0;
  transition: color .15s ease, background .15s ease;
}
.list-remove-all:hover{ color: var(--red); background: var(--hover-bg); }

/* "Collapse" — same quiet treatment as Remove All, but neutral (no red
   hover) since collapsing isn't destructive. Sits as the rightmost
   control in each section header. */
.list-collapse-toggle{
  border:none;
  background:transparent;
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--placeholder);
  cursor:pointer;
  padding: 3px 7px;
  border-radius: 6px;
  flex-shrink:0;
  transition: color .15s ease, background .15s ease;
}
.list-collapse-toggle:hover{ color: var(--ink); background: var(--hover-bg); }

/* Groups the right-side header controls (sum / Remove All / Collapse) so
   the title stays pinned left and this group stays pinned right as a
   single flex item — independent of which inner pieces are visible. */
.list-head-controls{
  display:flex;
  align-items:baseline;
  gap:4px;
  flex-shrink:0;
}

/* Sum shown in place of the rows once a section is collapsed — e.g.
   "$1,240 total". Hidden while expanded; only one of the two states is
   ever visible at once. */
.list-collapsed-sum{
  display:none;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-soft);
  white-space:nowrap;
  margin-right: 2px;
}

/* Collapsed state: an accordion per section, independent of the other.
   Rows hide, the header's controls stay visible (Remove All hides since
   there's nothing meaningful to remove-all-of when you can't see what's
   there), and the running total takes the place of the title's usual
   neighbor so the number is still visible at a glance. */
.bill-list-head.collapsed .list-remove-all,
.income-list-head.collapsed .list-remove-all{
  display:none;
}
.bill-list-head.collapsed .list-collapsed-sum,
.income-list-head.collapsed .list-collapsed-sum{
  display:inline;
}
.bill-rows-scroll.collapsed,
.income-rows-scroll.collapsed{
  display:none;
}

/* When one section is collapsed, let the other expand to fill the space. */
.bill-list.bills-collapsed .income-rows-scroll{
  max-height: min(660px, 70vh);
}
.bill-list.income-collapsed .bill-rows-scroll{
  max-height: min(660px, 70vh);
}

/* Fixed, generous cap rather than JS-measured height matching — simpler,
   and impossible to get into a broken state from a timing or measurement
   bug. A long bill list scrolls internally past this height. */
.bill-rows-scroll{
  max-height: min(320px, 35vh);
  overflow-y: auto;
  overflow-x: hidden;
}
/* Bottom fade so the scroll cut-off reads as an intentional blend into
   the page rather than an abrupt clip. Only applied (via JS toggling
   .has-fade) when there's actually more content below the fold — a
   list that fits in full stays fully visible with no fade. Mask-based,
   not a gradient overlay, so it works over any card content or theme
   background without needing a hardcoded color. */
.bill-rows-scroll.has-fade{
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
}
/* Scrollbar hidden — the fade signals more content instead */
.bill-rows-scroll::-webkit-scrollbar{ display:none; }
.bill-rows-scroll{ scrollbar-width: none; -ms-overflow-style: none; }

.bill-rows{
  display:flex;
  flex-direction:column;
  gap: 8px;
  /* Small inset so card shadows/focus rings don't clip against the
     scroll container's edge or get cut off by overflow:hidden elsewhere. */
  padding: 2px 2px 0;
}

/* Each bill is its own self-contained card: a top line (icon, name,
   remove) and a bottom line (due day, amount). Independent bordered
   cards, rather than a single dense multi-column grid of rows, render
   far more predictably across browsers — there's no shared grid track
   or tightly-packed row height for a layout engine to get wrong. */
.bill-card{
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 10px 10px 9px;
  display:flex;
  flex-direction:column;
  gap: 8px;
  transition: border-color .15s ease;
}
.bill-card:focus-within{
  border-color: var(--ink);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.bill-card-top{
  display:flex;
  align-items:center;
  gap: 8px;
}

.bill-icon-wrap{ position:relative; flex-shrink:0; }

.bill-icon{
  width: 22px; height:22px;
  border-radius:50%;
  background: var(--stamp-bg);
  color: var(--stamp-ink);
  display:flex; align-items:center; justify-content:center;
  flex-shrink:0;
  border:none;
  padding:0;
  font:inherit;
}
.bill-icon svg{ width:12px; height:12px; }

.bill-icon-trigger{
  cursor:pointer;
  transition: opacity .15s ease, box-shadow .15s ease;
}
.bill-icon-trigger:hover{ opacity: 0.8; }
.bill-icon-trigger:focus-visible{ box-shadow: 0 0 0 2px var(--focus-ring); outline:none; }
.bill-icon-wrap.menu-open .bill-icon-trigger{ box-shadow: 0 0 0 2px var(--focus-ring); }

/* Icon picker popover — grid of every icon in the library, same
   body-reparented positioning as the frequency popover (see
   createBodyPopover in app.js). */
.bill-icon-menu{
  position:fixed;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 28px -12px rgba(0,0,0,0.28);
  padding: 8px;
  display:grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 4px;
  width: 196px;
  z-index: 200;
}
.bill-icon-menu[hidden]{ display:none; }

.bill-icon-menu::before{
  content:"";
  position:absolute;
  top:14px;
  left:-5px;
  width:9px; height:9px;
  background: var(--card);
  border-left: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  transform: rotate(45deg);
}
.bill-icon-menu.flipped::before{
  left:auto;
  right:-5px;
  border-left:none;
  border-bottom:none;
  border-right: 1px solid var(--line);
  border-top: 1px solid var(--line);
}

.bill-icon-option{
  width: 28px; height: 28px;
  border-radius:50%;
  background: transparent;
  color: var(--ink-soft);
  border: 1px solid transparent;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer;
  padding:0;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.bill-icon-option svg{ width:14px; height:14px; }
.bill-icon-option:hover{ background: var(--hover-bg); border-color: var(--line); }
.bill-icon-option.active{ background: var(--stamp-bg); color: var(--stamp-ink); }

.bill-name-input{
  border:none;
  outline:none;
  background:transparent;
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  padding: 2px 0;
  width:100%;
  min-width:0;
}
.bill-name-input::placeholder{ color: var(--placeholder); }

.bill-recur-wrap{ position:relative; flex-shrink:0; }

.bill-recur{
  border:none;
  background:transparent;
  color: var(--placeholder);
  cursor:pointer;
  padding: 2px;
  flex-shrink:0;
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius: 4px;
  transition: color .15s ease, background .15s ease;
}
.bill-recur svg{ width:13px; height:13px; }
.bill-recur:hover{ color: var(--ink-soft); background: var(--hover-bg); }
.bill-recur.active{ color: var(--blue); }
.bill-recur.active:hover{ color: var(--blue); background: var(--hover-bg); }
.bill-recur-wrap.menu-open .bill-recur{ background: var(--hover-bg); }

/* Frequency popover — opens from the recurring icon. Reparented to <body>
   and positioned with `position:fixed` from JS (see openFreqMenu in
   app.js): the bill/income list scrolls inside an overflow:hidden
   container, so a popover anchored inside it would get silently clipped
   the moment it pokes past that container's edge — and a narrow, tightly
   stacked card list means that happens constantly. The position/transform
   here are just safe fallbacks; JS sets the real top/left every time it
   opens, including flipping to the left of the icon if the right side
   would run off the viewport. */
.bill-freq-menu{
  position:fixed;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 28px -12px rgba(0,0,0,0.28);
  padding: 5px;
  display:flex;
  flex-direction:column;
  gap: 1px;
  min-width: 110px;
  z-index: 200;
}
.bill-freq-menu[hidden]{ display:none; }

/* Small triangular pointer back toward the icon, so the popover still
   reads as anchored to it even though it's offset to the side. Points
   left by default (popover opens to the right of the icon); .flipped
   mirrors it to point right when the popover opens to the left instead. */
.bill-freq-menu::before{
  content:"";
  position:absolute;
  top:50%;
  left:-5px;
  width:9px; height:9px;
  background: var(--card);
  border-left: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  transform: translateY(-50%) rotate(45deg);
}
.bill-freq-menu.flipped::before{
  left:auto;
  right:-5px;
  border-left:none;
  border-bottom:none;
  border-right: 1px solid var(--line);
  border-top: 1px solid var(--line);
}

.bill-freq-option{
  display:flex;
  align-items:center;
  width:100%;
  background:none;
  border:none;
  border-radius: 6px;
  padding: 6px 8px;
  cursor:pointer;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
  text-align:left;
}
.bill-freq-option:hover{ background: var(--hover-bg); }
.bill-freq-option.active{ font-weight: 700; color: var(--blue); }

.bill-remove{
  border:none;
  background:transparent;
  color: var(--hint);
  font-size: 16px;
  line-height:1;
  cursor:pointer;
  padding: 2px 2px;
  flex-shrink:0;
  font-family: var(--sans);
}
.bill-remove:hover{ color: var(--red); }

.bill-card-bottom{
  display:flex;
  align-items:center;
  gap: 10px;
  padding-left: 30px; /* aligns under the name, past the icon column */
}

.bill-field{
  display:flex;
  align-items:center;
  gap: 6px;
  cursor:text;
}
.bill-field-date{ flex: 0 0 auto; }
.bill-field-amount{ flex: 1 1 auto; min-width:0; justify-content:flex-end; }

.bill-field-label{
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hint);
  flex-shrink:0;
}

.bill-date{
  border:1px solid var(--line);
  border-radius: 4px;
  outline:none;
  background: var(--card);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  text-align:center;
  width: 28px;
  padding: 3px 0;
  color: var(--ink-soft);
  -moz-appearance: textfield;
}
.bill-date::placeholder{ color: var(--placeholder-soft); }
.bill-date::-webkit-inner-spin-button,
.bill-date::-webkit-outer-spin-button{
  -webkit-appearance: none;
  margin:0;
}
.bill-date:focus{ border-color: var(--ink); }
.bill-date.has-value{ border-color: var(--ink); color: var(--ink); font-weight:600; }

/* Semi-monthly shows a second due-date input right next to the first
   (e.g. "Due [1] – [15]") instead of replacing it — both days matter
   equally, so neither reads as more "correct" than the other. */
.bill-field-date-double{ gap: 4px; }
.bill-date-sep{
  font-family: var(--mono);
  font-size: 10px;
  color: var(--placeholder-soft);
  flex-shrink:0;
}

.bill-amount-wrap{
  display:flex;
  align-items:center;
  gap:2px;
  justify-content:flex-end;
  min-width:0;
}
.bill-amount-wrap .dollar{ font-family: var(--mono); font-size:12px; color: var(--placeholder); flex-shrink:0; }

.bill-amount{
  border:none;
  outline:none;
  background:transparent;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 600;
  text-align:right;
  width: 100%;
  min-width:0;
  padding: 2px 0;
  color: var(--ink);
}
.bill-amount::placeholder{ color: var(--hint); }

/* Extra row: freeform note only */
.bill-card-extra{
  display:flex;
  align-items:center;
  gap: 8px;
  padding-left: 30px;
}

/* Payment method icon button — sits in the top row next to the recurring
   icon, using the same body-reparented popover as frequency/icon pickers. */
.bill-pm-wrap{ position:relative; flex-shrink:0; }

.bill-pm-btn{
  border:none;
  background:transparent;
  color: var(--placeholder);
  cursor:pointer;
  padding: 2px;
  flex-shrink:0;
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius: 4px;
  transition: color .15s ease, background .15s ease;
}
.bill-pm-btn svg{ width:13px; height:13px; }
.bill-pm-btn:hover{ color: var(--ink-soft); background: var(--hover-bg); }
.bill-pm-btn.active.pm-auto{ color: #7C3AED; }   /* purple for auto-pay */
.bill-pm-btn.active.pm-manual{ color: #D97706; } /* orange for manual */
.bill-pm-wrap.menu-open .bill-pm-btn{ background: var(--hover-bg); }

/* Payment method dropdown menu */
.bill-pm-menu{
  position:fixed;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 28px -12px rgba(0,0,0,0.28);
  padding: 5px;
  display:flex;
  flex-direction:column;
  gap: 1px;
  min-width: 100px;
  z-index: 200;
}
.bill-pm-menu[hidden]{ display:none; }
.bill-pm-menu::before{
  content:"";
  position:absolute;
  top:50%;
  left:-5px;
  width:9px; height:9px;
  background: var(--card);
  border-left: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  transform: translateY(-50%) rotate(45deg);
}
.bill-pm-menu.flipped::before{
  left:auto;
  right:-5px;
  border-left:none;
  border-bottom:none;
  border-right: 1px solid var(--line);
  border-top: 1px solid var(--line);
}

.bill-pm-option{
  display:flex;
  align-items:center;
  width:100%;
  background:none;
  border:none;
  border-radius: 6px;
  padding: 6px 8px;
  cursor:pointer;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
  text-align:left;
}
.bill-pm-option:hover{ background: var(--hover-bg); }
.bill-pm-option.active[data-pm="auto"]  { font-weight:700; color: #7C3AED; }
.bill-pm-option.active[data-pm="manual"]{ font-weight:700; color: #D97706; }
.bill-pm-option.active[data-pm=""]     { font-weight:700; color: var(--ink); }

.bill-note-input{
  border: none;
  outline: none;
  background: transparent;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 400;
  color: var(--ink-soft);
  width: 100%;
  min-width: 0;
  padding: 2px 0;
}
.bill-note-input::placeholder{ color: var(--placeholder-soft); font-style: italic; }

.bill-add-row{
  border:1px dashed var(--line);
  border-radius: var(--radius-md);
  background:transparent;
  color: var(--placeholder);
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align:center;
  cursor:pointer;
  padding: 11px 0;
  width:100%;
  margin-top: 8px;
}
.bill-add-row:hover{ color: var(--ink); background: var(--hover-bg); border-color: var(--hover-border); }

/* Trend graph card — sits below the bill list, tracks a chosen metric
   (Net/Income/Bills/Misc) across the 6 months ending at the one currently
   being viewed. Deliberately compact since it lives in the narrow sidebar
   column alongside the bill cards. */
.trend-card{
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
}

.trend-head{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:8px;
  margin-bottom: 12px;
}
.trend-head .section-label{ margin:0; }

.trend-metric-select{
  border:1px solid var(--line);
  border-radius: 6px;
  outline:none;
  background: var(--card);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  color: var(--ink);
  padding: 4px 22px 4px 8px;
  cursor:pointer;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M6 9L12 15L18 9' stroke='%23999999' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 6px center;
  background-size: 12px;
  transition: border-color .15s ease;
}
.trend-metric-select:hover{ border-color: var(--hover-border); }
.trend-metric-select:focus{ border-color: var(--ink); }

.trend-chart{
  display:flex;
  flex-direction:column;
  gap: 6px;
}

/* ---------- CATEGORY PIE CHART ---------- */

.pie-card{
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
}

.pie-head{
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 12px;
}
.pie-head .section-label{ margin: 0; }

.pie-body{
  display: flex;
  align-items: center;
  gap: 16px;
}

.pie-chart-wrap{
  flex-shrink: 0;
}

.pie-svg{
  display: block;
  width: 108px;
  height: 108px;
}


.pie-legend{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 0;
}

.pie-legend-item{
  display: grid;
  grid-template-columns: 10px 1fr auto auto;
  align-items: center;
  gap: 6px;
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--ink);
}

.pie-legend-dot{
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.pie-legend-label{
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink-soft);
  font-weight: 500;
}

.pie-legend-pct{
  font-weight: 700;
  color: var(--ink);
  min-width: 36px;
  text-align: right;
}

.pie-legend-val{
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-soft);
  min-width: 50px;
  text-align: right;
  /* Hidden by default — revealed on hover via .pie-row-active */
  opacity: 0;
  transition: opacity .15s ease;
}

.pie-row-active .pie-legend-val{
  opacity: 1;
}

/* Non-active slices dim when any slice is active */
.pie-slice{
  transition: opacity .15s ease, stroke-width .15s ease;
  cursor: pointer;
}
.pie-slice-active{
  stroke-width: 30 !important;
  opacity: 1 !important;
}
/* Dim siblings when one is active — we toggle active class only on the
   hovered slice, so target slices that are NOT active while a sibling IS */
.pie-svg:has(.pie-slice-active) .pie-slice:not(.pie-slice-active){
  opacity: 0.35;
}

/* Highlight the active legend row label */
.pie-legend-item{
  cursor: pointer;
  border-radius: 4px;
  transition: background .12s ease;
}
.pie-row-active{
  background: var(--hover-bg);
}
.pie-row-active .pie-legend-label{
  color: var(--ink);
}

.pie-empty{
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--placeholder);
  margin: 0;
  padding: 8px 0;
}

.trend-svg-wrap{
  height: 84px;
  width:100%;
}

.trend-svg{
  width:100%;
  height:100%;
  display:block;
  overflow:visible;
}

.trend-zero-line{
  stroke: var(--line);
  stroke-width: 1;
  stroke-dasharray: 2 2;
  vector-effect: non-scaling-stroke;
}

.trend-area{
  fill: var(--ink-soft);
  opacity: 0.07;
  stroke:none;
}

.trend-line{
  fill:none;
  stroke: var(--ink-soft);
  stroke-width: 1.75;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.trend-dot{
  fill: var(--card);
  stroke: var(--ink-soft);
  stroke-width: 1.75;
  vector-effect: non-scaling-stroke;
}
.trend-dot.current{ fill: var(--stamp-bg); stroke: var(--stamp-bg); }
.trend-dot.positive{ stroke: var(--green); }
.trend-dot.positive.current{ fill: var(--green); stroke: var(--green); }
.trend-dot.negative{ stroke: var(--red); }
.trend-dot.negative.current{ fill: var(--red); stroke: var(--red); }

.trend-labels-row{
  display:grid;
  grid-template-columns: repeat(6, 1fr);
}

.trend-col-label{
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--placeholder);
  text-align:center;
  cursor:default;
}
.trend-col-label.current{ color: var(--ink-soft); font-weight:700; }

/* Calendar */
.calendar{ min-width:0; }

.cal-top-row{
  display:flex;
  justify-content:flex-end;
  margin-bottom: 6px;
}

.cal-legend{
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 500;
  color: var(--placeholder-soft);
}
.cal-legend code{
  font-family: var(--mono);
  background: var(--synced-bg);
  border-radius: 3px;
  padding: 1px 4px;
  color: var(--ink-soft);
  font-size: 9.5px;
}

.cal-head{
  display:grid;
  grid-template-columns: repeat(7, 1fr);
  text-align:center;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  margin-bottom: 8px;
}

.cal-grid{
  display:grid;
  grid-template-columns: repeat(7, 1fr);
  grid-auto-rows: minmax(96px, auto);
  gap: 7px;
}

.cal-cell{
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 7px 8px 7px;
  display:flex;
  flex-direction:column;
  min-width:0;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.cal-cell:focus-within{
  border-color: var(--ink);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.cal-cell.weekend{ background: var(--weekend-bg); }

/* Today: a quiet marker so it's easy to find at a glance, but clearly a
   notch below the bright focus-within state used while actively editing
   a cell. A slightly stronger border + a faint tinted background does
   that without competing with real focus or the weekend tint. */
.cal-cell.is-today{
  border-color: var(--ink-soft);
  background: var(--synced-bg);
}
.cal-cell.is-today .cal-daynum{
  color: var(--ink-soft);
  font-weight: 600;
}
.cal-cell.is-today:focus-within{
  border-color: var(--ink);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.cal-daynum{
  font-family: var(--mono);
  font-size: 10px;
  color: var(--placeholder-soft);
  margin-bottom: 4px;
  flex-shrink:0;
}

.cal-items{
  display:flex;
  flex-direction:column;
  gap: 3px;
  flex: 1;
}

.cal-item-row{
  display:flex;
  align-items:center;
  gap: 4px;
}

.cal-item-row .dollar{
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--placeholder-soft);
  flex-shrink:0;
}

.cal-amount{
  border:none;
  outline:none;
  background:transparent;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  color: var(--red);
  width:100%;
  min-width:0;
  padding:1px 0;
}
.cal-amount::placeholder{ color: var(--placeholder-soft); font-weight:400; }
.cal-amount.income{ color: var(--green); }

.cal-item-note{
  border:none;
  outline:none;
  background:transparent;
  font-family: var(--sans);
  font-size: 9.5px;
  color: var(--ink-soft);
  width: 44%;
  min-width:0;
  flex-shrink:0;
  text-align:right;
}
.cal-item-note::placeholder{ color: var(--placeholder-soft); }

.cal-item-remove{
  border:none;
  background:transparent;
  color: var(--hint);
  font-size: 13px;
  line-height:1;
  cursor:pointer;
  padding: 0 0 0 2px;
  flex-shrink:0;
  font-family: var(--sans);
}
.cal-item-remove:hover{ color: var(--red); }

.cal-add-row{
  border:none;
  background:transparent;
  color: var(--placeholder);
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align:left;
  cursor:pointer;
  padding: 3px 0 1px;
  margin-top: 1px;
  align-self:flex-start;
}
.cal-add-row:hover{ color: var(--ink); }

/* Bill-synced line — auto-populated from the Bill List, read-only */
.cal-item-row.synced{
  background: var(--synced-bg);
  border-radius: 4px;
  padding: 1px 4px;
  margin: 0 -4px;
}
.cal-item-row.synced .cal-amount{
  color: var(--red);
  cursor:default;
  flex: 1 1 auto;
  width:auto;
  white-space:nowrap;
}
.cal-item-row.synced .cal-amount.income{ color: var(--green); }

/* The bill's own icon stands in for its name on the calendar — the Bill
   List is right there for the full label, and an icon reads faster in a
   cramped day cell. A small dot to its left marks a recurring bill; the
   icon itself always stays the same quiet ink-on-paper as everything
   else on the calendar. */
.cal-item-row.synced .cal-recur-dot{
  width:5px; height:5px;
  border-radius:50%;
  background: transparent;
  flex-shrink:0;
}
.cal-item-row.synced .cal-recur-dot.recurring{ background: var(--blue); }

/* Payment method dot — sits right after the recurring dot, same size.
   Purple = auto-pay, orange = manual. Transparent when not set. */
.cal-item-row.synced .cal-pm-dot{
  width:5px; height:5px;
  border-radius:50%;
  background: transparent;
  flex-shrink:0;
}
.cal-item-row.synced .cal-pm-dot.pm-auto  { background: #7C3AED; }
.cal-item-row.synced .cal-pm-dot.pm-manual{ background: #D97706; }

.cal-item-row.synced .cal-bill-icon{
  width:14px; height:14px;
  border-radius:50%;
  background: var(--stamp-bg);
  color: var(--stamp-ink);
  display:flex; align-items:center; justify-content:center;
  flex-shrink:0;
}
.cal-item-row.synced .cal-bill-icon svg{ width:8px; height:8px; }

/* Cells outside the active month (leading/trailing blanks) */
.cal-cell.blank{
  background: transparent;
  border-color: var(--line-soft);
  box-shadow:none;
}
.cal-cell.blank:focus-within{ box-shadow:none; border-color: var(--line-soft); }

/* Carries last month's ending balance onto day 1 — the calendar grid
   never renders cells for the previous month's trailing days, so this is
   the only place that figure has anywhere to attach. Deliberately
   smaller/quieter than .cal-balance below: it's context for where the
   month's running total picks up from, not data that belongs to today. */
.cal-carry-balance{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:4px;
  padding-bottom: 3px;
  margin-bottom: 3px;
  border-bottom: 1px dashed var(--line-soft);
}
.cal-carry-balance-label{
  font-family: var(--sans);
  font-size: 7.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--placeholder);
  font-style: italic;
}
.cal-carry-balance-value{
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  color: var(--placeholder);
}
.cal-carry-balance-value.positive{ color: var(--green); opacity:0.75; }
.cal-carry-balance-value.negative{ color: var(--red); opacity:0.75; }

.cal-balance{
  margin-top: 5px;
  padding-top: 4px;
  border-top: 1px solid var(--line-soft);
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:4px;
}
/* A day with no activity carries the same balance as the day before it —
   hiding the repeat keeps the days that actually moved the needle the
   only ones drawing the eye. */
.cal-balance.cal-balance-unchanged{
  display:none;
}
.cal-balance-label{
  font-family: var(--sans);
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hint);
}
.cal-balance-value{
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 700;
}
.cal-balance-value.positive{ color: var(--green); }
.cal-balance-value.negative{ color: var(--red); }

/* Alert icon — hidden by default, shown when balance hits the threshold */
.cal-balance-alert{
  display: none;
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  margin-left: 2px;
  align-self: center;
}
.cal-balance-alert svg{ width: 12px; height: 12px; display: block; }
.cal-balance.warning .cal-balance-alert{ display: block; }

/* ---------- LOWER BAND ---------- */

.lower{
  display:grid;
  grid-template-columns: 1fr 320px;
  gap: 18px;
  align-items:start;
}

.lower-left{ display:flex; flex-direction:column; min-width:0; }

.dollar{ font-family: var(--mono); font-size: 12px; color: var(--placeholder); }

/* Totals row: now holds only Bill Totals, since Income List moved into
   the sidebar below the Bill List. */
.totals-row{
  display:grid;
  grid-template-columns: 1fr;
  gap: 18px;
}

.bill-totals-head{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:8px;
  margin-bottom: 10px;
}
.bill-totals-head .section-label{ margin:0; }

/* "Edit Categories" — same quiet header-button treatment as Collapse/
   Remove All elsewhere in the app. */
.bt-edit-categories{
  border:none;
  background:transparent;
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--placeholder);
  cursor:pointer;
  padding: 3px 7px;
  border-radius: 6px;
  flex-shrink:0;
  transition: color .15s ease, background .15s ease;
}
.bt-edit-categories:hover{ color: var(--ink); background: var(--hover-bg); }

/* Fixed 4-column grid — 4 x 3 for the full 12-card cap (11 user
   categories + the always-present Misc card, see
   MAX_USER_BILL_CATEGORIES in app.js), fewer rows as categories shrink.
   A fixed column count (vs. the previous auto-fit/minmax) means each
   card is reliably wide enough for a label like "Transportation" or
   "Health & Fitness" to fit on one line; see .bt-label below for how
   the text itself is constrained within that width. */
.bt-row{
  display:grid;
  grid-template-columns: repeat(4, 1fr);
  gap:8px;
}

/* Shorter and wider than before: icon and label now sit side-by-side
   on one row instead of icon-above-label, so the card's height comes
   from one line of content instead of two, and the label gets the
   full card width to work with rather than competing with a
   centered icon above it. */
.bt-card{
  background: var(--stamp-bg);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  display:flex;
  flex-direction:column;
  gap:4px;
  min-width:0;
}

.bt-card-top{
  display:flex;
  align-items:center;
  gap:7px;
  min-width:0;
}

.bt-icon{
  width:20px; height:20px;
  border-radius:50%;
  background: var(--stamp-ink);
  color: var(--stamp-bg);
  display:flex; align-items:center; justify-content:center;
  flex-shrink:0;
}
.bt-icon svg{ width:11px; height:11px; }

/* Single-line clamp with an ellipsis fallback rather than wrapping —
   a wrapped second line is what was pushing the card taller and
   widening the layout unpredictably; truncating keeps every card the
   same fixed height regardless of label length. The full label is
   still available as a title-attribute tooltip on hover/long-press. */
.bt-label{
  font-size: 10.5px;
  font-weight:600;
  letter-spacing:0.06em;
  text-transform:uppercase;
  color: var(--hint);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  min-width:0;
}

.bt-value{
  font-family: var(--mono);
  font-size: 16px;
  font-weight:600;
  color: var(--stamp-ink);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}

.bt-hint{
  margin: 8px 2px 0;
  font-size: 10.5px;
  color: var(--placeholder);
  line-height:1.4;
}

/* Income List — lives in the sidebar directly below the Bill List,
   reusing its card markup (.bill-card / .bill-rows). Bill List and
   Income List now split the sidebar's original full scroll height
   evenly between them. */
.income-list{
  display:flex;
  flex-direction:column;
  min-width:0;
  margin-top: 14px;
}

.income-list-head{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:8px;
  margin-bottom: 10px;
}
.income-list-head .section-label{ margin:0; }

.income-rows-scroll{
  max-height: min(320px, 35vh);
  overflow-y: auto;
  overflow-x: hidden;
}
/* Bottom fade, same conditional approach as .bill-rows-scroll — see
   that rule for the full explanation. */
.income-rows-scroll.has-fade{
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
}
.income-rows-scroll::-webkit-scrollbar{ display:none; }
.income-rows-scroll{ scrollbar-width: none; -ms-overflow-style: none; }

.income-rows{ padding: 2px 2px 0; }

/* Income cards reuse .bill-card almost exactly — same icon/name/recurring/
   remove top line, same Date+Amount bottom line — just with the amount
   tinted green (income) instead of left at the neutral ink color (bills
   use red implicitly via .bill-amount's default, income overrides it). */
.income-card .income-amount{ color: var(--green); }
.income-card .bill-field-date .bill-field-label,
.income-card .bill-field-amount .bill-field-label{ color: var(--hint); }

/* ---------- SUMMARY STAMP ---------- */

.summary{
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow:hidden;
  align-self:stretch;
  display:flex;
  flex-direction:column;
  box-shadow: 0 8px 24px -16px rgba(26,26,26,0.25);
}

.sum-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  padding: 13px 18px;
  border-bottom: 1px solid var(--line-soft);
  gap: 10px;
}

.sum-label{
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  white-space:nowrap;
}

.sum-value{
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 700;
  white-space:nowrap;
}
.sum-value.plus{ color: var(--green); }
.sum-value.minus{ color: var(--red); }

.sum-row.stamp{
  background: var(--stamp-bg);
  border-bottom:none;
  margin-top:auto;
  padding: 18px;
  position:relative;
}
.sum-row.stamp .sum-label{
  color: var(--stamp-ink);
  font-family: var(--serif);
  font-style:italic;
  font-size: 14px;
  font-weight:500;
}
.sum-row.stamp .sum-value{
  font-size: 21px;
  letter-spacing: -0.01em;
}
.sum-row.stamp .sum-value.positive{ color: var(--stamp-positive); }
.sum-row.stamp .sum-value.negative{ color: var(--stamp-negative); }

/* ---------- FOOTER ---------- */

.page-footer{
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap: 6px;
}

.footer-left{ display:flex; align-items:center; gap:6px; }
.footer-right{ display:flex; align-items:center; gap:6px; }

/* Plain label, not a button — sits a touch quieter than Restore/Reset
   since there's nothing to click, just a small margin-right to separate
   it from the first real action. */
.footer-version{
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--placeholder-soft);
  padding: 4px 10px 4px 0;
  user-select: none;
}

/* Settings dropdown — gear-icon trigger (same circular-button shape as
   the theme trigger) opening a menu that holds Restore Defaults and
   Reset. Reset keeps its red-on-hover treatment since it's still the
   one truly destructive action in the app; Restore Defaults stays
   neutral. Positioned in the footer's left group, opposite Import CSV. */
.settings-picker{ position:relative; }

/* "Preferences" text link in the footer — replaces the old gear icon */
.pref-trigger{
  border: none;
  background: transparent;
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--placeholder);
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 6px;
  transition: color .15s ease, background .15s ease;
}
.pref-trigger:hover{ color: var(--ink); background: var(--hover-bg); }

/* ---------- PREFERENCES MODAL ---------- */
.pref-overlay{
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.35);
  z-index: 300;
  align-items: center;
  justify-content: center;
}
.pref-overlay.open{ display: flex; }
.pref-overlay.dismissing .pref-card{ opacity:0; transform: scale(0.97); }

.pref-card{
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 20px 48px -12px rgba(0,0,0,0.3);
  width: min(420px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  overflow: hidden; /* pages scroll individually */
  display: flex;
  flex-direction: column;
  transition: opacity .18s ease, transform .18s ease;
}

/* Each "page" inside the card fills the card and scrolls on its own */
.pref-page{
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 22px 24px 24px;
  overflow-y: auto;
  max-height: calc(100vh - 48px);
}
.pref-page[hidden]{ display: none; }

.pref-head{
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.pref-title{
  font-family: var(--sans);
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
}

.pref-close{
  width: 28px; height: 28px;
  border: none;
  background: transparent;
  color: var(--placeholder);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  padding: 0;
  transition: color .15s ease, background .15s ease;
}
.pref-close svg{ width: 14px; height: 14px; }
.pref-close:hover{ color: var(--ink); background: var(--hover-bg); }

.pref-back{
  width: 28px; height: 28px;
  border: none;
  background: transparent;
  color: var(--placeholder);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  padding: 0;
  flex-shrink: 0;
  transition: color .15s ease, background .15s ease;
}
.pref-back svg{ width: 16px; height: 16px; }
.pref-back:hover{ color: var(--ink); background: var(--hover-bg); }

.pref-section{
  border-top: 1px solid var(--line-soft);
  padding-top: 16px;
  margin-bottom: 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.pref-section:last-child{ margin-bottom: 0; }

.pref-section-title{
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hint);
  margin: 0 0 10px 0;
}

/* Alert threshold row */
.pref-row{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 6px 0;
}

.pref-row-info{
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.pref-row-label{
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
}

.pref-row-sub{
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 500;
  color: var(--placeholder);
}

.pref-threshold-wrap{
  display: flex;
  align-items: center;
  gap: 3px;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 4px 8px;
  flex-shrink: 0;
  background: var(--card);
  transition: border-color .15s ease;
}
.pref-threshold-wrap:focus-within{ border-color: var(--ink); }

.pref-threshold-dollar{
  font-family: var(--mono);
  font-size: 12px;
  color: var(--placeholder);
  flex-shrink: 0;
}

.pref-threshold-input{
  border: none;
  outline: none;
  background: transparent;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  width: 72px;
  text-align: right;
}
.pref-threshold-input::placeholder{ color: var(--placeholder-soft); }

/* Restore / Reset action rows */
.pref-action-btn{
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  width: 100%;
  background: none;
  border: none;
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
  text-align: left;
  transition: background .15s ease;
}
.pref-action-btn:hover{ background: var(--hover-bg); }

.pref-action-label{
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
}
.pref-action-sub{
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 500;
  color: var(--placeholder);
}
.pref-action-danger:hover .pref-action-label{ color: var(--red); }
.pref-action-warning:hover .pref-action-label{ color: #b45309; }
[data-theme="dark"] .pref-action-warning:hover .pref-action-label{ color: #f59e0b; }

/* Nav row — like an action button but with a trailing chevron */
.pref-nav-btn{ flex-direction: row; align-items: center; gap: 0; }
.pref-nav-btn .pref-action-label{ flex: 1; }
.pref-nav-btn .pref-action-sub{ flex: 1; font-size: 10.5px; }
.pref-nav-btn > span{ display: flex; flex-direction: column; gap: 1px; flex: 1; }
.pref-nav-chevron{ width: 16px; height: 16px; color: var(--placeholder); flex-shrink: 0; margin-left: 4px; }

/* Flush section — no extra top padding, used for the hotkeys table */
.pref-section-flush{ border-top: none; padding-top: 0; }

/* Keyboard shortcuts table */
.pref-hotkey-table{
  width: 100%;
  border-collapse: collapse;
  margin-top: 2px;
}
.pref-hotkey-table tr + tr td{ border-top: 1px solid var(--line-soft); }
.pref-hotkey-table td{
  padding: 7px 4px;
  vertical-align: middle;
}
.pref-hotkey-keys{
  white-space: nowrap;
  padding-right: 14px !important;
}
.pref-hotkey-desc{
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
}
.pref-hotkey-note{
  font-family: var(--sans);
  font-size: 10.5px;
  color: var(--placeholder);
  margin: 8px 0 0 0;
  font-style: italic;
}

kbd{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink);
  background: var(--hover-bg);
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 1px 5px;
  min-width: 20px;
  line-height: 1.5;
}

/* Quiet, same visual weight as the Preferences link — importing isn't
   destructive on its own (the confirm dialog before it spells out what
   will change), so it stays neutral on hover rather than red. Sits in
   the footer's own right-aligned group. */
.footer-import{
  border:none;
  background:transparent;
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--placeholder);
  cursor:pointer;
  padding: 4px 10px;
  border-radius: 6px;
  transition: color .15s ease, background .15s ease;
}
.footer-import:hover{ color: var(--ink); background: var(--hover-bg); }

/* ---------- WELCOME OVERLAY ---------- */

/* Hidden by default; only ever shown when the pre-paint <head> script
   (see index.html) finds no saved state at all and adds .is-first-visit
   to <html> before the first frame renders — so returning users never
   see so much as a flash of this. */
.welcome-overlay{
  display:none;
}
html.is-first-visit .welcome-overlay{
  display:flex;
}

/* ---------- INVITE GATE ---------- */

/* Always visible unless the visitor has already unlocked (invite-unlocked
   class added synchronously in the inline <head> script). */
.invite-overlay{
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 2000;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--paper);
  animation: welcomeScrimIn .25s ease both;
}
html.invite-unlocked .invite-overlay{
  display: none;
}
.invite-overlay.dismissing{
  animation: welcomeScrimOut .22s ease both;
  pointer-events: none;
}

.invite-card{
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 20px;
  max-width: 380px;
  width: 100%;
  padding: 38px 34px 32px;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,0.35);
  text-align: center;
  animation: welcomeCardIn .3s cubic-bezier(.2,.8,.3,1.1) both;
}
.invite-overlay.dismissing .invite-card{
  animation: welcomeCardOut .2s ease both;
}

.invite-kicker{
  margin: 0 0 2px;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.invite-title{
  margin: 0;
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 38px;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--ink);
}
.invite-subtitle{
  margin: 4px 0 24px;
  font-family: var(--sans);
  font-size: 12.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 500;
}
.invite-prompt{
  margin: 0 0 14px;
  font-family: var(--sans);
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.5;
}
.invite-input-wrap{
  margin-bottom: 8px;
}
.invite-input{
  width: 100%;
  box-sizing: border-box;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-align: center;
  padding: 12px 14px;
  outline: none;
  transition: border-color .15s;
}
.invite-input:focus{
  border-color: var(--ink);
}
.invite-input::placeholder{
  color: var(--placeholder);
  letter-spacing: 0.04em;
  font-weight: 400;
}
.invite-error{
  margin: 0 0 4px;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--red);
  min-height: 18px;
}
.invite-submit{
  margin-top: 14px;
  width: 100%;
  border: none;
  border-radius: 11px;
  background: var(--stamp-bg);
  color: var(--stamp-ink);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.01em;
  padding: 13px 0;
  cursor: pointer;
  transition: opacity .15s ease, transform .1s ease;
}
.invite-submit:hover{ opacity: 0.88; }
.invite-submit:active{ transform: scale(0.98); }

@keyframes shake{
  0%,100%{ transform: translateX(0); }
  20%{ transform: translateX(-8px); }
  40%{ transform: translateX(8px); }
  60%{ transform: translateX(-5px); }
  80%{ transform: translateX(5px); }
}
.invite-card.shake{
  animation: shake .35s ease both;
}

.welcome-overlay{
  position:fixed;
  inset:0;
  z-index: 1000;
  align-items:center;
  justify-content:center;
  padding: 24px;
  background: rgba(10,10,10,0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: welcomeScrimIn .25s ease both;
}
.welcome-overlay.dismissing{
  animation: welcomeScrimOut .22s ease both;
  pointer-events:none;
}

.welcome-card{
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 20px;
  max-width: 440px;
  width:100%;
  max-height: 88vh;
  overflow-y:auto;
  padding: 36px 34px 30px;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,0.45);
  text-align:center;
  animation: welcomeCardIn .3s cubic-bezier(.2,.8,.3,1.1) both;
}
.welcome-overlay.dismissing .welcome-card{
  animation: welcomeCardOut .2s ease both;
}

.welcome-kicker{
  margin: 0 0 2px;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.welcome-title{
  margin: 0;
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 38px;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--ink);
}

.welcome-subtitle{
  margin: 4px 0 22px;
  font-family: var(--sans);
  font-size: 12.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 500;
}

.welcome-body{
  text-align:left;
  font-family: var(--sans);
  color: var(--ink-soft);
}
.welcome-body > p{
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.55;
}

.welcome-points{
  margin: 0 0 4px;
  padding: 0;
  list-style:none;
  display:flex;
  flex-direction:column;
  gap: 11px;
}
.welcome-points li{
  position:relative;
  padding-left: 22px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-soft);
}
.welcome-points li::before{
  content:"";
  position:absolute;
  left:0;
  top: 6px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--stamp-bg);
}

.welcome-continue{
  margin-top: 26px;
  width:100%;
  border:none;
  border-radius: 11px;
  background: var(--stamp-bg);
  color: var(--stamp-ink);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.01em;
  padding: 13px 0;
  cursor:pointer;
  transition: opacity .15s ease, transform .1s ease;
}
.welcome-continue:hover{ opacity:0.88; }
.welcome-continue:active{ transform: scale(0.98); }

@keyframes welcomeScrimIn{
  from{ opacity:0; }
  to{ opacity:1; }
}
@keyframes welcomeScrimOut{
  from{ opacity:1; }
  to{ opacity:0; }
}
@keyframes welcomeCardIn{
  from{ opacity:0; transform: translateY(10px) scale(0.97); }
  to{ opacity:1; transform: translateY(0) scale(1); }
}
@keyframes welcomeCardOut{
  from{ opacity:1; transform: scale(1); }
  to{ opacity:0; transform: scale(0.97); }
}

@media (max-width: 480px){
  .welcome-card{ padding: 30px 24px 26px; }
  .welcome-title{ font-size: 32px; }
}

/* ---------- CATEGORY MANAGER ---------- */

.cat-manager-overlay{
  display:none;
  position:fixed;
  inset:0;
  z-index: 1000;
  align-items:center;
  justify-content:center;
  padding: 24px;
  background: rgba(10,10,10,0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: welcomeScrimIn .2s ease both;
}
.cat-manager-overlay.open{ display:flex; }
.cat-manager-overlay.dismissing{
  animation: welcomeScrimOut .18s ease both;
  pointer-events:none;
}

.cat-manager-card{
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 18px;
  max-width: 480px;
  width:100%;
  max-height: 86vh;
  overflow-y:auto;
  padding: 26px 26px 22px;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,0.45);
  animation: welcomeCardIn .25s cubic-bezier(.2,.8,.3,1.1) both;
}
.cat-manager-overlay.dismissing .cat-manager-card{
  animation: welcomeCardOut .18s ease both;
}

.cat-manager-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  margin-bottom: 6px;
}

.cat-manager-title{
  margin:0;
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 21px;
  color: var(--ink);
}

.cat-manager-close{
  border:none;
  background:transparent;
  color: var(--ink-soft);
  width:28px; height:28px;
  border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer;
  flex-shrink:0;
  transition: color .15s ease, background .15s ease;
}
.cat-manager-close svg{ width:15px; height:15px; }
.cat-manager-close:hover{ color: var(--ink); background: var(--hover-bg); }

.cat-manager-intro{
  margin: 0 0 18px;
  font-size: 12.5px;
  line-height:1.5;
  color: var(--ink-soft);
}

.cat-manager-list{
  display:flex;
  flex-direction:column;
  gap:8px;
}

/* Each row: icon trigger, name (input if editable / plain text if
   protected), category total for context, and a delete button (only
   present on editable rows — protected rows simply don't get one). */
.cat-row{
  display:flex;
  align-items:center;
  gap:10px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  background: var(--card);
  border: 1px solid var(--line-soft);
  cursor: default;
}
.cat-row-handle{
  display:flex;
  align-items:center;
  justify-content:center;
  width:18px;
  height:24px;
  flex-shrink:0;
  color: var(--placeholder);
  cursor: grab;
  opacity: 0.5;
  transition: opacity .15s;
}
.cat-row:hover .cat-row-handle{ opacity: 1; }
.cat-row-handle:active{ cursor: grabbing; }
.cat-row-handle svg{ width:12px; height:12px; pointer-events:none; }
.cat-row-dragging{
  opacity: 0.45;
  border-style: dashed;
}
.cat-row-drag-over{
  border-color: var(--accent, var(--ink-soft));
  background: var(--hover-bg);
}

.cat-row-icon{
  width:30px; height:30px;
  border-radius:50%;
  background: var(--stamp-bg);
  color: var(--stamp-ink);
  display:flex; align-items:center; justify-content:center;
  flex-shrink:0;
  border:none;
  cursor:pointer;
  padding:0;
}
.cat-row-icon svg{ width:15px; height:15px; }
.cat-row-icon:disabled{ cursor:default; opacity:0.7; }

.cat-row-name{
  flex:1;
  min-width:0;
  font-family: var(--sans);
  font-size: 13px;
  font-weight:600;
  color: var(--ink);
  border:none;
  background:transparent;
  padding: 4px 2px;
}
.cat-row-name:disabled{ color: var(--ink-soft); }
.cat-row-name:not(:disabled):focus{
  outline:none;
  border-bottom: 1px solid var(--line);
}

.cat-row-protected-tag{
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight:700;
  letter-spacing:0.06em;
  text-transform:uppercase;
  color: var(--placeholder);
  flex-shrink:0;
  white-space:nowrap;
}

.cat-row-remove{
  border:none;
  background:transparent;
  color: var(--placeholder);
  width:26px; height:26px;
  border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer;
  flex-shrink:0;
  transition: color .15s ease, background .15s ease;
}
.cat-row-remove svg{ width:13px; height:13px; }
.cat-row-remove:hover{ color: var(--red); background: var(--hover-bg); }

.cat-manager-footer{
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
}

.cat-add-row{
  border:1px dashed var(--line);
  border-radius: var(--radius-md);
  background:transparent;
  color: var(--placeholder);
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align:center;
  cursor:pointer;
  padding: 11px 0;
  width:100%;
}
.cat-add-row:hover{ color: var(--ink); background: var(--hover-bg); border-color: var(--hover-border); }
.cat-add-row:disabled{
  cursor:default;
  opacity:0.55;
}
.cat-add-row:disabled:hover{ color: var(--placeholder); background:transparent; border-color: var(--line); }

.cat-remove-all-btn{
  border: none;
  background: transparent;
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--placeholder);
  cursor: pointer;
  padding: 6px 10px;
  border-radius: var(--radius-md);
  transition: color .15s ease, background .15s ease;
  align-self: flex-start;
  margin-bottom: 6px;
}
.cat-remove-all-btn:hover{ color: var(--red); background: var(--hover-bg); }

.cat-manager-limit-note{
  margin: 8px 2px 0;
  font-size: 10.5px;
  color: var(--placeholder);
  text-align:center;
}

/* Icon picker popover reused for category rows — same body-reparented
   pattern and grid layout as .bill-icon-menu, just scoped under its own
   class so the two never collide structurally. */
.cat-icon-menu{
  position:fixed;
  z-index: 1100;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 8px;
  box-shadow: 0 20px 45px -15px rgba(0,0,0,0.4);
  display:grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 4px;
  width: 220px;
}
.cat-icon-option{
  width:30px; height:30px;
  border-radius:8px;
  border:none;
  background:transparent;
  color: var(--ink-soft);
  display:flex; align-items:center; justify-content:center;
  cursor:pointer;
}
.cat-icon-option svg{ width:15px; height:15px; }
.cat-icon-option:hover{ background: var(--hover-bg); color: var(--ink); }
.cat-icon-option.active{ background: var(--stamp-bg); color: var(--stamp-ink); }
.cat-icon-option:disabled{
  opacity:0.3;
  cursor:not-allowed;
}
.cat-icon-option:disabled:hover{ background:transparent; color: var(--ink-soft); }

@media (max-width: 480px){
  .cat-manager-card{ padding: 22px 18px 18px; }
  .cat-icon-menu{ grid-template-columns: repeat(5, 1fr); width:190px; }
}

/* ---------- RESPONSIVE ---------- */

/* Tablet / narrow desktop: stack the two-column board, let bill+income
   cards flow as a normal two-up grid instead of an internally-scrolled
   sidebar (there's no calendar-column height to match anymore), and
   stack Bill Totals above the Summary stamp. */
@media (max-width: 980px){
  body{ padding: 22px 16px 48px; }
  .board{ grid-template-columns: 1fr; }
  .board-right{ order:1; }
  .bill-list{ order:2; }
  .bill-rows-scroll{ max-height:none; overflow:visible; -webkit-mask-image:none; mask-image:none; }
  .bill-rows{ display:grid; grid-template-columns: repeat(2,1fr); gap:8px; padding:0; }
  .income-rows-scroll{ max-height:none; overflow:visible; -webkit-mask-image:none; mask-image:none; }
  .income-rows{ display:grid; grid-template-columns: repeat(2,1fr); gap:8px; padding:0; }
  .lower{ grid-template-columns: 1fr; }
  .totals-row{ grid-template-columns: 1fr; }
  .summary{ margin-top: 18px; }
  .cal-grid{ grid-auto-rows: minmax(64px, auto); }
}

/* Phones (portrait & landscape small). This is the breakpoint that
   matters most: the header collapses to a stacked block, every
   dropdown menu is widened/repositioned so it can't run off-screen,
   touch targets grow to a comfortable size, bill/income cards drop to
   one column, and the calendar switches from a 7-col grid to a
   vertical day-list so each day actually has room to show entries. */
@media (max-width: 640px){
  body{ padding: 16px 10px 40px; }
  .paper{ padding: 20px 14px 24px; border-radius: 16px; }
  .paper::before{ left:24px; right:24px; }

  /* ----- Header ----- */
  .head{ flex-direction:column; align-items:stretch; gap: 16px; margin-bottom: 20px; }
  .head-left{ flex: 0 0 auto; }
  .title{ font-size: 28px; }
  .head-mid{ flex: 0 0 auto; justify-content:stretch; }
  .opening-balance{ width:100%; }
  .ob-label{ flex:0 0 auto; }
  .ob-input-wrap{ flex:1 1 auto; padding: 0 16px; }
  .ob-input{ width: 100%; font-size: 17px; padding: 12px 4px; }

  .head-right{ align-items:stretch; width:100%; gap: 10px; }
  .month-nav{ width:100%; justify-content:space-between; }
  .month-nav-arrow{ width: 34px; height: 34px; } /* comfortable tap target */
  .month-nav-arrow svg{ width:16px; height:16px; }
  .month-nav-label{ min-width: 0; font-size: 15px; }

  .head-actions{
    width:100%;
    justify-content:space-between;
    flex-wrap: wrap;
    gap: 8px;
  }
  .icon-circle-btn{ width: 34px; height: 34px; }
  .theme-trigger{ width: 34px; height: 34px; }
  .export-trigger{ padding: 9px 14px; }
  .save-indicator{ flex: 0 0 auto; margin-left:auto; }

  /* Dropdown menus anchored to header buttons can overflow the right
     edge of a narrow viewport when right:0 is relative to a button
     sitting near that edge — pull them in and let them size to content
     up to the available width instead of a fixed min-width. */
  .theme-menu,
  .export-menu{
    right: 0;
    left: auto;
    min-width: 0;
    width: max-content;
    max-width: calc(100vw - 48px);
  }

  /* ----- Bill list / Income list ----- */
  .bill-list-head, .income-list-head{ flex-wrap: wrap; row-gap:6px; }
  .bill-rows{ grid-template-columns: 1fr; }
  .income-rows{ grid-template-columns: 1fr; }
  .bill-card{ padding: 11px 11px 10px; }
  .bill-card-bottom{ flex-wrap: wrap; row-gap: 6px; padding-left: 30px; }
  .bill-card-extra{ padding-left: 30px; }
  .bill-field-amount{ flex: 1 1 100px; }
  .list-collapse-toggle, .list-remove-all{ padding: 5px 8px; } /* easier to tap */

  /* ----- Bill Totals ----- */
  .bt-row{ grid-template-columns: repeat(2, 1fr); }
  .bill-totals-head{ flex-wrap: wrap; row-gap:6px; }

  /* ----- Calendar -----
     On mobile the calendar becomes a 6-column grid — Mon, Tue, Wed, Thu,
     Fri, and a Sat+Sun card. Each cell shows only the day number and the
     running balance (when it changed). Tapping any cell opens the full
     day detail modal. The Sat+Sun card stacks both days vertically inside
     one equal-size cell divided by a hairline. */
  .cal-head{ display:none; }
  .cal-grid{
    grid-template-columns: repeat(6, 1fr);
    grid-auto-rows: 72px;
    gap: 4px;
  }
  .cal-cell{
    flex-direction: column;
    align-items: stretch;
    padding: 6px 5px 5px;
    min-height: 0;
    height: 100%;
    overflow: hidden;
    cursor: pointer;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
  }
  .cal-cell:active{ opacity: 0.7; }
  .cal-cell.blank{ display:none; }
  /* hide all content except daynum and balance on mobile cells */
  .cal-cell .cal-items,
  .cal-cell .cal-add-row,
  .cal-cell .cal-carry-balance{ display: none; }
  /* balance row sits at the bottom, never overflows */
  .cal-cell .cal-balance{
    margin-top: auto;
    padding-top: 2px;
    border-top: none;
    justify-content: flex-start;
    overflow: hidden;
    min-width: 0;
  }
  .cal-cell .cal-balance.cal-balance-unchanged{ display: none; }
  .cal-cell .cal-balance-label{ display: none; }
  .cal-cell .cal-balance-value{
    font-size: 9px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }
  .cal-cell .cal-balance-alert{ flex-shrink: 0; }
  .cal-cell .cal-balance-alert svg{ width: 8px; height: 8px; }
  .cal-daynum{
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.01em;
    margin-bottom: 0;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* activity dot — only rendered by JS when the day has entries */
  .cal-cell-dot{
    width: 4px; height: 4px;
    border-radius: 50%;
    background: var(--ink-soft);
    margin: 3px 0 0;
    flex-shrink: 0;
  }
  /* Sat+Sun combined card — same fixed height, days fill each half */
  .cal-cell.weekend-combined{
    padding: 0;
    flex-direction: column;
    min-height: 0;
    height: 100%;
    overflow: hidden;
    cursor: default;
  }
  .cal-weekend-half{
    flex: 1 1 0;
    min-height: 0;
    min-width: 0;
    padding: 5px 5px 4px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    cursor: pointer;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
  }
  .cal-weekend-half:active{ opacity: 0.7; }
  .cal-weekend-half + .cal-weekend-half{
    border-top: 1px solid var(--line-soft);
  }
  /* hide items/add inside weekend halves too */
  .cal-weekend-half .cal-items,
  .cal-weekend-half .cal-add-row,
  .cal-weekend-half .cal-carry-balance{ display: none; }
  .cal-weekend-half .cal-balance{
    margin-top: auto;
    padding-top: 0;
    border-top: none;
    justify-content: flex-start;
    overflow: hidden;
    min-width: 0;
  }
  .cal-weekend-half .cal-balance.cal-balance-unchanged{ display: none; }
  .cal-weekend-half .cal-balance-label{ display: none; }
  .cal-weekend-half .cal-balance-value{
    font-size: 8px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }
  .cal-weekend-half .cal-balance-alert{ flex-shrink: 0; }
  .cal-weekend-half .cal-daynum{
    font-size: 9px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .cal-weekend-half .cal-balance-alert svg{ width: 7px; height: 7px; }

  /* ----- Totals / Summary stamp ----- */
  .sum-row{ padding: 12px 16px; }
  .sum-row.stamp{ padding: 16px; }

  /* ----- Footer ----- */
  .page-footer{ flex-wrap: wrap; gap: 10px; }
  .footer-left, .footer-right{ flex-wrap: wrap; }
}

/* Small phones */
@media (max-width: 480px){
  .title{ font-size: 24px; }
  .subtitle{ font-size: 11px; }
  .ob-label{ font-size: 12px; padding: 0 12px; }

  .bt-row{ grid-template-columns: repeat(2, 1fr); gap:6px; }
  .bt-card{ padding: 8px 9px; }

  .cal-grid{ grid-auto-rows: 60px; }
  .cal-cell{ padding: 4px 3px; }
  .cal-cell.weekend-combined{ padding: 0; }
  .cal-weekend-half{ padding: 4px 3px 3px; }
  .cal-daynum{ font-size: 8.5px; }
  .cal-cell .cal-balance-value{ font-size: 8px; }
  .cal-weekend-half .cal-balance-value{ font-size: 7.5px; }

  .sum-value{ font-size: 14px; }
  .sum-row.stamp .sum-value{ font-size: 19px; }

  .export-trigger{ padding: 8px 12px; font-size:12px; }
  .footer-version{ padding: 4px 0; width:100%; }
}

/* Very small phones — collapse the last few multi-column areas to a
   single column so nothing has to truncate or wrap mid-word. */
@media (max-width: 380px){
  .bt-row{ grid-template-columns: 1fr 1fr; }
  .ob-label{ display:none; } /* "$" + input still makes the field's purpose clear at this width */
  .month-nav-label{ font-size: 14px; }
}

/* ============================================================
   PRINT / EXPORT PDF
   Triggered by the Export PDF button (window.print()). Goals:
   - Landscape, fit-to-page, no browser chrome artifacts
   - Inputs render as plain text, not form fields
   - Empty placeholders disappear instead of printing as "0.00"
   - Colors (red/green amounts, black stamp) are preserved
============================================================ */
@page{
  size: landscape;
  margin: 10mm 12mm;
}

@media print{
  *{
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* Always print in the Classic light palette, regardless of which theme
     is active on screen — saves ink and avoids a dark page printing as a
     solid black rectangle. */
  html{
    --paper: #FFFFFF !important; --paper-edge: #EDEDED !important; --card: #FFFFFF !important;
    --ink: #111111 !important; --ink-soft: #5C5C5C !important;
    --line: #D6D6D6 !important; --line-soft: #E6E6E6 !important;
    --stamp-bg: #111111 !important; --stamp-ink: #FFFFFF !important;
    --green: #1E7A4C !important; --red: #B23B3B !important;
    --blue: #3568C2 !important;
    --stamp-positive: #4ADE94 !important; --stamp-negative: #F08A8A !important;
    --placeholder: #B0B0B0 !important; --placeholder-soft: #D2D2D2 !important; --hint: #C2C2C2 !important;
    --hover-bg: #FAFAFA !important; --hover-border: #A8A8A8 !important;
    --weekend-bg: #FAFAFA !important; --synced-bg: #F4F4F4 !important;
  }

  html, body{
    background: white;
    padding: 0;
    margin: 0;
  }

  .paper{
    box-shadow:none;
    border:none;
    border-radius:0;
    padding: 0;
    max-width:none;
    width:100%;
  }
  .paper::before{ display:none; }

  /* Hide interactive-only chrome */
  .icon-btn,
  .save-indicator,
  .cal-add-row,
  .cal-item-remove,
  .cal-item-row.is-empty,
  .bill-remove,
  .bill-recur,
  .bill-add-row,
  .list-collapse-toggle,
  .list-remove-all,
  .icon-circle-btn,
  .theme-picker,
  .export-picker,
  .month-nav-arrow,
  .month-input,
  .bill-freq-menu,
  .bill-icon-menu,
  .bt-edit-categories,
  .cat-manager-overlay,
  .trend-card,
  .welcome-overlay,
  .page-footer{
    display:none !important;
  }

  /* The frequency popover is a control, not something that prints usefully
     as an interactive menu — but which frequency is selected IS real
     data, so a recurring bill/income shows it as plain text in its place
     instead of the data just disappearing. */
  .bill-recur-wrap{
    display:inline-flex;
    align-items:baseline;
    gap: 4px;
  }
  .bill-recur-wrap.has-recur-label::after{
    content: attr(data-freq-label);
    font-family: var(--sans);
    font-size: 10px;
    font-weight: 600;
    color: var(--ink);
  }

  /* The bill and income lists should always print in full, regardless of
     their on-screen collapsed/expanded state or scroll position — a
     collapsed or clipped export would be useless on paper. */
  .board{ grid-template-columns: 236px 1fr !important; }
  .bill-rows-scroll.collapsed,
  .income-rows-scroll.collapsed{
    display:block !important;
  }
  .list-collapsed-sum{
    display:none !important;
  }
  .bill-rows-scroll{
    overflow: visible !important;
    max-height: none !important;
    -webkit-mask-image: none !important;
    mask-image: none !important;
  }
  .bill-rows{ gap: 5px !important; }

  /* Inputs read as plain typeset text, not editable fields */
  input{
    border:none !important;
    box-shadow:none !important;
    background:transparent !important;
    -webkit-appearance:none;
    appearance:none;
  }
  .bill-date{ border:none !important; }
  .bill-date.has-value{ font-weight:600; }

  /* Empty values shouldn't print as visible "0.00" placeholders — except the
     bill name field, where the placeholder IS the bill's default name (e.g.
     "Water") and must stay legible in the printed list. */
  input::placeholder{ color: transparent !important; }
  .bill-name-input::placeholder{ color: var(--ink) !important; }

  /* Card surfaces flatten to hairlines so the page reads like a printed ledger */
  .bill-card, .cal-cell{
    box-shadow:none;
  }
  .cal-cell.weekend{ background: #FAFAFA; }
  .cal-cell.blank{ border-color: transparent; }

  /* Avoid splitting a single bill card or calendar cell across a page break,
     but let the board itself flow naturally across pages if needed. */
  .bill-card{ break-inside: avoid; }
  .cal-cell{ break-inside: avoid; }

  /* The Income List should always print in full too, regardless of its
     on-screen scroll position — same reasoning as the Bill List. */
  .income-rows-scroll{
    overflow: visible !important;
    max-height: none !important;
    -webkit-mask-image: none !important;
    mask-image: none !important;
  }

  /* Summary stamp keeps its black background + colored ink in print */
  .sum-row.stamp{
    background: var(--stamp-bg) !important;
    -webkit-print-color-adjust: exact;
  }
  .bt-card{ background: var(--stamp-bg) !important; }

  /* Tighten vertical rhythm so a typical month fits one page */
  .head{ margin-bottom: 12px; }
  .board{ margin-bottom: 10px; }
  .board-right{ gap: 10px; }
  .lower{ gap: 10px; }
  .bill-card{ padding: 6px 8px; gap: 5px; }
  .bill-card-bottom{ padding-left: 0; }
  .bill-card-extra{ padding-left: 0; }
  .bill-list-head{ margin-bottom: 4px; }
  .section-label{ margin-bottom: 6px; }
  .cal-cell{ padding: 5px 7px 5px; }
  .cal-grid{ gap: 5px; grid-auto-rows: minmax(78px, auto) !important; }
  .bt-card{ padding: 8px 12px; }
  .bt-hint{ display:none; }
  .sum-row{ padding: 8px 16px; }
  .sum-row.stamp{ padding: 10px 16px; }
  .totals-row{ margin-top: 0; }
  .lower-left{ gap: 8px; }
  .cal-top-row{ margin-bottom: 3px; }
  body{ font-size: 95%; }
}

/* ============================================================
   ACCOUNT SWITCHER BAR
   ============================================================ */
.account-bar {
  padding: 0 0 14px 0;
  display: flex;
  align-items: center;
}
.account-switcher {
  display: flex;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
}
.acct-tab {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px 5px 8px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  background: var(--card);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s, box-shadow 0.12s;
  white-space: nowrap;
  max-width: 150px;
}
.acct-tab:hover {
  background: var(--hover-bg);
  border-color: var(--hover-border);
}
.acct-tab.active {
  /* border-color, background, and box-shadow set via inline styles
     in renderAccountSwitcher() using the account's own color */
  border-width: 1.5px;
}
.acct-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.acct-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 110px;
}
.acct-manage-btn {
  width: 28px;
  height: 28px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--placeholder);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
  transition: color .15s ease, background .15s ease, border-color .15s ease;
}
.acct-manage-btn:hover {
  color: var(--ink);
  background: var(--hover-bg);
  border-color: var(--hover-border);
}
.acct-manage-btn svg { width: 13px; height: 13px; }

/* ============================================================
   ACCOUNT MANAGER MODAL
   ============================================================ */
.acct-manager-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(10,10,10,0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: welcomeScrimIn .2s ease both;
}
.acct-manager-overlay.open {
  display: flex;
}
.acct-manager-overlay.dismissing {
  animation: welcomeScrimOut .18s ease both;
  pointer-events: none;
}
.acct-manager-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 18px;
  max-width: 480px;
  width: 100%;
  max-height: 86vh;
  overflow-y: auto;
  padding: 26px 26px 22px;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,0.45);
  animation: welcomeCardIn .25s cubic-bezier(.2,.8,.3,1.1) both;
}
.acct-manager-overlay.dismissing .acct-manager-card {
  animation: welcomeCardOut .18s ease both;
}
.acct-manager-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}
.acct-manager-title {
  margin: 0;
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 21px;
  color: var(--ink);
}
.acct-manager-close {
  border: none;
  background: transparent;
  color: var(--ink-soft);
  width: 28px; height: 28px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: color .15s ease, background .15s ease;
}
.acct-manager-close svg { width: 15px; height: 15px; }
.acct-manager-close:hover { color: var(--ink); background: var(--hover-bg); }
.acct-manager-intro {
  margin: 0 0 18px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-soft);
}
.acct-manager-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.acct-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  background: var(--card);
  border: 1px solid var(--line-soft);
}
.acct-row-color {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  flex-shrink: 0;
  box-shadow: 0 0 0 1.5px rgba(0,0,0,0.12);
  transition: transform 0.1s;
}
.acct-row-color:hover { transform: scale(1.15); }
.acct-row-name {
  flex: 1;
  min-width: 0;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  border: none;
  background: transparent;
  padding: 4px 2px;
}
.acct-row-name:focus {
  outline: none;
  border-bottom: 1px solid var(--line);
}
.acct-row-remove {
  border: none;
  background: transparent;
  color: var(--placeholder);
  width: 26px; height: 26px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: color .15s ease, background .15s ease;
}
.acct-row-remove svg { width: 13px; height: 13px; }
.acct-row-remove:hover { color: var(--red); background: var(--hover-bg); }
.acct-add-row {
  margin-top: 8px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--placeholder);
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align: center;
  cursor: pointer;
  padding: 11px 0;
  width: 100%;
  transition: color .15s, background .15s, border-color .15s;
}
.acct-add-row:hover:not(:disabled) { color: var(--ink); background: var(--hover-bg); border-color: var(--hover-border); }
.acct-add-row:disabled { cursor: default; opacity: 0.55; }
.acct-limit-note {
  margin: 8px 2px 0;
  font-size: 10.5px;
  color: var(--placeholder);
  text-align: center;
}

/* ============================================================
   DAY DETAIL MODAL — mobile only
   Opened when the user taps any calendar cell on a narrow
   viewport. The overlay fades in; the card slides up from the
   bottom sheet style so it feels native on touch devices.
============================================================ */
.day-modal-overlay{
  position: fixed;
  inset: 0;
  z-index: 500;
  background: rgba(0,0,0,0.45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  animation: dayModalScrimIn .2s ease both;
}
.day-modal-overlay[hidden]{ display: none; }
.day-modal-overlay.dismissing{
  animation: dayModalScrimOut .18s ease both;
}
.day-modal-overlay.dismissing .day-modal-card{
  animation: dayModalCardOut .18s ease both;
}

.day-modal-card{
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -8px 40px -8px rgba(0,0,0,0.28);
  width: 100%;
  max-width: 560px;
  max-height: 92vh;
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: dayModalCardIn .25s cubic-bezier(.2,.85,.3,1.05) both;
}

.day-modal-head{
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0;
}

.day-modal-title{
  margin: 0;
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 18px;
  color: var(--ink);
}

.day-modal-close{
  width: 30px; height: 30px;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  padding: 0;
  flex-shrink: 0;
  transition: color .15s, background .15s;
}
.day-modal-close svg{ width: 15px; height: 15px; }
.day-modal-close:hover{ color: var(--ink); background: var(--hover-bg); }

/* The body hosts a normal .cal-cell's content (daynum hidden, items,
   add button, balance) but with generous desktop-style spacing. */
.day-modal-body{
  overflow-y: auto;
  flex: 1 1 auto;
  padding: 16px 20px 24px;
  /* re-establish the same flex column a cal-cell uses so buildDayContent()
     output renders correctly without any JS changes */
  display: flex;
  flex-direction: column;
  gap: 0;
}
/* hide the daynum inside the modal — the title already carries it */
.day-modal-body .cal-daynum{ display: none; }
/* restore normal desktop sizes for content inside the modal */
.day-modal-body .cal-items{ flex: 1 1 auto; min-width: 0; gap: 0; }
/* Each item row gets generous vertical padding for easy tapping */
.day-modal-body .cal-item-row{
  min-height: 48px;
  padding: 8px 0;
  gap: 10px;
  border-bottom: 1px solid var(--line-soft);
}
.day-modal-body .cal-item-row:last-child{ border-bottom: none; }
/* Synced rows (bill/income auto-lines) get the same height treatment */
.day-modal-body .cal-item-row.synced{
  min-height: 48px;
  padding: 8px 6px;
  margin: 0 -6px;
  border-radius: 6px;
}
.day-modal-body .cal-amount{
  font-size: 16px;
  padding: 4px 0;
  min-height: 40px;
  display: flex;
  align-items: center;
}
.day-modal-body .cal-item-note{
  width: 42%;
  font-size: 14px;
  padding: 4px 0;
  min-height: 40px;
  display: flex;
  align-items: center;
  text-align: right;
}
/* Remove (×) button — large hit area */
.day-modal-body .cal-item-remove{
  font-size: 20px;
  width: 36px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin-left: 2px;
}
/* "+ add" button — full-width pill, easy to tap */
.day-modal-body .cal-add-row{
  width: 100%;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  padding: 14px 0;
  margin-top: 8px;
  border-radius: var(--radius-md);
  border: 1px dashed var(--line);
  color: var(--placeholder);
  transition: color .15s, background .15s, border-color .15s;
}
.day-modal-body .cal-add-row:hover,
.day-modal-body .cal-add-row:active{
  color: var(--ink);
  background: var(--hover-bg);
  border-color: var(--hover-border);
}
.day-modal-body .cal-balance{
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
}
.day-modal-body .cal-balance-label{ font-size: 11px; }
.day-modal-body .cal-balance-value{ font-size: 18px; }
.day-modal-body .cal-balance-alert svg{ width: 14px; height: 14px; }
.day-modal-body .cal-carry-balance{
  display: flex;
  margin-bottom: 10px;
  padding-bottom: 10px;
}
.day-modal-body .cal-carry-balance-label{ font-size: 10px; }
.day-modal-body .cal-carry-balance-value{ font-size: 12px; }

@keyframes dayModalScrimIn{
  from{ opacity:0; }
  to{ opacity:1; }
}
@keyframes dayModalScrimOut{
  from{ opacity:1; }
  to{ opacity:0; }
}
@keyframes dayModalCardIn{
  from{ transform: translateY(100%); opacity:0; }
  to{ transform: translateY(0); opacity:1; }
}
@keyframes dayModalCardOut{
  from{ transform: translateY(0); opacity:1; }
  to{ transform: translateY(100%); opacity:0; }
}
