:root {
  /* ---- Design tokens: spacing / type / radius / elevation ----
     Theme-independent (don't move when the color theme changes), and
     layered UNDER the theme color variables below them — themes.js's
     deriveThemeVars()/theme.js's applyTheme() only ever touch the color
     custom properties further down, never these. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;
  --space-10: 56px;

  --text-xs: 11.5px;
  --text-sm: 13px;
  --text-base: 15px;
  --text-md: 16px;
  --text-lg: 19px;
  --text-xl: 23px;
  --text-2xl: 29px;

  --radius-sm: 7px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 22px;
  --radius-pill: 999px;

  /* Static elevation scale — works in both light and dark because panel
     surfaces are always derived to be lighter than the page background
     (see themes.js's lighten()-based derivation), so a dark, soft shadow
     reads correctly as "lifted" either way. */
  --shadow-xs: 0 1px 2px rgba(15, 15, 20, 0.05);
  --shadow-sm: 0 1px 2px rgba(15, 15, 20, 0.04), 0 4px 10px rgba(15, 15, 20, 0.06);
  --shadow-md: 0 2px 4px rgba(15, 15, 20, 0.05), 0 10px 24px rgba(15, 15, 20, 0.09);
  --shadow-lg: 0 8px 16px rgba(15, 15, 20, 0.08), 0 24px 56px rgba(15, 15, 20, 0.16);

  --sidebar-width: 252px;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);

  /* ---- Theme colors (contract preserved exactly — see theme.js) ---- */
  --bg: #eaebec;
  --panel: #f8f8f9;
  --panel-2: #ffffff;
  --text: #16171a;
  --muted: #6b6e73;
  --border: #d8d9dc;
  --accent: #e8622c;
  --accent-ink: #ffffff;
  --done: #4f8a63;
  --done-bg: #e4efe6;
  --danger: #c6483a;
  --danger-bg: #f6e2df;
  --warn: #b4790f;
  --warn-bg: #f7ecd6;
  --font-heading: "Archivo", system-ui, sans-serif;
  --font-body: "Work Sans", system-ui, sans-serif;
  color-scheme: light;
}

html[data-font="inter"] { --font-heading: "Inter", system-ui, sans-serif; --font-body: "Inter", system-ui, sans-serif; }
html[data-font="poppins"] { --font-heading: "Poppins", system-ui, sans-serif; --font-body: "Poppins", system-ui, sans-serif; }
html[data-font="lora"] { --font-heading: "Lora", Georgia, serif; --font-body: "Lora", Georgia, serif; }
html[data-font="jetbrains-mono"] { --font-heading: "JetBrains Mono", ui-monospace, monospace; --font-body: "JetBrains Mono", ui-monospace, monospace; }
html[data-font="space-grotesk"] { --font-heading: "Space Grotesk", system-ui, sans-serif; --font-body: "Space Grotesk", system-ui, sans-serif; }
html[data-font="nunito"] { --font-heading: "Nunito", system-ui, sans-serif; --font-body: "Nunito", system-ui, sans-serif; }
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1b1c1f;
    --panel: #222327;
    --panel-2: #28292d;
    --text: #ecedef;
    --muted: #9a9da3;
    --border: #35363b;
    --accent: #ff7a3d;
    --accent-ink: #1b1c1f;
    --done: #7fbe8f;
    --done-bg: #253226;
    --danger: #e06655;
    --danger-bg: #3a2523;
    --warn: #e0b23d;
    --warn-bg: #3a331e;
    color-scheme: dark;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
}

/* ---- App shell: sidebar + main, side by side on desktop ---- */
.app-shell { display: flex; align-items: stretch; min-height: 100vh; }

.sidebar {
  flex: 0 0 var(--sidebar-width);
  width: var(--sidebar-width);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-6) var(--space-4) var(--space-4);
  background: var(--panel);
  border-right: 1px solid var(--border);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.sidebar-brand { display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--space-2); }
.sidebar-brand-mark {
  flex-shrink: 0; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; color: var(--accent-ink); background: var(--accent); border-radius: var(--radius-sm);
}
.sidebar-brand .eyebrow { margin: 0; }

.sidebar-footer { margin-top: auto; padding-top: var(--space-3); border-top: 1px solid var(--border); }
.sidebar-settings-btn { width: 100%; justify-content: center; }
.sidebar-link-btn {
  display: flex; align-items: center; gap: 6px; width: 100%; font: inherit; font-size: var(--text-sm); font-weight: 500;
  color: var(--muted); background: transparent; border: none; border-radius: var(--radius-md); padding: 8px 10px;
  margin-bottom: var(--space-2); cursor: pointer; text-align: left;
}
.sidebar-link-btn:hover { color: var(--text); background: var(--panel-2); }
.sidebar-search-btn {
  display: flex; align-items: center; gap: 8px; width: 100%; font: inherit; font-size: var(--text-sm); color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 9px 12px; cursor: pointer; text-align: left;
}
.sidebar-search-btn:hover { border-color: var(--accent); color: var(--text); }
.sidebar-search-btn kbd {
  margin-left: auto; white-space: nowrap; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px; color: var(--muted);
  border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; background: var(--panel);
}
.trash-count:empty { display: none; }
.trash-count {
  margin-left: auto; font-size: 10px; font-weight: 700; color: var(--muted); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 1px 7px;
}

/* Page colors + the small page menu (color for any page; share / linked
   lists for a calendar, whose full-screen view hides the page header). */
.page-color-btn {
  flex-shrink: 0; width: 34px; height: 34px; display: grid; place-content: center; padding: 0;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-md); cursor: pointer;
}
.page-color-btn:hover { border-color: var(--accent); }
.page-color-dot { width: 16px; height: 16px; border-radius: 50%; background: var(--accent); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12); }
.page-color-btn.is-default .page-color-dot { background: conic-gradient(#e8622c, #e0b23d, #2bb6a3, #3d8bff, #a855f7, #e05f8a, #e8622c); }
.page-menu {
  position: fixed; z-index: 30; min-width: 232px; max-width: calc(100vw - 16px); padding: 8px;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
}
.page-menu-item {
  display: block; width: 100%; text-align: left; font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--text);
  background: transparent; border: none; border-radius: var(--radius-sm); padding: 10px 10px; cursor: pointer;
}
.page-menu-item:hover, .page-menu-item:focus-visible { background: var(--panel); }
.page-menu-sep { height: 1px; background: var(--border); margin: 6px 2px; }
.page-menu-label { font-size: var(--text-xs); font-weight: 600; color: var(--muted); padding: 6px 6px 8px; }
.page-menu-swatches { display: grid; grid-template-columns: repeat(6, 32px); gap: 6px; padding: 0 4px 4px; }
.page-swatch {
  width: 32px; height: 32px; border-radius: 50%; border: 2px solid transparent; padding: 0; cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
}
.page-swatch.is-default { background: var(--accent); position: relative; }
.page-swatch.is-default::after { content: "A"; position: absolute; inset: 0; display: grid; place-content: center; font-size: 11px; font-weight: 800; color: var(--accent-ink); }
.page-swatch.selected { border-color: var(--text); box-shadow: 0 0 0 2px var(--panel-2) inset; }
.tab.has-color { box-shadow: inset 3px 0 0 var(--page-color); }
.tab.has-color.active { color: var(--text); background: color-mix(in srgb, var(--page-color) 16%, var(--panel-2)); border-color: color-mix(in srgb, var(--page-color) 40%, transparent); }
.mobile-home-card.has-color { border-left: 4px solid var(--page-color); }
.calendar-menu-btn { padding: 7px 12px; font-size: var(--text-sm); }

/* First-run welcome card (welcome.js) */
.welcome-card {
  background: var(--panel-2); border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
  border-radius: var(--radius-lg); box-shadow: var(--shadow-md); padding: var(--space-5) var(--space-6) var(--space-5);
  position: relative; overflow: hidden;
}
.welcome-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 4px; background: var(--accent);
}
.welcome-head { display: flex; align-items: center; gap: var(--space-3); }
.welcome-head h2 { flex: 1; margin: 0; font-family: var(--font-heading); font-size: var(--text-xl); letter-spacing: -0.01em; }
.welcome-lead { margin: 4px 0 var(--space-4); color: var(--muted); font-size: var(--text-base); }
.welcome-tips { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.welcome-tip {
  display: flex; gap: var(--space-3); align-items: flex-start; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: var(--space-3);
}
.welcome-tip-icon {
  flex-shrink: 0; width: 34px; height: 34px; display: grid; place-content: center; font-size: 17px;
  background: color-mix(in srgb, var(--accent) 14%, transparent); border-radius: var(--radius-md);
}
.welcome-tip strong { display: block; font-size: var(--text-sm); margin-bottom: 2px; }
.welcome-tip p { margin: 0; font-size: var(--text-sm); color: var(--muted); line-height: 1.45; }
.welcome-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-5); }
.welcome-actions .primary-btn, .welcome-actions .secondary-btn { padding: 10px 18px; font-size: var(--text-sm); }
.welcome-note { margin: var(--space-3) 0 0; font-size: var(--text-xs); color: var(--muted); }
.welcome-card.is-compact { padding: var(--space-4); margin-bottom: var(--space-5); flex-shrink: 0; }
.welcome-card.is-compact .welcome-head h2 { font-size: var(--text-lg); }
.welcome-card.is-compact .welcome-lead { font-size: var(--text-sm); margin-bottom: var(--space-3); }
.welcome-card.is-compact .welcome-tips { grid-template-columns: 1fr; gap: var(--space-2); }
.welcome-card.is-compact .welcome-tip { padding: 10px; }
.welcome-card.is-compact .welcome-actions { margin-top: var(--space-4); }
.welcome-card.is-compact .welcome-actions > * { flex: 1; justify-content: center; }
.mobile-home-welcome:empty, .welcome-slot:empty { display: none; }
.welcome-slot { margin-bottom: var(--space-4); }
body.calendar-fullscreen .welcome-slot { display: none; }
/* Home-screen Today: one tight row per item — the client/value badges
   still show on the list itself, they just don't fit a phone row here. */
.mobile-home-today-body .today-row { padding: 9px var(--space-4); gap: 6px 8px; }
.mobile-home-today-body .client-badge, .mobile-home-today-body .value-badge { display: none; }
.mobile-home-today-body .today-row-text { flex: 1 1 60%; font-size: var(--text-sm); }
.mobile-home-today-body .today-page-tag { font-size: 10.5px; padding: 3px 8px; }
@media (max-width: 700px) { .welcome-tips { grid-template-columns: 1fr; } }

/* Search everything (Ctrl/Cmd+K) */
.modal-overlay.search-overlay { align-items: flex-start; padding-top: 10vh; }
.modal.search-modal { max-width: 620px; width: 100%; gap: 0; }
.search-modal-head { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); }
.search-modal-icon { font-size: 16px; opacity: 0.6; }
.search-modal-head input {
  flex: 1; min-width: 0; font: inherit; font-size: var(--text-md); color: var(--text); background: transparent; border: none; padding: 8px 4px; outline: none;
}
.search-modal-head input::-webkit-search-cancel-button { display: none; }
.search-modal-head input:focus, .search-modal-head input:focus-visible { outline: none; border: none; box-shadow: none; background: transparent; }
.search-results { max-height: min(60vh, 520px); overflow-y: auto; padding: 6px 0 10px; }
.search-hint { color: var(--muted); font-size: var(--text-sm); text-align: center; padding: var(--space-6) var(--space-4); margin: 0; }
.search-group-title {
  padding: 10px var(--space-4) 4px; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.search-result {
  display: flex; align-items: center; gap: var(--space-3); width: 100%; font: inherit; color: var(--text); background: transparent;
  border: none; padding: 9px var(--space-4); cursor: pointer; text-align: left;
}
.search-result.active { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.search-result-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }
.search-result-check { color: var(--muted); flex-shrink: 0; }
.search-result-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: var(--text-sm); }
.search-result.is-done .search-result-text { color: var(--muted); text-decoration: line-through; }
.search-result mark { background: color-mix(in srgb, var(--accent) 28%, transparent); color: inherit; border-radius: 3px; padding: 0 1px; }
.search-result-meta { flex-shrink: 0; max-width: 45%; font-size: var(--text-xs); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search-modal-foot { padding: 8px var(--space-4); border-top: 1px solid var(--border); font-size: var(--text-xs); color: var(--muted); }
@media (max-width: 600px) {
  .modal-overlay.search-overlay { padding: 0; align-items: stretch; }
  .modal.search-modal { max-height: 100vh; height: 100%; border-radius: 0; border: none; }
  .search-results { max-height: none; flex: 1; }
  .search-modal-foot { display: none; }
  .search-result { flex-direction: column; align-items: stretch; gap: 2px; }
  .search-result-main { width: 100%; }
  .search-result-meta { max-width: 100%; padding-left: 24px; }
}
@keyframes search-flash { 0%, 60% { box-shadow: 0 0 0 2px var(--accent); background: color-mix(in srgb, var(--accent) 14%, var(--panel-2)); } 100% { box-shadow: 0 0 0 0 transparent; } }
.row-wrap.search-flash { animation: search-flash 1.8s var(--ease); }
@media (prefers-reduced-motion: reduce) { .row-wrap.search-flash { animation: none; outline: 2px solid var(--accent); } }

/* Recently deleted modal */
.trash-list { display: flex; flex-direction: column; gap: 6px; }
.trash-empty { color: var(--muted); font-size: var(--text-sm); text-align: center; padding: var(--space-5) 0; margin: 0; }
.trash-row {
  display: flex; align-items: center; gap: var(--space-3); padding: 10px 12px; background: var(--panel-2);
  border: 1px solid var(--border); border-radius: var(--radius-md);
}
.trash-row-icon {
  flex-shrink: 0; width: 30px; height: 30px; display: grid; place-content: center; font-size: 14px;
  background: var(--panel); border-radius: var(--radius-sm); color: var(--muted);
}
.trash-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.trash-row-name { font-weight: 600; font-size: var(--text-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trash-row-meta { font-size: var(--text-xs); color: var(--muted); }
.trash-restore-btn { padding: 6px 12px; font-size: var(--text-xs); }
.trash-foot { justify-content: space-between; gap: var(--space-3); }
.trash-foot .section-del[hidden] { display: none; }

/* ---- Mobile home screen (list picker) + the back/settings bar that
   replaces it once a page is open. Both are no-ops on desktop — hidden
   here unconditionally, and only switched on inside the 860px media query
   further down, where the sidebar is hidden entirely instead. The sibling
   rule is what actually swaps the view on mobile: while #mobile-home is
   showing, the whole .app-shell (sidebar + page content) is hidden behind
   it rather than just visually covered, so nothing in it can be focused or
   scrolled to by accident. ---- */
.mobile-home { display: none; }
.mobile-page-bar { display: none; }

.mobile-home-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-5); flex-shrink: 0; }
.mobile-home-brand { display: flex; align-items: center; gap: var(--space-2); }
.mobile-home-title { font-family: var(--font-heading); font-size: var(--text-lg); font-weight: 800; margin: 0; letter-spacing: -0.01em; }

.mobile-home-list { display: flex; flex-direction: column; gap: var(--space-3); }
.mobile-home-card {
  display: flex; align-items: center; gap: var(--space-3); width: 100%; text-align: left;
  font: inherit; color: var(--text); background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--space-3) var(--space-4); cursor: pointer;
  box-shadow: var(--shadow-sm); transition: border-color 0.12s var(--ease), box-shadow 0.12s var(--ease);
}
.mobile-home-card:hover, .mobile-home-card:focus-visible { border-color: var(--accent); }
.mobile-home-card-icon {
  flex-shrink: 0; width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 19px; color: var(--accent-ink); background: var(--accent); border-radius: var(--radius-md);
}
.mobile-home-card-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mobile-home-card-name {
  font-family: var(--font-heading); font-weight: 700; font-size: var(--text-base); color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mobile-home-card-sub { font-size: var(--text-xs); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mobile-home-card-chevron { flex-shrink: 0; color: var(--muted); font-size: var(--text-lg); line-height: 1; }

.mobile-home-empty {
  text-align: center; color: var(--muted); font-size: var(--text-sm); padding: var(--space-7) var(--space-4);
}

.mobile-home-add-wrap { margin-top: var(--space-4); flex-shrink: 0; }
.mobile-home-add-btn {
  width: 100%; font: inherit; font-size: var(--text-sm); font-weight: 700; color: var(--muted); background: transparent;
  border: 1px dashed var(--border); border-radius: var(--radius-md); padding: 12px; cursor: pointer;
}
.mobile-home-add-btn:hover { color: var(--accent); border-color: var(--accent); }
.mobile-add-page-form { margin-top: var(--space-3); flex-direction: column; }

.mobile-back-btn {
  font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--muted); background: transparent;
  border: none; padding: 8px 4px; cursor: pointer; display: inline-flex; align-items: center; gap: 2px;
}
.mobile-back-btn:hover { color: var(--accent); }

.app-main { flex: 1; min-width: 0; display: flex; justify-content: center; padding: var(--space-7) var(--space-5) 64px; }
main { width: 100%; max-width: 720px; }

.page-head { display: flex; align-items: flex-start; gap: var(--space-3); margin-bottom: var(--space-5); }
.page-head-text { flex: 1; min-width: 0; }
.eyebrow {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: var(--text-xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin: 0 0 6px;
}
.page-title-row { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.page-title-wrap { margin: 0; flex: 1 1 160px; min-width: 0; }
.page-head-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; flex-shrink: 0; }
.page-title {
  width: 100%; min-width: 0; font-family: var(--font-heading); font-weight: 800;
  font-size: clamp(27px, 5vw, var(--text-2xl)); letter-spacing: -0.015em; text-wrap: balance;
  background: transparent; color: var(--text); border: 1px solid transparent;
  border-radius: var(--radius-sm); padding: 2px 6px; margin-inline: -6px;
}
.page-title:hover { border-color: var(--border); }
.page-title:focus { border-color: var(--accent); background: var(--panel-2); outline: none; }
.page-del { flex-shrink: 0; }
.page-del[hidden] { display: none; }

.share-page-btn { flex-shrink: 0; font-size: var(--text-xs); padding: 7px 12px; }
.share-page-btn.is-shared { color: var(--accent); border-color: var(--accent); }

.invite-code-display {
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--text-md); font-weight: 700;
  color: var(--text); background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: var(--space-3); text-align: center; margin: 0 0 10px; word-break: break-all;
}
.invite-code-display[hidden] { display: none; }

.tab-shared-icon { margin-right: 4px; font-size: var(--text-xs); }

/* ---- Sidebar nav (was a horizontal tab row; now a vertical list) ---- */
.tabs { display: flex; flex-direction: column; gap: 2px; margin: 0; }
.tab {
  display: flex; align-items: center; gap: var(--space-2);
  font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--muted); background: transparent;
  border: 1px solid transparent; border-radius: var(--radius-md); padding: 9px var(--space-3); cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: left; width: 100%;
  transition: background 0.12s var(--ease), color 0.12s var(--ease);
}
.tab::before {
  flex-shrink: 0; font-size: 13px; line-height: 1; width: 16px; text-align: center; opacity: 0.85;
}
.tab[data-page-type="tasks"]::before { content: "\2713"; }
.tab[data-page-type="grocery"]::before { content: "\1F6D2"; }
.tab[data-page-type="calendar"]::before { content: "\1F4C5"; }
.tab:hover { color: var(--text); background: var(--panel-2); }
.tab.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, var(--panel-2)); border-color: color-mix(in srgb, var(--accent) 30%, transparent); }
.tab-add {
  font: inherit; font-size: var(--text-md); font-weight: 700; line-height: 1; color: var(--muted); background: transparent;
  border: 1px dashed var(--border); border-radius: var(--radius-md); width: 100%; height: 34px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: var(--space-1);
}
.tab-add:hover { color: var(--accent); border-color: var(--accent); }

.add-page-form {
  display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3);
  margin: 0; background: var(--panel-2); border: 1px dashed var(--border); border-radius: var(--radius-md);
}
.add-page-form[hidden] { display: none; }
.add-page-form input[type="text"] {
  flex: 1; min-width: 0; font: inherit; font-size: var(--text-sm); color: var(--text);
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px;
}
.add-page-form select {
  font: inherit; font-size: var(--text-sm); color: var(--text); background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px; cursor: pointer;
}
.add-page-form .primary-btn, .add-page-form .secondary-btn { flex: 1; justify-content: center; }
.add-page-form > div, .add-page-form .form-actions { display: flex; gap: var(--space-2); }

.icon-text-btn {
  flex-shrink: 0; font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 8px 13px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; transition: border-color 0.12s var(--ease), color 0.12s var(--ease);
}
.icon-text-btn:hover { border-color: var(--accent); color: var(--accent); }

.list-search {
  display: flex; align-items: center; gap: 6px; margin: 0 0 var(--space-4);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 2px 4px 2px 14px;
  box-shadow: var(--shadow-xs);
}
.list-search[hidden] { display: none; }
/* Pinned while scrolling, so search/quick-add is always one tap away on a
   long list. The page background fades in behind it once it's stuck so
   rows sliding underneath never show through around its edges. */
.list-search {
  position: sticky; top: max(8px, env(safe-area-inset-top)); z-index: 6;
  transition: box-shadow 0.15s var(--ease);
}
.list-search.is-stuck { box-shadow: var(--shadow-md), 0 -12px 0 6px var(--bg); }
.list-search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent); }
.list-search input[type="text"] {
  flex: 1; min-width: 0; font: inherit; font-size: var(--text-base); color: var(--text);
  background: transparent; border: none; padding: 10px 0;
}
.list-search input[type="text"]::placeholder { color: var(--muted); }
.list-search .del-btn[hidden] { display: none; }

.toolbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; margin: 0 0 var(--space-5); }
.summary {
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--text-sm); color: var(--muted); margin: 0;
  font-variant-numeric: tabular-nums;
}
.review-btn {
  flex-shrink: 0; font: inherit; font-weight: 600; font-size: var(--text-sm); color: var(--text);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 7px 13px; cursor: pointer;
  transition: border-color 0.12s var(--ease), color 0.12s var(--ease), box-shadow 0.12s var(--ease);
}
/* :not(:disabled) alone gives this three selector units of specificity —
   MORE than .review-btn.active or .voice-btn.listening (two each) — so
   without the extra :not()s below, simply hovering an active/listening
   button (which mobile browsers keep "stuck" after a tap until you tap
   elsewhere) always won and repainted its text the same color as its
   own background: invisible text on "Collapse all" → "Expand all", and
   on the mic button while listening. Both states should visually win
   over a mere hover, so hover is explicitly excluded from touching
   color/background when either is present. */
.review-btn:hover:not(:disabled):not(.active):not(.listening) { border-color: var(--accent); color: var(--accent); box-shadow: var(--shadow-xs); }
.review-btn:disabled { opacity: 0.6; cursor: not-allowed; }
.review-btn.active { border-color: var(--accent); color: var(--accent-ink); background: var(--accent); }

.toolbar-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.voice-btn.listening {
  border-color: var(--accent); color: var(--accent-ink); background: var(--accent);
  animation: voice-pulse 1.4s ease-in-out infinite;
}
@keyframes voice-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
  50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .voice-btn.listening { animation: none; } }

.review-panel { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg); margin-bottom: var(--space-4); overflow: hidden; box-shadow: var(--shadow-sm); }
.review-head { display: flex; align-items: center; gap: 10px; padding: var(--space-3) var(--space-4); background: var(--panel-2); border-bottom: 1px solid var(--border); }
.review-title { font-family: var(--font-heading); font-weight: 700; font-size: var(--text-base); flex: 1; }
.review-body { padding: var(--space-3) var(--space-4); font-size: var(--text-base); line-height: 1.6; white-space: pre-wrap; color: var(--text); }

.today-btn-count {
  display: inline-grid; place-content: center; min-width: 16px; height: 16px; padding: 0 4px; margin-left: 5px;
  font-size: 10px; font-weight: 700; line-height: 1; color: var(--accent-ink); background: var(--accent);
  border-radius: var(--radius-pill); vertical-align: 1px;
}
.today-body { padding: 4px 0 10px; }
.today-empty { padding: var(--space-5) var(--space-4); text-align: center; color: var(--muted); font-size: var(--text-sm); }
.today-group-title {
  padding: 10px var(--space-4) 4px; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
}
.today-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; padding: 10px var(--space-4);
  border-top: 1px solid var(--border);
}
.today-group-title + .today-row { border-top: none; }
.today-row-text { flex: 1 1 140px; min-width: 0; font-size: var(--text-base); }
.today-page-tag {
  flex-shrink: 0; font: inherit; font-size: var(--text-xs); font-weight: 600; color: var(--muted); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 4px 10px; cursor: pointer; white-space: nowrap;
}
.today-page-tag:hover { color: var(--accent); border-color: var(--accent); }
.today-row.is-done .today-row-text { color: var(--muted); text-decoration: line-through; }
.today-row-time {
  flex-shrink: 0; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 11px; font-weight: 500;
  color: var(--accent); min-width: 44px;
}
.today-row-glyph { flex-shrink: 0; width: 18px; text-align: center; color: var(--muted); font-size: 14px; }
.today-daily-badge {
  flex-shrink: 0; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px; padding: 3px 7px;
  border-radius: var(--radius-sm); background: var(--warn-bg); color: var(--warn, #c7891a); white-space: nowrap;
}

/* Mobile home screen's own Today block (the toolbar's Today button lives
   inside a page, which is hidden behind the home screen). */
.mobile-home-head-actions { display: flex; gap: var(--space-2); }
.mobile-home-today {
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm); margin-bottom: var(--space-5); overflow: hidden; flex-shrink: 0;
}
.mobile-home-today-head {
  display: flex; align-items: center; gap: var(--space-2); width: 100%; font: inherit; color: var(--text);
  background: var(--panel-2); border: none; border-bottom: 1px solid var(--border); padding: var(--space-3) var(--space-4);
  cursor: pointer; text-align: left;
}
.mobile-home-today.is-collapsed .mobile-home-today-head { border-bottom: none; }
.mobile-home-today-title { font-family: var(--font-heading); font-weight: 700; font-size: var(--text-base); flex: 1; }
.mobile-home-today-count {
  display: inline-grid; place-content: center; min-width: 20px; height: 20px; padding: 0 6px;
  font-size: 11px; font-weight: 700; color: var(--accent-ink); background: var(--accent); border-radius: var(--radius-pill);
}
.mobile-home-today-count[hidden] { display: none; }
.mobile-home-today-chevron { color: var(--muted); transition: transform 0.15s var(--ease); }
.mobile-home-today.is-collapsed .mobile-home-today-chevron { transform: rotate(-90deg); }
.mobile-home-today-body { max-height: 46vh; overflow-y: auto; }
.mobile-home-lists-title {
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px; font-weight: 500; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 var(--space-2) var(--space-1);
}

.sections { display: flex; flex-direction: column; gap: var(--space-4); }
.panel { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm); }

.section {
  background: var(--panel-2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); overflow: hidden; transition: opacity 0.12s var(--ease), box-shadow 0.15s var(--ease);
  box-shadow: var(--shadow-sm);
}
.section:hover { box-shadow: var(--shadow-md); }
.section.dragging { opacity: 0.45; }
/* The section's own color is the header's full-width background (set
   inline per-section in ui.js, along with a --ink custom property —
   near-black or near-white, whichever reads on that background). Every
   icon/text inside just says `color: var(--ink)` instead of the usual
   --text/--muted tokens, and hover/press states use a currentColor tint
   via color-mix so they work on any section color without per-color
   light/dark branching. */
.section-head {
  display: flex; align-items: center; gap: 10px; padding: var(--space-3) var(--space-4);
  color: var(--ink, var(--text)); cursor: grab; transition: padding 0.1s var(--ease);
}
/* Collapsed: only the arrow, color swatch, and title earn a place —
   drag handle, reorder buttons, item count, and Delete all disappear
   until it's expanded again, so a long list of collapsed sections reads
   as a compact index instead of each one still claiming a full row's
   worth of chrome. The section stays draggable by its header either way
   (head.draggable isn't tied to the handle's visibility). */
.section-head:not(.expanded) { padding: 9px var(--space-4); }
.section-head:not(.expanded) .section-count,
.section-head:not(.expanded) .section-del {
  display: none;
}
/* Drag handles (drag.js) — one compact handle for mouse, touch, and pen,
   replacing the old stacked up/down arrows that doubled each row's height
   on phones. touch-action: none lets a finger drag it without scrolling
   the page; the button itself also takes ArrowUp/ArrowDown. */
.section-handle, .drag-handle {
  flex-shrink: 0; display: grid; place-content: center; font: inherit; line-height: 1; letter-spacing: -1px;
  background: transparent; border: none; border-radius: var(--radius-sm); cursor: grab; user-select: none;
  -webkit-user-select: none; touch-action: none; -webkit-touch-callout: none; padding: 0;
}
.section-handle { width: 26px; height: 28px; color: var(--ink, var(--muted)); opacity: 0.8; font-size: 15px; }
.section-handle:hover, .drag-handle:hover { background: color-mix(in srgb, currentColor 12%, transparent); }
.section-handle:active, .drag-handle:active { cursor: grabbing; }
body.is-reordering, body.is-reordering * { user-select: none !important; -webkit-user-select: none !important; cursor: grabbing !important; }
.is-dragging { box-shadow: var(--shadow-lg); opacity: 0.96; background: var(--panel-2); border-radius: var(--radius-md); }
section.section.is-dragging { border-radius: var(--radius-lg); }
.drag-placeholder {
  list-style: none; border: 2px dashed color-mix(in srgb, var(--accent) 55%, transparent); border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--accent) 6%, transparent); box-sizing: border-box;
}
section.drag-placeholder { border-radius: var(--radius-lg); }

.color-swatch {
  -webkit-appearance: none; appearance: none; flex-shrink: 0; width: 20px; height: 20px; padding: 0;
  border: 2px solid color-mix(in srgb, currentColor 45%, transparent); border-radius: 50%; background: none; cursor: pointer;
}
.color-swatch::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50%; overflow: hidden; }
.color-swatch::-webkit-color-swatch { border: none; border-radius: 50%; }
.color-swatch::-moz-color-swatch { border: none; border-radius: 50%; }
.color-swatch.small { width: 16px; height: 16px; margin-top: 2px; border-color: var(--border); }
.section-head input[type="text"] { cursor: text; }
.section-head button, .section-head input[type="color"] { cursor: pointer; }

.collapse-btn {
  flex-shrink: 0; width: 28px; height: 28px; display: grid; place-content: center; border: none;
  background: transparent; color: inherit; cursor: pointer; font-size: 15px; border-radius: var(--radius-sm);
  transition: transform 0.15s var(--ease), background 0.12s var(--ease);
}
.collapse-btn:hover { background: color-mix(in srgb, currentColor 18%, transparent); }
.collapse-btn.is-collapsed { transform: rotate(-90deg); }

.section-name {
  font-family: var(--font-heading); font-weight: 700; font-size: var(--text-md); margin: 0; flex: 1; min-width: 0;
  word-wrap: break-word; background: transparent; color: inherit; border: 1px solid transparent;
  border-radius: var(--radius-sm); padding: 4px 6px; margin-inline: -6px;
}
.section-name::placeholder { color: inherit; opacity: 0.7; }
.section-name:hover { border-color: color-mix(in srgb, currentColor 30%, transparent); }
.section-name:focus { border-color: currentColor; background: color-mix(in srgb, currentColor 14%, transparent); outline: none; }

.section-count { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--text-xs); color: inherit; opacity: 0.8; flex-shrink: 0; font-variant-numeric: tabular-nums; }

.section-del {
  flex-shrink: 0; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 11px; letter-spacing: 0.02em;
  color: inherit; opacity: 0.85; background: transparent; border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
  border-radius: var(--radius-sm); padding: 5px 9px; cursor: pointer; white-space: nowrap;
}
.section-del:hover { opacity: 1; color: var(--accent-ink); background: var(--danger); border-color: var(--danger); }
.section-del.confirm { opacity: 1; color: var(--accent-ink); background: var(--danger); border-color: var(--danger); }

.health-strip {
  padding: 8px var(--space-4); font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 11px;
  color: var(--muted); background: var(--panel); border-bottom: 1px solid var(--border);
}
.stalled-flag { color: var(--danger); font-weight: 600; }

form.add-task { display: flex; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); background: var(--panel); }
form.add-task[hidden] { display: none; }
form.add-task input[type="text"] {
  flex: 1; min-width: 0; font: inherit; font-size: var(--text-base); color: var(--text);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px;
}
form.add-task input::placeholder { color: var(--muted); }
form.add-task button {
  font: inherit; font-weight: 600; font-size: var(--text-sm); color: var(--accent-ink);
  background: var(--accent); border: none; border-radius: var(--radius-sm); padding: 0 var(--space-4); cursor: pointer;
}
form.add-task button:disabled { opacity: 0.5; cursor: not-allowed; }
form.add-task button:hover:not(:disabled) { filter: brightness(1.06); }

input:focus-visible, button:focus-visible, select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

ul.list { list-style: none; margin: 0; padding: 0; background: var(--panel-2); }
li.row-wrap { position: relative; border-bottom: 1px solid var(--border); border-left: 3px solid transparent; }
li.row-wrap:last-child { border-bottom: none; }
li.row-wrap.someday .row-text { color: var(--muted); }

.category-select {
  font: inherit; font-size: 12px; color: var(--text); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: 6px; padding: 4px 6px; cursor: pointer; flex-shrink: 0; max-width: 120px;
}

@keyframes task-celebrate-pop {
  0% { transform: translateY(2px) scale(0.85); opacity: 0; }
  25% { transform: translateY(-2px) scale(1.05); opacity: 1; }
  75% { transform: translateY(-16px) scale(1); opacity: 1; }
  100% { transform: translateY(-26px) scale(0.95); opacity: 0; }
}
@keyframes task-celebrate-fade {
  0% { opacity: 0; } 15% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; }
}
.celebrate-badge {
  position: absolute; right: 14px; top: 8px; font-family: var(--font-heading); font-weight: 700;
  font-size: 12px; color: var(--done); background: var(--done-bg); border-radius: var(--radius-pill);
  padding: 4px 10px; pointer-events: none; z-index: 2; white-space: nowrap;
  animation: task-celebrate-pop 1.1s ease forwards;
}
@media (prefers-reduced-motion: reduce) {
  .celebrate-badge { animation: task-celebrate-fade 1.1s ease forwards; }
}

.row { display: flex; align-items: flex-start; gap: 10px; padding: var(--space-3) var(--space-4); transition: background 0.1s var(--ease); }
li.row-wrap:hover .row { background: var(--panel); }

.drag-handle { width: 22px; height: 24px; margin: -1px -4px 0 -6px; color: var(--muted); font-size: 13px; }

.check {
  appearance: none; -webkit-appearance: none; width: 21px; height: 21px; margin-top: 1px;
  flex-shrink: 0; border: 1.5px solid var(--border); border-radius: var(--radius-sm); background: var(--panel-2);
  cursor: pointer; display: grid; place-content: center; transition: border-color 0.12s var(--ease), background 0.12s var(--ease);
}
.check:hover { border-color: var(--accent); }
.check::after {
  content: ""; width: 11px; height: 11px; border-radius: 4px; background: var(--done);
  transform: scale(0); transition: transform 0.12s var(--ease);
}
.check:checked { border-color: var(--done); background: var(--done-bg); }
.check:checked::after { transform: scale(1); }

.row-text { flex: 1; min-width: 0; font-size: var(--text-base); line-height: 1.45; padding-top: 1px; word-wrap: break-word; cursor: text; border-radius: 4px; }
.row-text:hover { background: color-mix(in srgb, var(--accent) 7%, transparent); }
/* Tap-to-edit (always editable) — same footprint as the text it replaces. */
.row-text-input {
  flex: 1; min-width: 0; font: inherit; font-size: var(--text-base); line-height: 1.45; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--accent); border-radius: 6px; padding: 0 6px; margin: -1px 0;
}
li.row-wrap.done .row-text {
  color: var(--muted); text-decoration: line-through; text-decoration-color: var(--done); text-decoration-thickness: 1.5px;
}

.due-badge {
  flex-shrink: 0; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px;
  letter-spacing: 0.02em; padding: 3px 7px; border-radius: var(--radius-sm); white-space: nowrap; margin-top: 2px;
  background: var(--bg); color: var(--muted); border: 1px solid var(--border);
}
.due-badge.due-warn { background: var(--warn-bg); color: var(--warn); border-color: transparent; }
.due-badge.due-danger { background: var(--danger-bg); color: var(--danger); border-color: transparent; }
.recur-badge { flex-shrink: 0; margin-top: 3px; font-size: 12px; color: var(--muted); }
.daily-badge { color: var(--warn, #c7891a); }

.client-badge, .value-badge {
  flex-shrink: 0; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px;
  letter-spacing: 0.02em; padding: 3px 7px; border-radius: var(--radius-sm); white-space: nowrap; margin-top: 2px;
}
.client-badge { background: var(--bg); color: var(--muted); border: 1px solid var(--border); }
.value-badge { background: var(--done-bg); color: var(--done); border: 1px solid transparent; }

.details-toggle {
  flex-shrink: 0; width: 22px; height: 22px; display: grid; place-content: center; border: none;
  background: transparent; color: var(--muted); cursor: pointer; border-radius: var(--radius-sm); font-size: 13px;
}
.details-toggle:hover, .details-toggle.open { color: var(--accent); background: var(--bg); }

.move-select {
  font: inherit; font-size: 12px; color: var(--text); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: 6px; padding: 4px 6px; cursor: pointer;
}

.del-btn {
  flex-shrink: 0; width: 26px; height: 26px; border-radius: var(--radius-sm); border: none; background: transparent;
  color: var(--muted); cursor: pointer; font-size: 15px; line-height: 1; display: grid; place-content: center;
  transition: background 0.12s var(--ease), color 0.12s var(--ease);
}
.del-btn:hover { background: var(--danger-bg); color: var(--danger); }

.section.drag-over { outline: 2px dashed var(--accent); outline-offset: -2px; }

.task-details { padding: var(--space-3) var(--space-4) var(--space-4) 42px; background: var(--panel); border-top: 1px dashed var(--border); }
.detail-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 18px; }
.detail-field { display: flex; align-items: center; gap: 6px; }
.detail-label {
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--muted);
}
.detail-field input[type="date"], .detail-field input[type="datetime-local"], .detail-field input[type="text"], .detail-field input[type="number"], .detail-field select {
  font: inherit; font-size: 13px; color: var(--text); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 5px 8px;
}
.detail-field input[type="text"] { width: 140px; }
.detail-field input[type="number"] { width: 90px; }
.someday-field { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text); cursor: pointer; }
.someday-field input { cursor: pointer; }
/* [hidden] alone loses to .detail-row's `display: flex` at equal CSS
   specificity (both are one class/attribute selector) — the custom-days
   row carries BOTH classes, so without this explicit override it stayed
   visibly rendered even while its `hidden` attribute (and every test
   checking that attribute) correctly said it was hidden. */
.custom-days-row[hidden], .calendar-quickadd-custom-days[hidden] { display: none; }
.custom-days-row { margin-top: -4px; padding-top: 8px; border-top: 1px dashed var(--border); }
.custom-day-check {
  display: flex; align-items: center; gap: 4px; font-size: 12.5px; color: var(--text); cursor: pointer;
}
.custom-day-check input { cursor: pointer; }

.ai-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--space-3); }
.ai-btn {
  font: inherit; font-size: 12px; font-weight: 600; color: var(--accent); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 6px 10px; cursor: pointer;
}
.ai-btn:hover:not(:disabled) { border-color: var(--accent); }
.ai-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.ai-output {
  margin-top: 10px; padding: 10px 12px; background: var(--panel-2); border: 1px solid var(--border);
  border-radius: var(--radius-md); font-size: 13px; line-height: 1.5; white-space: pre-wrap; color: var(--text);
}
.ai-off-note { margin-top: 10px; font-size: 12px; color: var(--muted); }
.ai-off-note a { color: inherit; text-decoration: underline; cursor: pointer; background: none; border: none; font: inherit; padding: 0; }
.stop-btn {
  margin-top: 8px; font: inherit; font-size: 11px; color: var(--danger); background: transparent;
  border: 1px solid var(--danger); border-radius: var(--radius-sm); padding: 4px 9px; cursor: pointer;
}

.someday-divider {
  padding: 10px var(--space-4) 4px; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
}

.empty-tasks { padding: var(--space-5) var(--space-4); text-align: center; color: var(--muted); font-size: 13px; }
.empty-all { padding: var(--space-7) var(--space-5); text-align: center; color: var(--muted); font-size: 14px; }

/* Same equal-specificity [hidden]-vs-"display: flex" issue as
   .custom-days-row above — #add-section-panel carries both "panel" and
   "add-section" classes, and without this it stayed visibly rendered on
   calendar pages (hidden there — sections/categories aren't a Family
   Calendar concept) even though its `hidden` attribute was correctly
   set and every test checking that attribute passed. */
.add-section[hidden] { display: none; }
.add-section { display: flex; gap: var(--space-2); padding: var(--space-4); }
.add-section input {
  flex: 1; min-width: 0; font: inherit; font-size: var(--text-base); color: var(--text);
  background: var(--panel-2); border: 1px dashed var(--border); border-radius: var(--radius-sm); padding: 9px 12px;
}
.add-section input::placeholder { color: var(--muted); }
.add-section button {
  font: inherit; font-weight: 600; font-size: 13px; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0 var(--space-4); cursor: pointer;
}
.add-section button:disabled { opacity: 0.5; cursor: not-allowed; }
.add-section button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }

.status { margin-top: var(--space-3); font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 12px; color: var(--muted); min-height: 16px; }
.status.warn { color: var(--danger); }

.footer-note { margin-top: var(--space-6); font-size: 12px; line-height: 1.5; color: var(--muted); }
.footer-note code { font-family: "IBM Plex Mono", ui-monospace, monospace; background: var(--panel); padding: 1px 5px; border-radius: 4px; }
.footer-links { margin-top: 6px; }
.footer-links a { color: var(--muted); text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--muted) 40%, transparent); }
.footer-links a:hover, .footer-links a:focus-visible { color: var(--accent); text-decoration-color: var(--accent); }

/* ---- modals ---- */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(10,10,14,0.46); display: flex; align-items: center; justify-content: center;
  padding: 16px; z-index: 10; backdrop-filter: blur(2px);
}
.modal-overlay[hidden] { display: none; }
.modal {
  background: var(--panel-2); border-radius: var(--radius-xl); border: 1px solid var(--border); width: 100%; max-width: 480px;
  max-height: calc(100vh - 32px); display: flex; flex-direction: column; overflow: hidden; box-shadow: var(--shadow-lg);
}
.modal-head { display: flex; align-items: center; gap: 10px; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); }
.modal-head h2 { font-family: var(--font-heading); font-size: var(--text-lg); margin: 0; flex: 1; }
.modal-body { padding: var(--space-4) var(--space-5); overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-6); }
.modal-foot { padding: var(--space-3) var(--space-5); border-top: 1px solid var(--border); display: flex; justify-content: flex-end; }

.settings-section h3 { font-family: var(--font-heading); font-size: var(--text-base); margin: 0 0 8px; }
.settings-help { font-size: 12.5px; line-height: 1.5; color: var(--muted); margin: 0 0 12px; }
.field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px; }
.field-label { font-size: 12px; font-weight: 600; color: var(--text); }
.field input, .field select {
  font: inherit; font-size: 14px; color: var(--text); background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 9px 10px;
}
.theme-colors { display: flex; flex-wrap: wrap; gap: 18px; margin-bottom: 4px; }
.theme-color-field { display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; }
.theme-color-field .color-swatch { width: 26px; height: 26px; }
.settings-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.settings-status { font-size: 12px; color: var(--muted); }
.settings-status.ok { color: var(--done); }
.settings-status.err { color: var(--danger); }

.primary-btn {
  font: inherit; font-weight: 600; font-size: 13px; color: var(--accent-ink); background: var(--accent);
  border: none; border-radius: var(--radius-md); padding: 9px 17px; cursor: pointer; box-shadow: var(--shadow-xs);
  transition: filter 0.1s var(--ease), box-shadow 0.12s var(--ease), transform 0.08s var(--ease);
}
.primary-btn:hover { filter: brightness(1.06); box-shadow: var(--shadow-sm); }
.primary-btn:active { transform: translateY(1px); }
.secondary-btn {
  font: inherit; font-weight: 600; font-size: 13px; color: var(--text); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: var(--radius-md); padding: 8px 15px; cursor: pointer; display: inline-flex; align-items: center;
  transition: border-color 0.12s var(--ease), color 0.12s var(--ease), box-shadow 0.12s var(--ease);
}
.secondary-btn[hidden] { display: none; }
a.secondary-btn { text-decoration: none; }
.secondary-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.settings-optional {
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-pill);
  padding: 2px 7px; margin-left: 6px; vertical-align: 2px;
}
.reminder-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; padding: 8px 0; font-size: var(--text-sm); cursor: pointer;
}
.reminder-row input[type="checkbox"] { width: 18px; height: 18px; margin: 0; accent-color: var(--accent); flex-shrink: 0; }
.reminder-row input:disabled + span { color: var(--muted); }
.reminder-inline-input {
  font: inherit; font-size: var(--text-sm); color: var(--text); background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 5px 8px;
}
.reminder-inline-input:disabled { opacity: 0.5; }
.reminders-status { color: var(--text); background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 8px 12px; }
.reminders-status[hidden] { display: none; }
.report-filters { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 var(--space-3); }
.report-custom-dates { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--space-3); }
.report-custom-dates[hidden] { display: none; }
.report-preview {
  font-size: var(--text-sm); font-weight: 600; color: var(--text); margin: 2px 0 8px; padding: 9px 12px;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-md);
}
@media (max-width: 600px) { .report-filters { grid-template-columns: 1fr; } }
.secondary-btn:hover { border-color: var(--accent); color: var(--accent); box-shadow: var(--shadow-xs); }
.file-btn { position: relative; overflow: hidden; }

@media (prefers-reduced-motion: reduce) { .check::after, .collapse-btn { transition: none; } }
.check.celebrate { animation: check-pulse 0.5s ease-out; }
@keyframes check-pulse {
  0% { box-shadow: 0 0 0 0 var(--done-bg); }
  100% { box-shadow: 0 0 0 7px rgba(0,0,0,0); }
}
@media (prefers-reduced-motion: reduce) { .check.celebrate { animation: none; } }

/* ---- Mobile navigation: below 860px the sidebar (desktop's always-visible
   "home screen") is replaced entirely by #mobile-home, a full-screen list
   picker, plus a slim back/settings bar at the top of whichever page is
   open. No horizontal top tab bar anymore — see #mobile-home below for the
   picker itself. ---- */
@media (max-width: 860px) {
  .app-shell { flex-direction: column; min-height: 0; }
  .sidebar { display: none; }
  .app-main { padding: var(--space-5) var(--space-4) 48px; }

  .mobile-home:not([hidden]) {
    display: flex; flex-direction: column; position: fixed; inset: 0; z-index: 3;
    background: var(--bg); overflow-y: auto; padding: var(--space-5) var(--space-4) var(--space-6);
  }
  /* Only at mobile widths does #mobile-home actually cover the screen, so
     the whole app-shell (sidebar + page content) only needs to step aside
     here, not on desktop where .mobile-home is already display:none. */
  .mobile-home:not([hidden]) ~ .app-shell { display: none; }
  .mobile-page-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }
}

@media (max-width: 420px) {
  /* Below ~420px even a 160px title-flex-basis doesn't leave the title
     comfortable room next to 2-3 action buttons — give it the full
     width on its own line and let the actions wrap as their own row
     underneath, so the title never gets squeezed to a sliver. */
  .page-title-row { flex-direction: column; align-items: stretch; }
  .page-title-wrap { flex-basis: auto; width: 100%; }
  .page-head-actions { width: 100%; }
  .sidebar-brand .eyebrow { display: none; }
}

/* Mobile pass: iOS Safari auto-zooms the whole page when focusing any text
   input styled under 16px, which is jarring — bump every form field to
   exactly 16px here instead of changing the (slightly more compact) desktop
   sizing everywhere. Touch targets for the small icon buttons are also
   enlarged, since ~22px is comfortably clickable with a mouse but a miss-tap
   magnet with a finger. */
@media (max-width: 600px) {
  input[type="text"], input[type="email"], input[type="password"],
  input[type="date"], input[type="search"], input[type="number"], select, textarea {
    /* !important: several more-specific desktop rules (form.add-task
       input[type="text"], .field input, etc.) set font-size: 14px, and this
       has to win over every one of them without hunting down and re-
       specifying each selector here. */
    font-size: 16px !important;
  }
  .page-title { font-size: clamp(24px, 7vw, 30px); }

  .collapse-btn { width: 40px; height: 40px; font-size: 19px; }
  .details-toggle, .del-btn { width: 32px; height: 32px; font-size: 15px; }
  .check { width: 24px; height: 24px; }
  .check::after { width: 12px; height: 12px; }
  .color-swatch { width: 24px; height: 24px; }
  .color-swatch.small { width: 20px; height: 20px; }
  /* Compact rows: the single drag handle replaced the old stacked ▲▼ pair
     (which made every row ~64px tall), so rows can stay one line. The
     handle keeps a finger-sized hit area via padding, not visual size. */
  .drag-handle { width: 26px; height: 32px; margin: -5px -4px -5px -8px; font-size: 14px; }
  .section-handle { width: 30px; height: 34px; }
  .row { padding: 9px 12px; gap: 8px; align-items: center; }
  .row .check { margin-top: 0; }
  /* Grocery category picker: an icon-sized control on a phone (it still
     opens the native picker); the full name shows in the picker itself. */
  .category-select {
    width: 32px; max-width: 32px; height: 30px; padding: 0; color: transparent; text-indent: 40px; overflow: hidden;
    background: var(--panel-2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b6e73' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 4v16M7 20l-3-3M7 20l3-3M17 20V4M17 4l-3 3M17 4l3 3'/%3E%3C/svg%3E") center / 16px no-repeat;
    -webkit-appearance: none; appearance: none;
  }
  .category-select option { color: var(--text); }
  .section-head { padding: 14px; }
  .tab { padding: 9px 14px; }
  .tab-add { height: 36px; }

  /* On a narrow phone, the section header (drag handle/move buttons,
     collapse arrow, color dot, name, item count, delete button) is too much
     to fit on one line — without a wrap point, the name INPUT doesn't get
     to wrap like text would, it just silently clips to a few characters
     ("Illustration Clients" rendering as "Illustratio"). Give the row a
     wrap point and a sane minimum width for the name so it reliably gets
     most of the first line, with the count/delete button dropping to a
     second line instead of squeezing the name down.  */
  .section-head { flex-wrap: wrap; row-gap: 6px; gap: 8px; }
  .section-name { flex: 1 1 140px; }

  /* Same squeeze, same fix, for task/grocery rows: on a narrow phone the
     due-badge/recur-badge/category-select/delete button (all fixed-width)
     were leaving almost no room for the item text, which can't truncate
     like the section name did — instead it wrapped one word-fragment per
     line ("Orga/nic/Baby/Spina/ch..."). Giving row-text a minimum flex
     basis forces those trailing controls onto their own second line
     instead, so the text gets most of the first line to itself. */
  .row { flex-wrap: wrap; row-gap: 6px; }
  .row-text, .row-text-input { flex: 1 1 120px; }
}

/* --- Family calendar (page.type === "calendar") --- */

.calendar-view { display: flex; flex-direction: column; gap: var(--space-4); }

.calendar-toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-2) var(--space-3);
  box-shadow: var(--shadow-sm);
}
.calendar-nav { display: flex; align-items: center; gap: 8px; }
.calendar-nav-btn {
  font: inherit; font-size: 16px; font-weight: 700; color: var(--text); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: var(--radius-md); width: 34px; height: 34px; cursor: pointer;
  transition: border-color 0.12s var(--ease), color 0.12s var(--ease);
}
.calendar-nav-btn:hover { border-color: var(--accent); color: var(--accent); }
.calendar-month-label { font-family: var(--font-heading); font-size: var(--text-md); font-weight: 700; min-width: 12ch; text-align: center; }

.calendar-fullscreen-back {
  font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--muted); background: transparent;
  border: none; padding: 6px 4px; cursor: pointer;
}
.calendar-fullscreen-back:hover { color: var(--accent); }

/* Reused by the "Add event" modal's custom-days row (see index.html) even
   though the form it was originally built for is gone — same checkbox
   layout either way. */
.calendar-quickadd-custom-days {
  display: flex; flex-wrap: wrap; gap: 6px 14px; padding-top: 2px;
}

.calendar-grid {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; background: var(--border);
  border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm);
}
.calendar-weekday {
  background: var(--panel-2); color: var(--muted); font-size: 11px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; text-align: center; padding: 9px 4px;
}
/* Fixed height, always — the cell never grows to fit its content. When
   there's more than fits, buildCalendarGrid caps how many chips it
   appends and adds a "+N more" button instead; overflow:hidden here is
   just a hard backstop so nothing can ever force the cell taller. */
.calendar-day {
  background: var(--panel-2); height: 118px; padding: 7px 6px; display: flex; flex-direction: column;
  gap: 4px; cursor: pointer; overflow: hidden; position: relative; transition: background 0.1s var(--ease);
  /* A tap-and-hold is how mobile opens the "Add event" modal (see ui.js) —
     without these, the device's own text-selection / callout menu kicks in
     during the hold instead, fighting the gesture. */
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
}
.calendar-day:hover { background: var(--panel); }
.calendar-day.outside-month { background: var(--panel); opacity: 0.5; }
.calendar-day.is-today .calendar-day-number {
  color: var(--accent-ink); background: var(--accent); border-radius: 50%;
  width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
}
.calendar-day.is-selected { box-shadow: inset 0 0 0 2px var(--accent); }
.calendar-day-number { flex-shrink: 0; font-size: 12.5px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.calendar-holiday-label {
  flex-shrink: 0; display: block; width: 100%; max-width: 100%; text-align: left;
  font: inherit; font-size: 9.5px; font-weight: 700; font-style: italic; color: var(--accent);
  background: transparent; border: none; padding: 0; margin: -2px 0 0; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.calendar-holiday-label:hover { text-decoration: underline; }
.calendar-day-events { display: flex; flex-direction: column; gap: 3px; min-height: 0; overflow: hidden; }
.calendar-day-more {
  flex-shrink: 0; align-self: flex-start; font: inherit; font-size: 10.5px; font-weight: 700; color: var(--muted);
  background: var(--panel); border: none; padding: 2px 6px; border-radius: var(--radius-pill); cursor: pointer; white-space: nowrap;
}
.calendar-day-more:hover { color: var(--accent); }
.calendar-day-view {
  position: absolute; top: 3px; right: 3px; width: 22px; height: 22px; display: inline-flex;
  align-items: center; justify-content: center; font-size: 11px; line-height: 1; color: var(--muted);
  background: transparent; border: none; margin: 0; cursor: pointer; border-radius: var(--radius-sm);
  opacity: 0.6;
}
.calendar-day-view:hover { opacity: 1; color: var(--accent); background: var(--panel); }

/* ---- Family Calendar full-screen takeover (closest to Apple Calendar on
   iPhone) — at EVERY viewport width, not just mobile. While active
   (body.calendar-fullscreen, toggled in render()) the sidebar, page-head,
   toolbar and footer are hidden outright, and .calendar-view itself takes
   over the whole viewport as a fixed overlay with its own minimal top bar
   (see the "Lists" back button built in renderCalendarGrid). Exiting
   (tapping that back button) just removes this class again — the sidebar
   or mobile back button that reappears is the "way back to other lists"
   from here, not a page navigation in its own right. ---- */
body.calendar-fullscreen .sidebar,
body.calendar-fullscreen .mobile-page-bar,
body.calendar-fullscreen .page-head,
body.calendar-fullscreen .toolbar,
body.calendar-fullscreen .list-search,
body.calendar-fullscreen .review-panel,
body.calendar-fullscreen .footer-note,
body.calendar-fullscreen #status {
  display: none !important;
}
body.calendar-fullscreen .app-main { padding: 0; }
body.calendar-fullscreen main { max-width: none; }

.calendar-view.is-fullscreen {
  position: fixed; inset: 0; z-index: 2; background: var(--bg);
  padding: var(--space-3) var(--space-3) env(safe-area-inset-bottom, var(--space-3));
}
.calendar-view.is-fullscreen .calendar-toolbar {
  background: transparent; border: none; box-shadow: none; padding: var(--space-2) var(--space-1);
}
/* Rows stretch to fill whatever height is left, instead of the fixed
   118px cells used everywhere else — the whole point of "full screen" is
   that the grid actually fills the screen, Apple-Calendar-style. Cells
   still never grow or shrink based on how many events are in them, same
   as the fixed-height version — minmax(0, …) is what keeps that true:
   a plain 1fr row has an implicit "auto" minimum, so a busier cell's
   content would otherwise be able to stretch its whole row taller than
   the others. */
.calendar-view.is-fullscreen .calendar-grid {
  flex: 1; min-height: 0; grid-template-rows: auto repeat(6, minmax(0, 1fr));
}
.calendar-view.is-fullscreen .calendar-day { height: 100%; }

.calendar-event-chip {
  display: flex; align-items: center; gap: 4px; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 3px 6px; font-size: 11px; cursor: default; line-height: 1.3;
}
.calendar-event-chip.is-done { opacity: 0.55; }
.calendar-event-chip.is-done .calendar-event-text, .calendar-event-chip.is-done .calendar-event-text-input {
  text-decoration: line-through; text-decoration-color: var(--done);
}
.calendar-event-chip input[type="checkbox"] { flex-shrink: 0; width: 13px; height: 13px; margin: 0; accent-color: var(--accent); cursor: pointer; }
/* A projected (non-anchor) occurrence of a recurring event — dashed
   border and a little more transparency distinguish it at a glance from
   the one real, editable anchor chip. */
.calendar-event-chip.is-virtual { border-style: dashed; opacity: 0.8; }
.calendar-event-recur-glyph { flex-shrink: 0; font-size: 10px; color: var(--muted); cursor: help; }
.calendar-event-time { flex-shrink: 0; color: var(--muted); font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 10px; }
.calendar-event-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.calendar-event-text-input {
  flex: 1; min-width: 0; font: inherit; font-size: 11px; color: var(--text); background: transparent; border: none; padding: 0;
}
.calendar-event-text-input:focus { outline: 1px solid var(--accent); border-radius: 3px; }
.calendar-event-del {
  flex-shrink: 0; font: inherit; font-size: 13px; line-height: 1; color: var(--muted); background: transparent;
  border: none; cursor: pointer; padding: 0 2px;
}
.calendar-event-del:hover { color: var(--danger); }
.calendar-event-source {
  flex-shrink: 0; font-size: 9.5px; padding: 2px 6px; margin: 0;
}

.calendar-day-full-events { display: flex; flex-direction: column; gap: 8px; }
.calendar-day-full-events .calendar-event-chip { font-size: 13px; padding: 7px 10px; }
.calendar-day-full-events .calendar-no-events { color: var(--muted); font-size: 13px; }

/* Month / Agenda toggle + explicit "+ Event" button in the calendar bar. */
.calendar-toolbar-right { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
.calendar-mode-toggle {
  display: inline-flex; padding: 3px; gap: 2px; background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-pill);
}
.calendar-mode-btn {
  font: inherit; font-size: var(--text-xs); font-weight: 600; color: var(--muted); background: transparent; border: none;
  border-radius: var(--radius-pill); padding: 6px 12px; cursor: pointer;
}
.calendar-mode-btn.active { background: var(--accent); color: var(--accent-ink); }
.calendar-add-event-btn { padding: 8px 14px; font-size: var(--text-sm); }

/* Agenda: a chronological list of upcoming days that have something on them. */
.calendar-agenda { display: flex; flex-direction: column; gap: var(--space-3); }
.calendar-view.is-fullscreen .calendar-agenda { flex: 1; min-height: 0; overflow-y: auto; padding-bottom: var(--space-6); }
.calendar-agenda-day {
  flex-shrink: 0; background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-xs); overflow: hidden;
}
.calendar-agenda-day.is-today { border-color: var(--accent); }
.calendar-agenda-date {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px var(--space-2); padding: var(--space-3) var(--space-4) var(--space-2);
}
.calendar-agenda-date strong { font-family: var(--font-heading); font-size: var(--text-base); }
.calendar-agenda-day.is-today .calendar-agenda-date strong { color: var(--accent); }
.calendar-agenda-date-sub { font-size: var(--text-xs); color: var(--muted); }
.calendar-agenda-holiday {
  font-size: var(--text-xs); font-weight: 700; font-style: italic; color: var(--accent);
}
.calendar-agenda-add {
  margin-left: auto; align-self: center; width: 28px; height: 28px; font: inherit; font-size: 16px; line-height: 1; color: var(--muted);
  background: transparent; border: 1px solid var(--border); border-radius: 50%; cursor: pointer;
}
.calendar-agenda-add:hover { color: var(--accent); border-color: var(--accent); }
.calendar-agenda-events { display: flex; flex-direction: column; gap: 6px; padding: 0 var(--space-3) var(--space-3); }
.calendar-agenda-events:empty { display: none; }
.calendar-agenda-day:has(.calendar-agenda-events:empty) .calendar-agenda-date { padding-bottom: var(--space-3); }
.calendar-agenda-events .calendar-event-chip { font-size: 13px; padding: 8px 10px; }
.calendar-agenda-events .calendar-event-text-input { font-size: 13px; }
.calendar-agenda-empty { text-align: center; color: var(--muted); font-size: var(--text-sm); padding: var(--space-8) var(--space-4); }

/* ---- Mobile calendar: rebuilt, not just shrunk. Dylan's single biggest
   complaint about the old look was the calendar on a phone — seven
   cramped, barely-tappable 84px squares with tiny overlapping text. The
   grid math (fixed cell height, capped visible chips, "+N more") is
   untouched here on purpose (ui.js's isNarrowCalendar/maxVisibleEvents);
   this is a restyle: taller, calmer cells; a bigger, bolder date number;
   event chips as small color dots + one clean line of text instead of
   full bordered boxes; and real touch-sized nav/view buttons. ---- */
@media (max-width: 600px) {
  .calendar-view { gap: var(--space-3); }
  .calendar-toolbar { padding: var(--space-2); }
  .calendar-nav-btn { width: 38px; height: 38px; font-size: 17px; }
  .calendar-month-label { font-size: var(--text-base); min-width: 0; }

  .calendar-grid { border-radius: var(--radius-md); gap: 1px; }
  .calendar-weekday { font-size: 10px; padding: 7px 2px; letter-spacing: 0.04em; }

  /* Taller than the old 84px crush, and with real padding — the grid
     scrolls into view fine; a legible, tappable grid beats a shorter one
     that forces you into the day popup for almost everything. */
  .calendar-day { height: 108px; padding: 5px 4px; gap: 3px; }
  .calendar-day.is-today .calendar-day-number { width: 20px; height: 20px; font-size: 11.5px; }
  .calendar-day-number { font-size: 11.5px; }
  .calendar-holiday-label { font-size: 8px; }

  /* Chips inside the GRID cells (not the day-popup modal, which stays
     full-size and fully interactive) collapse to a plain color dot, the
     same pattern Google/Apple Calendar use for a phone month view — no
     event text competing for the ~45px of width a 7-column cell has to
     work with, which is what made the old grid feel cramped and
     unreadable. Dots sit in a row under the date number; the chip's
     title attribute (set in ui.js) gives a tap-and-hold hint, and
     tapping the day's "view"/"+N" affordance opens the full, legible
     day popup where every event has its real text, checkbox and delete
     button at full size. */
  .calendar-day-events {
    flex-direction: row; flex-wrap: wrap; align-items: center; gap: 5px; padding-top: 1px;
  }
  .calendar-day-events .calendar-event-chip {
    gap: 0; padding: 0; background: transparent; border: none; width: 9px; height: 9px; min-width: 0;
  }
  .calendar-day-events .calendar-event-chip::before {
    content: ""; flex-shrink: 0; width: 9px; height: 9px; border-radius: 50%; background: var(--accent);
  }
  .calendar-day-events .calendar-event-chip.is-virtual::before { background: transparent; border: 1.5px solid var(--accent); }
  .calendar-day-events .calendar-event-chip.is-done::before { background: var(--done); opacity: 0.6; }
  .calendar-day-events .calendar-event-chip input[type="checkbox"],
  .calendar-day-events .calendar-event-time,
  .calendar-day-events .calendar-event-recur-glyph,
  .calendar-day-events .calendar-event-text,
  .calendar-day-events .calendar-event-text-input,
  .calendar-day-events .calendar-event-del {
    display: none;
  }

  .calendar-day-more {
    font-size: 9.5px; font-weight: 700; padding: 0; background: transparent; color: var(--accent);
    text-decoration: none;
  }
  .calendar-day-view {
    font-size: 11px; top: 2px; right: 2px; width: 22px; height: 22px; opacity: 0.75;
    background: var(--panel); border-radius: 50%;
  }

  /* With no event text to lay out, the cell can be shorter without
     feeling tight — a calmer grid that still leaves every date and its
     dots easy to read and tap. */
  .calendar-day { height: 76px; padding: 6px 5px 5px; gap: 4px; }
}

@media (max-width: 380px) {
  .calendar-day { height: 68px; }
}

/* ---- v9: event/task notes + reminders ---- */
.field textarea {
  font: inherit; font-size: 14px; color: var(--text); background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 9px 10px; resize: vertical; min-height: 64px;
}
.field-hint { font-size: 11.5px; color: var(--muted); }
.modal-foot { gap: 10px; }
.danger-btn { color: var(--danger); margin-right: auto; }
.danger-btn:hover { border-color: var(--danger); }
.calendar-event-wrap { display: flex; flex-direction: column; gap: 2px; }
.calendar-event-note {
  margin: 0 0 4px 30px; font-size: 12px; line-height: 1.4; color: var(--muted);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.calendar-event-edit {
  flex-shrink: 0; border: none; background: transparent; color: var(--muted); cursor: pointer;
  font-size: 14px; line-height: 1; padding: 4px 6px; border-radius: var(--radius-sm);
}
.calendar-event-edit:hover, .calendar-event-edit:focus-visible { color: var(--text); background: var(--panel-2); }
.calendar-event-note-mark { flex-shrink: 0; font-size: 10px; line-height: 1; }
.detail-field.detail-note { display: flex; flex-direction: column; align-items: stretch; gap: 4px; margin-top: 10px; }
.task-note-input {
  font: inherit; font-size: 13px; color: var(--text); background: var(--panel-2); width: 100%; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 7px 9px; resize: vertical; min-height: 44px;
}
.remind-at-input { min-width: 0; }
.link-btn { border: none; background: none; color: var(--accent); font: inherit; font-size: 12px; cursor: pointer; padding: 4px; }
.note-badge, .remind-badge { font-size: 11px; }
.today-row-note {
  flex: 0 1 auto; min-width: 0; max-width: 40%; font-size: 12px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
@media (max-width: 860px) { .today-row-note { max-width: 35%; } }
@media (max-width: 600px) {
  /* Grid chips are bare color dots on a phone — no room for the 📝 mark;
     notes show in the day popup and the agenda instead. */
  .calendar-grid .calendar-event-note-mark { display: none; }
  /* Keep Month/Agenda, ⋯, + Event and Today on one row at phone width. */
  .calendar-toolbar-right { gap: 6px; }
  .calendar-toolbar-right .calendar-mode-btn { padding-left: 10px; padding-right: 10px; }
  .calendar-toolbar-right .calendar-menu-btn { padding: 7px 10px; }
  .calendar-toolbar-right .calendar-add-event-btn { padding: 8px 11px; }
  .calendar-toolbar-right > :last-child { padding-left: 11px; padding-right: 11px; }
}
.task-details .detail-row + .detail-row { margin-top: 10px; }
.reminder-push { margin: 14px 0 6px; padding-top: 12px; border-top: 1px dashed var(--border); }
.reminder-push[hidden] { display: none; }
.reminder-push-title { margin: 0 0 6px; font-size: 12px; font-weight: 700; color: var(--text); }
.reminders-push-status { margin-top: 2px; }
.reminders-push-status.err { color: var(--danger); }
