/* =============================================================
   Family Calendar — design system
   ============================================================= */

/* Family Calendar palette — one muted indigo accent on cool slate neutrals.
   The whole grid is built from a small set of tokens so cell backgrounds,
   borders, hover, and "today" all read as one coherent surface. Tag colors
   come from the user-controlled palette and ride on top; the chrome stays
   quiet so it doesn't fight them. */
:root {
  color-scheme: light;
  /* Surfaces — cool, near-neutral slate. No warm cream. */
  --bg: #f5f6f8;          /* app background */
  --bg-elev: #ffffff;     /* cells, cards, modals */
  --bg-soft: #eef0f4;     /* inputs, recessed surfaces */
  --bg-hover: #e6e9ef;    /* cell + button hover */
  --line: #e3e6ec;        /* hairline dividers / grid gaps */
  --line-strong: #c9cfd9; /* stronger borders */
  /* Text — slate, high-contrast over white. */
  --text: #1a1f2e;
  --text-soft: #4a5266;
  --text-mute: #7a8295;
  /* Accent — a single muted indigo. Used for today, focus, links, and
     primary fills. Selected ring shares this hue so the calendar doesn't
     advertise two different "active" colors. */
  --primary: #4f5dc8;
  --primary-hover: #404eb5;
  --primary-soft: #e7eaff;
  --primary-tint: rgba(79, 93, 200, .10);
  /* Filled bg with white text on top (buttons, today circle, chat user bubble).
     Slightly darker than --primary to keep WCAG-AA on white. */
  --primary-fill: #404eb5;
  --on-primary: #ffffff;
  /* Secondary accent — used very sparingly (gradients, a couple of brand
     surfaces). A cooler slate-blue, not a competing hue. */
  --accent: #7c89e8;
  --accent-soft: #e7eaff;
  --success: #15a36b;
  --warn: #d97706;
  --danger: #dc2626;
  --danger-soft: #fde8e8;
  --coral: #e85a72;
  --indigo-soft: #c7d2fe;
  --today-ring: #4f5dc8;
  --selected-ring: #4f5dc8;
  --focus-ring: rgba(79, 93, 200, .35);
  --primary-gradient: linear-gradient(135deg, #4f5dc8 0%, #7c89e8 100%);
  --primary-glow: 0 8px 24px rgba(79, 93, 200, .22), 0 2px 6px rgba(79, 93, 200, .12);
  --shadow-sm: 0 1px 2px rgba(20, 28, 50, .05), 0 1px 1px rgba(20, 28, 50, .03);
  --shadow-md: 0 8px 24px rgba(20, 28, 50, .08), 0 2px 6px rgba(20, 28, 50, .05);
  --shadow-lg: 0 24px 60px rgba(20, 28, 50, .16), 0 6px 16px rgba(20, 28, 50, .08);
  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --radius-xl: 28px;
  --holiday: #b91c1c;
}

[data-theme="dark"] {
  color-scheme: dark;
  /* Deep cool slate, not violet-black. */
  --bg: #0f1320;
  --bg-elev: #181d2c;
  --bg-soft: #131826;
  --bg-hover: #232a3d;
  --line: #262c3d;
  --line-strong: #3a4257;
  --text: #eef1f8;
  --text-soft: #b8c0d3;
  --text-mute: #7c8499;
  /* Brighter indigo for accent text on dark surfaces (AA on --bg-elev). */
  --primary: #8b97e6;
  --primary-hover: #a5afee;
  --primary-soft: #232a52;
  --primary-tint: rgba(139, 151, 230, .16);
  /* Filled bg + white text. Slightly darker so white stays AA-readable. */
  --primary-fill: #4f5dc8;
  --on-primary: #ffffff;
  --accent: #6f7cd8;
  --accent-soft: #1c2244;
  --success: #34d399;
  --warn: #fbbf24;
  --danger: #fb7185;
  --danger-soft: #3a1a24;
  --coral: #fda4af;
  --indigo-soft: #4f46e5;
  --today-ring: #8b97e6;
  --selected-ring: #8b97e6;
  --focus-ring: rgba(139, 151, 230, .45);
  --primary-gradient: linear-gradient(135deg, #8b97e6 0%, #6f7cd8 100%);
  --primary-glow: 0 10px 30px rgba(139, 151, 230, .26), 0 2px 8px rgba(111, 124, 216, .18);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-md: 0 10px 30px rgba(0, 0, 0, .45), 0 2px 6px rgba(0, 0, 0, .30);
  --shadow-lg: 0 28px 80px rgba(0, 0, 0, .60), 0 8px 20px rgba(0, 0, 0, .40);
}

/* ============================ Accent color themes ============================
   Independent of light/dark — overrides only the primary-family variables so
   buttons, today ring, pills, and focus glow take on the chosen hue.
   Indigo is the default (already set above); the others kick in via [data-accent].
*/
[data-accent="rose"] {
  --primary: #e11d48;
  --primary-hover: #be123c;
  --primary-soft: #ffe4e6;
  --primary-tint: rgba(225, 29, 72, .10);
  --primary-fill: #e11d48;
  --today-ring: #e11d48;
  --focus-ring: rgba(225, 29, 72, .35);
}
[data-theme="dark"][data-accent="rose"] {
  --primary: #fb7185;
  --primary-hover: #fda4af;
  --primary-soft: #3a1424;
  --primary-tint: rgba(251, 113, 133, .14);
  --primary-fill: #be123c;
  --today-ring: #fda4af;
  --focus-ring: rgba(251, 113, 133, .45);
}

[data-accent="emerald"] {
  --primary: #059669;
  --primary-hover: #047857;
  --primary-soft: #d1fae5;
  --primary-tint: rgba(5, 150, 105, .10);
  --primary-fill: #059669;
  --today-ring: #059669;
  --focus-ring: rgba(5, 150, 105, .35);
}
[data-theme="dark"][data-accent="emerald"] {
  --primary: #34d399;
  --primary-hover: #6ee7b7;
  --primary-soft: #08321f;
  --primary-tint: rgba(52, 211, 153, .14);
  --primary-fill: #047857;
  --today-ring: #6ee7b7;
  --focus-ring: rgba(52, 211, 153, .45);
}

[data-accent="amber"] {
  --primary: #d97706;
  --primary-hover: #b45309;
  --primary-soft: #fef3c7;
  --primary-tint: rgba(217, 119, 6, .10);
  --primary-fill: #d97706;
  --today-ring: #d97706;
  --focus-ring: rgba(217, 119, 6, .35);
}
[data-theme="dark"][data-accent="amber"] {
  --primary: #fbbf24;
  --primary-hover: #fcd34d;
  --primary-soft: #3a2812;
  --primary-tint: rgba(251, 191, 36, .14);
  --primary-fill: #b45309;
  --today-ring: #fcd34d;
  --focus-ring: rgba(251, 191, 36, .45);
}

[data-accent="sky"] {
  --primary: #0284c7;
  --primary-hover: #0369a1;
  --primary-soft: #e0f2fe;
  --primary-tint: rgba(2, 132, 199, .10);
  --primary-fill: #0284c7;
  --today-ring: #0284c7;
  --focus-ring: rgba(2, 132, 199, .35);
}
[data-theme="dark"][data-accent="sky"] {
  --primary: #38bdf8;
  --primary-hover: #7dd3fc;
  --primary-soft: #0c2438;
  --primary-tint: rgba(56, 189, 248, .14);
  --primary-fill: #0369a1;
  --today-ring: #7dd3fc;
  --focus-ring: rgba(56, 189, 248, .45);
}

[data-accent="violet"] {
  --primary: #7c3aed;
  --primary-hover: #6d28d9;
  --primary-soft: #ede9fe;
  --primary-tint: rgba(124, 58, 237, .10);
  --primary-fill: #7c3aed;
  --today-ring: #7c3aed;
  --focus-ring: rgba(124, 58, 237, .35);
}
[data-theme="dark"][data-accent="violet"] {
  --primary: #a78bfa;
  --primary-hover: #c4b5fd;
  --primary-soft: #2a1d52;
  --primary-tint: rgba(167, 139, 250, .14);
  --primary-fill: #6d28d9;
  --today-ring: #c4b5fd;
  --focus-ring: rgba(167, 139, 250, .45);
}

[data-accent="red"] {
  --primary: #dc2626;
  --primary-hover: #b91c1c;
  --primary-soft: #fee2e2;
  --primary-tint: rgba(220, 38, 38, .10);
  --primary-fill: #dc2626;
  --today-ring: #dc2626;
  --focus-ring: rgba(220, 38, 38, .35);
}
[data-theme="dark"][data-accent="red"] {
  --primary: #f87171;
  --primary-hover: #fca5a5;
  --primary-soft: #3a1212;
  --primary-tint: rgba(248, 113, 113, .14);
  --primary-fill: #b91c1c;
  --today-ring: #fca5a5;
  --focus-ring: rgba(248, 113, 113, .45);
}

[data-accent="orange"] {
  --primary: #ea580c;
  --primary-hover: #c2410c;
  --primary-soft: #ffedd5;
  --primary-tint: rgba(234, 88, 12, .10);
  --primary-fill: #ea580c;
  --today-ring: #ea580c;
  --focus-ring: rgba(234, 88, 12, .35);
}
[data-theme="dark"][data-accent="orange"] {
  --primary: #fb923c;
  --primary-hover: #fdba74;
  --primary-soft: #3a1d0a;
  --primary-tint: rgba(251, 146, 60, .14);
  --primary-fill: #c2410c;
  --today-ring: #fdba74;
  --focus-ring: rgba(251, 146, 60, .45);
}

[data-accent="lime"] {
  --primary: #65a30d;
  --primary-hover: #4d7c0f;
  --primary-soft: #ecfccb;
  --primary-tint: rgba(101, 163, 13, .10);
  --primary-fill: #65a30d;
  --today-ring: #65a30d;
  --focus-ring: rgba(101, 163, 13, .35);
}
[data-theme="dark"][data-accent="lime"] {
  --primary: #a3e635;
  --primary-hover: #bef264;
  --primary-soft: #1e2c0a;
  --primary-tint: rgba(163, 230, 53, .14);
  --primary-fill: #4d7c0f;
  --today-ring: #bef264;
  --focus-ring: rgba(163, 230, 53, .45);
}

[data-accent="teal"] {
  --primary: #0d9488;
  --primary-hover: #0f766e;
  --primary-soft: #ccfbf1;
  --primary-tint: rgba(13, 148, 136, .10);
  --primary-fill: #0d9488;
  --today-ring: #0d9488;
  --focus-ring: rgba(13, 148, 136, .35);
}
[data-theme="dark"][data-accent="teal"] {
  --primary: #2dd4bf;
  --primary-hover: #5eead4;
  --primary-soft: #082f2c;
  --primary-tint: rgba(45, 212, 191, .14);
  --primary-fill: #0f766e;
  --today-ring: #5eead4;
  --focus-ring: rgba(45, 212, 191, .45);
}

[data-accent="fuchsia"] {
  --primary: #c026d3;
  --primary-hover: #a21caf;
  --primary-soft: #fae8ff;
  --primary-tint: rgba(192, 38, 211, .10);
  --primary-fill: #c026d3;
  --today-ring: #c026d3;
  --focus-ring: rgba(192, 38, 211, .35);
}
[data-theme="dark"][data-accent="fuchsia"] {
  --primary: #e879f9;
  --primary-hover: #f0abfc;
  --primary-soft: #3a1240;
  --primary-tint: rgba(232, 121, 249, .14);
  --primary-fill: #a21caf;
  --today-ring: #f0abfc;
  --focus-ring: rgba(232, 121, 249, .45);
}

[data-accent="slate"] {
  --primary: #475569;
  --primary-hover: #334155;
  --primary-soft: #f1f5f9;
  --primary-tint: rgba(71, 85, 105, .10);
  --primary-fill: #475569;
  --today-ring: #475569;
  --focus-ring: rgba(71, 85, 105, .35);
}
[data-theme="dark"][data-accent="slate"] {
  --primary: #94a3b8;
  --primary-hover: #cbd5e1;
  --primary-soft: #1e293b;
  --primary-tint: rgba(148, 163, 184, .14);
  --primary-fill: #334155;
  --today-ring: #cbd5e1;
  --focus-ring: rgba(148, 163, 184, .45);
}

/* Accent swatch picker (Settings modal) */
.accent-grid {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 2px;
}
.accent-swatch {
  width: 34px; height: 34px;
  border-radius: 10px;
  border: 2px solid var(--line);
  padding: 0;
  background: var(--swatch, var(--primary));
  cursor: pointer;
  position: relative;
  transition: transform .08s, border-color .12s, box-shadow .12s;
}
.accent-swatch:hover { transform: scale(1.06); border-color: var(--line-strong); }
.accent-swatch.active {
  border-color: var(--text);
  box-shadow: 0 0 0 2px var(--bg-elev) inset;
}
.accent-swatch.active::after {
  content: "";
  position: absolute; left: 50%; top: 50%;
  width: 6px; height: 11px;
  border: solid #fff; border-width: 0 2px 2px 0;
  transform: translate(-50%, -65%) rotate(45deg);
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.35));
}

* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0; height: 100%; overflow: hidden;
  /* Kill the grey flash iOS Safari paints over tapped buttons/links — it
     reads as laggy and unpolished. Inherited, so this covers everything. */
  -webkit-tap-highlight-color: transparent;
}
/* Keep over-scroll inside the calendar's own scroll regions so a rubber-band
   at the top/bottom on iOS doesn't trigger the browser's back/forward swipe. */
.cal-panel, .card, .dv-scroll, .week-time-view, .year-view { overscroll-behavior: contain; }

/* The HTML `hidden` attribute must always win over our explicit display rules
   (.modal, .toast, .nlp-preview etc. set display:flex/grid which would otherwise
   beat the UA `[hidden] { display: none }` rule and leave modals stacked). */
[hidden] { display: none !important; }
body {
  background:
    radial-gradient(1100px 600px at 110% -10%, rgba(79, 93, 200, .06), transparent 60%),
    radial-gradient(900px 500px at -10% 110%, rgba(79, 93, 200, .04), transparent 60%),
    var(--bg);
  background-attachment: fixed;
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
[data-theme="dark"] body {
  background:
    radial-gradient(1100px 600px at 110% -10%, rgba(139, 151, 230, .10), transparent 60%),
    radial-gradient(900px 500px at -10% 110%, rgba(111, 124, 216, .06), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}

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

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

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Focus rings — only on keyboard nav. Outline respects each element's own
   border-radius (no global override). */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

kbd {
  display: inline-block; padding: 1px 6px; border: 1px solid var(--line-strong);
  border-bottom-width: 2px; border-radius: 6px; background: var(--bg-elev);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px;
  color: var(--text-soft);
}
code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--bg-soft); padding: 1px 5px; border-radius: 5px;
  font-size: 12px; color: var(--text-soft);
}

/* ============================ Auth gate ============================ */

.auth-gate {
  position: fixed; inset: 0; z-index: 200;
  /* A warm, inviting split: mascot on one side, form on a soft cream side. */
  color: #2b2420;
  background: linear-gradient(135deg, #fff6ef 0%, #ffeaf0 100%);
  display: grid; grid-template-columns: 1.05fr 0.95fr;
  overflow: auto;
  /* The card is an always-light design, but it lives inside #app which may
     carry data-theme="dark" (with `color-scheme: dark`). That inherited dark
     color-scheme makes the browser paint the inputs' internal + autofilled
     text light-on-cream — invisible while typing. Pin the whole gate to light
     so form controls and autofill render against the light card correctly. */
  color-scheme: light;
}
/* Mascot half */
.auth-hero {
  position: relative; display: grid; place-items: center;
  background: linear-gradient(155deg, #ff9e7d 0%, #ff6a88 52%, #c86dd7 100%);
  overflow: hidden;
}
.auth-hero::after {   /* soft vignette so the caption reads */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120% 80% at 50% 30%, transparent 40%, rgba(0,0,0,.18) 100%);
}
.auth-hero-img {
  width: min(74%, 460px); height: auto; position: relative; z-index: 1;
  border-radius: 22%;
  filter: drop-shadow(0 28px 60px rgba(60,20,30,.4));
}
.auth-hero-cap { position: absolute; left: 0; right: 0; bottom: 7%; z-index: 2; text-align: center; padding: 0 24px; color: #fff; }
.auth-hero-title { font-size: clamp(28px, 3.6vw, 46px); font-weight: 800; letter-spacing: -0.02em; text-shadow: 0 2px 16px rgba(0,0,0,.3); }
.auth-hero-sub { font-size: clamp(14px, 1.6vw, 18px); opacity: .96; margin-top: 6px; text-shadow: 0 1px 10px rgba(0,0,0,.3); }
/* Form half */
.auth-panel {
  display: grid; place-items: center;
  padding: max(24px, env(safe-area-inset-top)) 28px max(24px, env(safe-area-inset-bottom));
}
.auth-card {
  width: 100%; max-width: 400px;
  background: #ffffff;
  border: 1px solid #f1e4dc;
  border-radius: var(--radius-lg);
  box-shadow: 0 30px 70px -28px rgba(120,60,40,.35);
  padding: 30px;
  position: relative;
}
.auth-card::before { display: none; }   /* drop the old dark gradient ring */
.auth-gate .auth-brand-title { color: #2b2420; }
.auth-gate .auth-brand-tagline { color: #9c8a80; }
.auth-gate .brand-mark {
  /* Soft pink-tinted tile with the pink glyph — the base mark is a solid
     pink square with a white icon, which would render as a near-invisible
     pink-on-pink blob against the cream auth card. */
  width: 36px; height: 36px; border-radius: 10px;
  background: rgba(255, 106, 136, .12);
  color: #ff6a88;
}
.auth-gate .auth-tabs { border-bottom-color: #f1e4dc; }
.auth-gate .auth-tab { color: #b1a097; }
.auth-gate .auth-tab:hover { color: #6a5b52; }
.auth-gate .auth-tab.active { color: #2b2420; border-bottom-color: #ff6a88; }
.auth-gate .field-label { color: #8a7a71; }
.auth-gate .auth-card input {
  background: #fdf8f5; border: 1px solid #ece0d8; color: #2b2420; border-radius: 10px;
}
.auth-gate .auth-card input::placeholder { color: #c2b3aa; }
/* Chrome/Safari autofill paints its own bg + text on top of the rule above.
   Force the dark-on-cream look so signed-in email/password stay legible. */
.auth-gate .auth-card input:-webkit-autofill,
.auth-gate .auth-card input:-webkit-autofill:hover,
.auth-gate .auth-card input:-webkit-autofill:focus {
  -webkit-text-fill-color: #2b2420;
  caret-color: #2b2420;
  -webkit-box-shadow: 0 0 0 1000px #fdf8f5 inset;
          box-shadow: 0 0 0 1000px #fdf8f5 inset;
}
.auth-gate .auth-card input:focus {
  /* Keep the light background on focus — the generic `.field input:focus`
     rule later in the file otherwise sets `background: var(--bg-elev)`, which
     is dark in dark mode and turns the field black while typing. */
  background: #fff;
  color: #2b2420;
  border-color: #ff6a88; outline: none;
  box-shadow: 0 0 0 3px rgba(255,106,136,.18);
}
.auth-gate .auth-submit {
  background: linear-gradient(135deg, #ff8f6b, #ff6a88); color: #fff; border: 0;
  box-shadow: 0 10px 24px -10px rgba(255,106,136,.7);
}
.auth-gate .auth-submit:hover { filter: brightness(1.05); }
.auth-gate .auth-hint { color: #9c8a80; }
@media (max-width: 820px) {
  .auth-gate { grid-template-columns: 1fr; }
  .auth-hero { min-height: 32vh; }
  .auth-hero-img { width: min(46%, 200px); }
  .auth-hero-cap { bottom: 10px; }
  .auth-hero-title { font-size: 24px; }
}
/* Subtle decorative gradient ring above the card, anchored to the brand mark. */
.auth-card::before {
  content: "";
  position: absolute; inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--primary) 30%, transparent),
    transparent 40%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}
.auth-brand {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 20px;
}
.auth-brand-text { display: flex; flex-direction: column; gap: 2px; }
.auth-brand-title { font-size: 16px; font-weight: 700; letter-spacing: -0.015em; }
.auth-brand-tagline { font-size: 12px; color: var(--text-mute); }
.auth-tabs {
  display: flex; gap: 0;
  border-bottom: 1px solid var(--line);
  margin-bottom: 18px;
}
.auth-tab {
  flex: 1; background: none; border: 0;
  padding: 10px 0;
  font: inherit; font-size: 13px; font-weight: 600;
  color: var(--text-mute);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color .12s, border-color .12s;
}
.auth-tab:hover { color: var(--text-soft); }
.auth-tab.active { color: var(--text); border-bottom-color: var(--primary); }
.auth-form .field { margin-bottom: 12px; }
.auth-error {
  background: var(--danger-soft); color: var(--danger);
  border-radius: 8px; padding: 8px 12px;
  font-size: 12px; font-weight: 600;
  margin-bottom: 12px;
}
.auth-submit { width: 100%; justify-content: center; padding: 10px 14px; min-height: 40px; }
.auth-hint {
  margin: 14px 0 0;
  font-size: 12px; color: var(--text-mute);
  text-align: center;
}

/* Settings additions */
.settings-section-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); font-weight: 700;
  margin: 16px 0 10px;
  padding-top: 4px;
  border-top: 1px solid var(--line);
}
/* First section in a form doesn't need a top divider. */
.modal-body > .settings-section-label:first-child,
form > .settings-section-label:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.settings-section-label + .field { margin-top: 0; }
.field input[readonly] {
  background: var(--bg-soft); color: var(--text-soft); cursor: default;
}
.pw-pane {
  border: 1px solid var(--line); border-radius: 10px;
  padding: 4px 12px;
  margin-bottom: 14px;
}
.pw-pane > summary {
  cursor: pointer; list-style: none;
  padding: 8px 0; font-size: 12px; font-weight: 600; color: var(--text-soft);
}
.pw-pane > summary::-webkit-details-marker { display: none; }
.pw-pane > summary::before {
  content: "›"; display: inline-block; width: 14px; text-align: center;
  color: var(--text-mute); transition: transform .12s;
}
.pw-pane[open] > summary::before { transform: rotate(90deg); }
.pw-pane[open] { padding-bottom: 12px; }
.pw-status { font-size: 12px; margin-top: 6px; color: var(--text-mute); min-height: 16px; }
.pw-status.ok  { color: var(--success); }
.pw-status.err { color: var(--danger); }

/* ============================ App shell ============================ */

.app {
  /* Height-bound the shell to the visible viewport so the whole UI
     (topbar + grid + footer, plus the side drawer when open) fits in
     one screen — no body scroll. `100svh` is the small-viewport fallback
     for browsers without `dvh`; `100dvh` overrides on modern UAs and
     handles the iOS Safari address-bar collapse without re-layout. */
  height: 100svh;
  height: 100dvh;
  overflow: hidden;
  /* Flexbox so the main scene (calendar / settings / dev) gets the
     remaining vertical space cleanly. Grid here misbehaves when the
     hidden mobile-tabs / hidden alt-scenes shift remaining items into
     the wrong template row, and the footer ends up as 1fr. */
  display: flex;
  flex-direction: column;
  /* Full-bleed: no max-width, no horizontal padding. The Gmail-style
     topbar + flush calendar grid want to stretch edge-to-edge. */
  margin: 0;
  padding: 0;
  padding-bottom: env(safe-area-inset-bottom);
  gap: 0;
  /* The data-theme attribute lives on .app, so CSS variables only get
     redefined inside it. Set bg here so the page doesn't leak the
     body's light bg in dark mode (notably visible behind the Settings
     and Developer scenes, which don't paint their own backgrounds). */
  background: var(--bg);
  color: var(--text);
}
.app > .topbar,
.app > .mobile-tabs,
.app > .focusbar,
.app > .footer { flex: none; }
.app > .layout,
.app > .app-view { flex: 1; min-height: 0; }

/* ============================ Top bar ============================ */

/* Compact, two-cluster row: month nav on the left, view switcher +
   actions on the right. Thin border underneath separates it from the
   calendar grid (no shadow — keeps things flat and quiet). */
.topbar {
  position: relative;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: 8px 16px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  min-height: 56px;
}

/* ---------- Phone overflow ("More") menu ----------
   #moreBtn is hidden on desktop (all icons fit) and revealed in the ≤880px
   block, where the secondary topbar icons fold into #moreMenu. The
   `.topbar .topbar-more-btn` specificity (0,2,0) beats `.iconbtn` so the
   display toggle wins regardless of source order. */
.topbar .topbar-more-btn { display: none; }
.topbar-more-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 8px;
  z-index: 60;
  min-width: 220px;
  padding: 6px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: var(--radius-md, 14px);
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; gap: 2px;
  animation: pop .14s ease;
  /* The menu now carries the view switcher + every folded action, so it can
     out-grow a phone screen — cap it to the viewport and scroll inside. */
  max-height: calc(100vh - 70px);
  max-height: calc(100dvh - 70px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.topbar-more-menu[hidden] { display: none; }
.more-item {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 11px 12px;
  border: 0; border-radius: 10px;
  background: transparent;
  color: var(--text);
  font: inherit; font-size: 15px; font-weight: 500;
  text-align: left;
  cursor: pointer;
  min-height: 44px;
}
.more-item:hover, .more-item:focus-visible { background: var(--bg-hover); outline: none; }
.more-item svg { color: var(--text-soft); flex-shrink: 0; }
/* Active view row (the More menu doubles as the phone view switcher). */
.more-item.active { background: var(--primary-fill); color: var(--on-primary); }
.more-item.active svg { color: currentColor; }
/* Section label + divider that group the menu (View · actions · extras). */
.more-section-label {
  padding: 6px 12px 2px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--text-mute);
}
.more-divider { height: 1px; margin: 5px 6px; background: var(--line); }
.topbar-left {
  display: flex; align-items: center; gap: 10px;
  min-width: 0; flex: 1;
}
.topbar-right {
  display: flex; align-items: center; gap: 4px;
  flex-shrink: 0;
}
.brand-mark {
  width: 30px; height: 30px; border-radius: 8px;
  background: var(--primary);
  color: white; display: grid; place-items: center;
  flex-shrink: 0;
  /* Button reset — it's a real <button> now (clicking returns to the
     calendar scene). */
  border: 0; padding: 0; cursor: pointer;
  transition: filter .12s ease, transform .05s ease;
}
.brand-mark:hover { filter: brightness(1.08) saturate(1.05); }
.brand-mark:active { transform: translateY(1px); }
.brand-mark:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.topbar-title {
  margin: 0 0 0 6px;
  font-size: 18px; font-weight: 600; letter-spacing: -0.015em;
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.cal-nav { display: inline-flex; align-items: center; gap: 2px; }
.nav-arrow {
  width: 32px; height: 32px;
  border: 0; background: transparent;
  color: var(--text-soft);
}
.nav-arrow:hover { background: var(--bg-hover); color: var(--text); }
.topbar-divider {
  width: 1px; height: 22px;
  background: var(--line);
  margin: 0 6px;
  flex-shrink: 0;
}
.today-btn {
  padding: 5px 14px; min-height: 32px;
  border-color: var(--line);
}
.view-seg { flex-shrink: 0; }
.view-seg .seg-btn { padding: 5px 12px; min-height: 28px; font-size: 12px; transition: background .15s ease, color .15s ease, box-shadow .15s ease; }

/* Wall-display clock sitting in the topbar — hidden by default; the
   `has-topbar-clock` body class (toggled from Settings → Appearance)
   reveals it. Suppressed on phones regardless of the setting. */
.topbar-clock {
  display: none;
  align-items: baseline; gap: 10px;
  padding: 0 4px;
  flex-shrink: 0;
  user-select: none;
}
body.has-topbar-clock .topbar-clock { display: inline-flex; }
.topbar-clock-time {
  font-size: 20px; font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.topbar-clock-date {
  font-size: 12px; font-weight: 500;
  color: var(--text-mute);
  letter-spacing: 0.01em;
  text-transform: uppercase;
  line-height: 1;
}
@media (max-width: 880px) {
  .topbar-clock,
  body.has-topbar-clock .topbar-clock { display: none !important; }
}

/* Theme picker (Settings → Appearance) — segmented control with icon + label. */
.theme-seg .seg-btn { display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; }
.theme-seg .seg-btn svg { flex-shrink: 0; }

/* ============================ Buttons ============================ */

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: 10px; border: 1px solid transparent;
  background: var(--bg-elev); color: var(--text);
  font-weight: 600; font-size: 13px; cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: background .15s ease, transform .05s ease, border-color .15s ease, color .15s ease;
  min-height: 36px;
}
.btn:hover { background: var(--bg-hover); }
.btn:active { transform: translateY(1px); }
.btn.primary {
  background: var(--primary-fill);
  color: var(--on-primary); border-color: transparent;
  box-shadow: var(--primary-glow, var(--shadow-sm));
}
.btn.primary:hover { filter: brightness(1.06) saturate(1.05); transform: translateY(-1px); }
.btn.primary:active { transform: translateY(0); }
[data-theme="dark"] .btn.primary:hover { filter: brightness(1.12) saturate(1.05); }
.btn.ghost {
  background: transparent; border-color: var(--line);
}
.btn.ghost:hover { background: var(--bg-hover); }
.btn.small { padding: 5px 10px; font-size: 12px; border-radius: 8px; min-height: 28px; }
.btn.danger {
  background: var(--danger); color: white; border-color: transparent;
}
.btn.danger:hover { filter: brightness(.93); }
.btn.danger-text { color: var(--danger); }
.btn.danger-text:hover { background: var(--danger-soft); }

.iconbtn {
  display: inline-grid; place-items: center;
  width: 32px; height: 32px;
  border-radius: 8px; border: 1px solid var(--line);
  background: var(--bg-elev); color: var(--text-soft);
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.iconbtn:hover { background: var(--bg-hover); color: var(--text); }
.iconbtn:active { transform: translateY(1px); }
.iconbtn:focus-visible { outline-offset: 1px; }

.link {
  background: none; border: 0; padding: 2px 4px; color: var(--text-soft);
  cursor: pointer; font-size: 12px; border-radius: 6px;
}
.link:hover { color: var(--text); text-decoration: underline; }

/* Segmented control */
.seg {
  display: inline-flex; background: var(--bg-soft);
  padding: 3px; border-radius: 10px; border: 1px solid var(--line);
}
.seg-btn {
  border: 0; background: transparent; color: var(--text-soft);
  padding: 6px 14px; border-radius: 7px; cursor: pointer;
  font-size: 12px; font-weight: 600;
  min-height: 30px;
}
.seg-btn.active, .seg-btn[aria-checked="true"] {
  background: var(--bg-elev); color: var(--text);
  box-shadow: var(--shadow-sm);
}

/* ============================ Mobile tabs ============================ */

.mobile-tabs { display: none; }

@media (max-width: 880px) {
  .mobile-tabs {
    display: flex;
    background: var(--bg-elev);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 3px;
    box-shadow: var(--shadow-sm);
  }
  .mtab {
    flex: 1;
    border: 0; background: transparent;
    padding: 9px 8px; border-radius: 9px;
    font-size: 13px; font-weight: 600;
    color: var(--text-soft); cursor: pointer;
    transition: background .12s, color .12s;
  }
  .mtab.active { background: var(--primary-tint); color: var(--primary); }
}

/* ======================= Mobile focus bar ======================= */

/* A bottom navigation bar (phone only) for one-thumb switching between the
   main views — Calendar / Lists / Baby / Planner — with a "More" tab for the
   long tail. It's a flex-none child of .app, so it reserves its own strip at
   the bottom and the active scene compresses to fit above it (no fixed
   positioning, no content hidden underneath). Long-press a destination tab to
   pin it as the home view (see the JS controller). */
.focusbar { display: none; }

@media (max-width: 880px) {
  .focusbar {
    display: flex;
    align-items: stretch;
    gap: 2px;
    padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--bg-elev) 94%, transparent);
    border-top: 1px solid var(--line);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    /* Sit above the calendar grid but below the modal layer (z 200) so
       full-screen pages and dialogs cover it. */
    z-index: 55;
  }
  .focus-tab {
    position: relative;
    isolation: isolate;   /* local stacking context for the active pill */
    flex: 1;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 3px;
    min-height: 52px;
    padding: 6px 2px;
    border: 0; border-radius: 12px;
    background: transparent;
    color: var(--text-mute);
    font: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color .14s ease, background .14s ease, transform .06s ease;
  }
  .focus-tab svg { width: 22px; height: 22px; position: relative; z-index: 1; }
  .focus-label {
    position: relative; z-index: 1;
    font-size: 11px; font-weight: 600; letter-spacing: -0.01em;
    line-height: 1;
  }
  .focus-tab:active { transform: scale(.94); }
  .focus-tab.active { color: var(--primary); }
  .focus-tab.active svg { color: var(--primary); }
  /* Filled pill behind the active tab's icon for a clear, modern selected
     state (mirrors Material 3 / iOS tab bars). */
  .focus-tab.active::before {
    content: "";
    position: absolute;
    top: 4px; left: 50%;
    transform: translateX(-50%);
    width: 46px; height: 26px;
    border-radius: 13px;
    background: var(--primary-tint);
    z-index: 0;
  }
  /* Home pin — a small dot above the icon marks the tab that the app opens
     to on launch. */
  .focus-tab.is-home::after {
    content: "";
    position: absolute;
    top: 6px; right: 50%;
    transform: translateX(15px);
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--primary);
    box-shadow: 0 0 0 2px var(--bg-elev);
  }
  .focus-tab:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }

  /* Hide the bar on the settings / dev takeovers — those are full-screen
     utility scenes with their own back/close chrome. */
  body[data-scene="settings"] .focusbar,
  body[data-scene="dev"] .focusbar { display: none; }
}

/* ===================== "More" focus sheet ====================== */

/* A bottom sheet (phone only) launched from the focus bar's "More" tab. Lists
   every capability as a tile grid; tap to switch, tap the star to pin a home
   view. Slides up over the app; a scrim dims what's behind. */
.focus-sheet, .focus-sheet-backdrop { display: none; }

@media (max-width: 880px) {
  .focus-sheet-backdrop {
    display: block;
    position: fixed; inset: 0;
    z-index: 110;
    background: rgba(0, 0, 0, .45);
    opacity: 0;
    transition: opacity .2s ease;
  }
  .focus-sheet-backdrop.open { opacity: 1; }
  .focus-sheet-backdrop[hidden] { display: none; }

  .focus-sheet {
    display: flex; flex-direction: column;
    position: fixed; left: 0; right: 0; bottom: 0;
    z-index: 120;
    max-height: 82vh;
    padding: 6px 14px calc(18px + env(safe-area-inset-bottom));
    background: var(--bg-elev);
    border-top-left-radius: 20px;
    border-top-right-radius: 20px;
    box-shadow: 0 -12px 40px rgba(0, 0, 0, .28);
    transform: translateY(100%);
    transition: transform .24s cubic-bezier(.32, .72, 0, 1);
    overscroll-behavior: contain;
  }
  .focus-sheet.open { transform: translateY(0); }
  .focus-sheet[hidden] { display: none; }

  .focus-sheet-grip {
    width: 40px; height: 4px;
    margin: 8px auto 4px;
    border-radius: 2px;
    background: var(--line);
    flex: none;
  }
  .focus-sheet-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 2px 2px 10px;
    flex: none;
  }
  .focus-sheet-title {
    margin: 0;
    font-size: 17px; font-weight: 700; letter-spacing: -0.02em;
    color: var(--text);
  }
  .focus-sheet-close {
    width: 34px; height: 34px;
    border: 0; border-radius: 50%;
    background: var(--bg-hover);
    color: var(--text-soft);
    font-size: 22px; line-height: 1;
    cursor: pointer;
  }
  .focus-sheet-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 2px;
  }
  .fs-tile {
    position: relative;
    border-radius: 16px;
    background: var(--bg);
    border: 1px solid var(--line);
    transition: border-color .12s ease, background .12s ease;
  }
  .fs-tile.active {
    border-color: color-mix(in srgb, var(--primary) 55%, transparent);
    background: var(--primary-tint);
  }
  .fs-go {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 92px;
    padding: 14px 6px;
    border: 0; border-radius: 16px;
    background: transparent;
    color: var(--text);
    font: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .fs-go:active { transform: scale(.96); }
  .fs-icon {
    display: grid; place-items: center;
    width: 44px; height: 44px;
    border-radius: 12px;
    background: var(--bg-elev);
    color: var(--primary);
    box-shadow: var(--shadow-sm);
  }
  .fs-tile.active .fs-icon { background: var(--bg-elev); }
  .fs-label {
    font-size: 12px; font-weight: 600; letter-spacing: -0.01em;
    line-height: 1.2; text-align: center;
    color: var(--text-soft);
  }
  .fs-tile.active .fs-label { color: var(--primary); }
  /* Home star — top-right corner of the tile. */
  .fs-star {
    position: absolute; top: 5px; right: 5px;
    display: grid; place-items: center;
    width: 28px; height: 28px;
    border: 0; border-radius: 50%;
    background: transparent;
    color: var(--text-mute);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .fs-star.on { color: var(--primary); }
  .fs-star:active { transform: scale(.9); }
  .focus-sheet-hint {
    margin: 12px 2px 0;
    font-size: 12px; color: var(--text-mute);
    text-align: center;
    flex: none;
  }
  .focus-sheet-star { color: var(--primary); }
}

/* ============================ Layout ============================ */

/* Desktop: the calendar takes the full width of the layout. The side
   panel (day detail + milestones + insights) lives in a slide-in drawer
   on the right, toggled by #sideToggleBtn in the topbar. Default state
   is closed so the calendar gets the whole page; the open state is
   persisted to localStorage so it sticks across reloads. */
.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-auto-rows: 1fr;
  gap: 0;
  align-items: stretch;
  min-height: 0;
  /* Stretch the calendar grid to fill the viewport between the topbar
     and the footer (mirrors Google Calendar's full-bleed grid). */
  height: 100%;
}

/* Active state on the topbar toggle button when the drawer is open. */
.app[data-side-open="true"] .side-toggle-btn {
  background: var(--primary-tint);
  color: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 30%, transparent);
}

@media (max-width: 880px) {
  /* Cap the app to the visible viewport so the month grid fits without
     body scroll. `min-height: 100dvh` (the desktop rule) lets the grid's
     intrinsic height push the app taller than the screen on phones —
     here we want a hard cap and let the flex children compress. */
  .app { height: 100dvh; min-height: 0; overflow: hidden; }
  html, body { overflow: hidden; }

  .layout { grid-template-columns: 1fr; gap: 0; height: 100%; min-height: 0; }
  .side { display: contents; }
  /* Mobile: tab-controlled visibility */
  [data-pane] { display: none; }
  [data-pane].pane-active { display: flex; flex-direction: column; }
  /* Calendar pane keeps the flex column from the desktop rule so the grid
     stretches to fill the available height under the topbar + tabs. */
  .cal-panel[data-pane].pane-active { display: flex; flex-direction: column; }
  .layout > .side > .card { margin-top: 0; }

  /* On phones the topbar wraps to fit; the day/milestone panes get their
     own .card padding back. */
  .card { padding: 12px; border-radius: 12px; margin: 8px 10px; }

  /* Sticky mobile tabs so switching panes stays one-thumb. */
  .mobile-tabs {
    position: sticky;
    top: 0;
    z-index: 50;
    backdrop-filter: blur(6px);
    background: color-mix(in srgb, var(--bg-elev) 92%, transparent);
  }

  /* Mobile topbar: tighter, drop the view switcher (Month/Week/Year is
     a desktop affordance — phones almost always want the month grid),
     drop the brand mark to claw back space, and hide the less-essential
     icons (chat / share / dev) since the title needs room and those
     actions stay reachable via Settings → … and the command palette. */
  .topbar { gap: 6px; padding: 4px 10px; min-height: 44px; }
  .brand-mark { display: none; }
  .view-seg, .topbar-divider { display: none; }
  .topbar #chatBtn,
  .topbar #shareBtn { display: none; }
  .topbar-title {
    font-size: 15px;
    min-width: 0; flex: 1;
  }
  .today-btn { padding: 4px 10px; min-height: 30px; }
  .topbar-right { gap: 2px; }

  /* Calendar cells stay legible at narrow widths. The previous
     `minmax(70px, 1fr)` floor forced 6×70 = 420px minimum which
     overflowed small phones; `minmax(0, 1fr)` lets rows distribute
     the available height evenly so the whole month fits on one screen. */
  .grid { grid-auto-rows: minmax(0, 1fr); gap: 3px; padding: 6px; }
  .cell { padding: 8px 6px; gap: 4px; }
  .pill { font-size: 12px; padding: 2px 6px; line-height: 1.25; }
  .weekdays > div { padding: 6px 8px; font-size: 10px; }
  /* Smaller today-circle so the day-num row doesn't dominate squat cells. */
  .cell.today .day-num { width: 22px; height: 22px; font-size: 12px; }
  .day-num { font-size: 13px; }
  /* Tighter inset on phones — the 10px desktop margin eats too much. */
  .cal-panel { margin: 4px; border-radius: var(--radius-md); }
  /* Compact footer on phones — sync state is nice-to-have, not worth a row. */
  .footer { padding: 3px 10px; font-size: 10px; }

  /* Day card sections: stack icon over label on narrow widths. */
  .day-sec-tab { padding: 6px 6px; gap: 4px; }
  .day-sec-label { font-size: 11px; }

  /* Insights: 2x2 mini-grid on phones — 4-in-a-row gets too cramped. */
  .ins-stats { grid-template-columns: repeat(2, 1fr); }
  .ins-stat { border-right: 0; border-bottom: 1px solid var(--line); padding: 4px 0; }
  .ins-stat:nth-last-child(-n+2) { border-bottom: 0; }
  .ins-stat:nth-child(2n) { border-left: 1px solid var(--line); }
  .ins-mood-spark { display: none; }  /* spark fights for space on narrow */

  /* Attachment thumbs slightly smaller on phones. */
  .att-thumb { width: 48px; height: 48px; }

  .year-view { padding: 10px; }
  .year-months-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .ym-card { padding: 8px 8px 10px; }
  .ym-head { font-size: 12px; }
  .ym-dow > span, .ym-day { font-size: 10px; }
  .ym-day { min-height: 22px; }
}

@media (max-width: 480px) {
  /* On really narrow phones, hide section labels and just show icons. */
  .day-sec-label { display: none; }
  .day-sec-tab { gap: 0; padding: 6px; }
  /* Bigger touch targets for the entry toolbar — iOS HIG ~44pt is the goal;
     38/42 is a tasteful compromise that keeps the toolbar compact. */
  .tool-btn { width: 38px; height: 38px; }
  .entry-add-btn { width: 42px; height: 42px; }
  /* Bigger topbar icon buttons on small phones too. */
  .topbar .iconbtn { width: 36px; height: 36px; }
  /* Modal padding tighter on tiny screens */
  .modal-body { padding: 14px; }
  .modal-head { padding: 12px 14px; }
}

/* ============================ Calendar ============================ */

/* Rounded card — the topbar still acts as the calendar's frame, but the
   grid is now inset slightly with rounded outer corners so the month
   reads as a contained surface rather than a full-bleed sheet. */
.cal-panel {
  background: var(--bg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
  margin: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}

/* View-switch transition — views toggle the [hidden] attribute (display:none),
   so an opacity transition can't animate the swap. Instead each view body runs
   a short fade+rise keyframe the moment it becomes visible. Globally disabled
   by the prefers-reduced-motion block above. */
@keyframes viewFadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.grid:not([hidden]),
.year-view:not([hidden]),
.week-time-view:not([hidden]),
.day-view:not([hidden]) {
  animation: viewFadeIn .22s ease-out;
}

.weekdays {
  display: grid; grid-template-columns: repeat(7, 1fr);
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.weekdays > div {
  padding: 10px 12px;
  font-size: 12px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); font-weight: 700;
  text-align: center;
}
.weekdays > div.today-col {
  color: var(--primary);
}

.grid {
  display: grid; grid-template-columns: repeat(7, 1fr);
  grid-auto-rows: minmax(0, 1fr);
  background: transparent;
  gap: 10px;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  padding: 10px;
}

.cell {
  background: var(--bg-elev);
  padding: 12px 10px;
  display: flex; flex-direction: column; gap: 4px;
  cursor: pointer; position: relative;
  transition: background .12s ease, box-shadow .12s ease;
  min-height: 0; min-width: 0;
  overflow: hidden;
  border-radius: var(--radius-sm);
}
.cell:hover { background: var(--bg-hover); box-shadow: var(--shadow-sm); }
.cell.out { background: var(--bg-soft); }
.cell.out:hover { background: var(--bg-soft); filter: brightness(0.98); }
.cell.out .day-num { color: var(--text-mute); }
/* Empty cell hint — shows on hover when no events present */
.cell:not(.out):not(:has(.pill)):hover::after {
  content: "+ Add";
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: var(--text-mute); font-weight: 500;
  opacity: 0.6;
  pointer-events: none;
}
/* Fixed-size circle for today's date — same shape for 1 through 31. */
.cell.today .day-num {
  background: var(--primary-fill); color: var(--on-primary);
  width: 26px; height: 26px;
  display: inline-grid; place-items: center;
  border-radius: 50%; font-weight: 700;
  font-size: 13px;
  padding: 0;
  font-variant-numeric: tabular-nums;
  box-shadow: var(--primary-glow, var(--shadow-sm));
}
/* Gentle one-shot feedback when a day is selected — the ring eases in
   rather than snapping. Loops once, so it never becomes a distraction. */
@keyframes selectRingIn {
  from { box-shadow: inset 0 0 0 2px transparent; }
  to   { box-shadow: inset 0 0 0 2px var(--selected-ring); }
}
.cell.selected {
  box-shadow: inset 0 0 0 2px var(--selected-ring);
  z-index: 1;
  background: color-mix(in srgb, var(--selected-ring) 6%, var(--bg-elev));
  animation: selectRingIn .2s ease-out;
}
/* When today is also selected, the inset ring still appears; the indigo
   day-num circle remains the "today" anchor. No special override needed. */
/* Weekend tint — a hair cooler than the weekday cells, no accent hue.
   The effect should read as "these days are slightly recessed", not
   "these days are highlighted". */
.cell.weekend:not(.out) {
  background: color-mix(in srgb, var(--bg-elev) 70%, var(--bg-soft) 30%);
}
[data-theme="dark"] .cell.weekend:not(.out) {
  background: color-mix(in srgb, var(--bg-elev) 70%, var(--bg-soft) 30%);
}

.cell-head {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 6px;
}
.cell-head .day-num { grid-column: 2; justify-self: center; }
.cell-head .cell-head-right { grid-column: 3; justify-self: end; }
.day-num {
  font-size: 15px; font-weight: 500; color: var(--text);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.cell-count {
  font-size: 11px; color: var(--primary); font-weight: 700;
  background: var(--primary-tint);
  border-radius: 999px;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  display: inline-grid; place-items: center;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* Right-side cluster of the cell header: weather chip + count badge. */
.cell-head-right {
  display: inline-flex; align-items: center; gap: 4px;
  min-width: 0;
}

/* Schedule-pressure flag in the day-cell header. Mirrors the conflict /
   overload signal the chat agent + daily brief compute, but at a glance on
   the grid. Icon + aria-label carry the meaning; colour is reinforcement. */
.cell-flag {
  font-size: 11px; line-height: 1;
  display: inline-grid; place-items: center;
  width: 16px; height: 16px;
  border-radius: 999px;
  flex: 0 0 auto;
}
.cell-flag.is-conflict {
  color: var(--danger);
  background: var(--danger-soft);
  font-size: 10px;
}
.cell-flag.is-busy {
  color: var(--warn);
  font-size: 8px;
}
.cell-flag.is-tasks {
  color: var(--primary);
  gap: 1px;
  width: auto; min-width: 16px; padding: 0 3px;
}
.cell-flag.is-tasks .cell-flag-n {
  font-size: 9px; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;
}
@media (prefers-reduced-motion: no-preference) {
  .cell-flag.is-conflict { animation: cellFlagIn .25s ease both; }
}
@keyframes cellFlagIn {
  from { transform: scale(.4); opacity: 0; }
  to   { transform: scale(1);  opacity: 1; }
}

/* Subtle, day-cell-corner weather chip: stroke SVG icon + Hi/Lo. Sized so
   it doesn't compete with the day number or event pills. Fades in once
   the forecast resolves (the grid re-renders on data arrival). */
.wx-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; line-height: 1;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  opacity: .9;
}
.wx-chip .wx-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 13px; height: 13px;
  color: var(--text-soft);
  flex-shrink: 0;
}
.wx-chip .wx-icon svg { display: block; width: 100%; height: 100%; }
.wx-chip .wx-temps {
  font-weight: 600; font-size: 11px;
  color: var(--text);
  letter-spacing: -0.01em;
}
.wx-chip .wx-sep {
  color: var(--text-mute); font-weight: 400; opacity: .55;
  margin: 0 1px;
}
.cell.out .wx-chip { opacity: .35; }
.cell.today .wx-chip { color: var(--text); opacity: 1; }
.cell.today .wx-chip .wx-icon { color: var(--primary); }

/* On phones the cells are dense — drop the temps and keep just the icon
   so the day number stays legible. */
@media (max-width: 600px) {
  .wx-chip .wx-temps { display: none; }
  .wx-chip { gap: 0; }
}

.cell-list {
  display: flex; flex-direction: column; gap: 4px;
  overflow: hidden; min-height: 0;
}
/* Compact, uniform event chips so several fit a month cell the way mature
   calendars show them. Pills keep their full height (never compressed to
   where text clips) — reflowMonthEvents() decides how many fit and collapses
   the rest into "+N more" instead of squashing every row. */
.cell-list .pill {
  flex-shrink: 0;
  font-size: 12px;
  line-height: 1.3;
  padding: 2px 8px;
}
.pill {
  --entry-color: var(--text-mute);
  font-size: 14px; padding: 3px 8px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--entry-color) 14%, var(--bg-soft));
  color: var(--text);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  line-height: 1.5;
  display: flex; align-items: center; gap: 3px;
  transition: background .12s, color .12s, transform .08s;
}
.cell .pill:hover { background: color-mix(in srgb, var(--entry-color) 24%, var(--bg-soft)); color: var(--text); }
.pill .pill-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--entry-color);
  flex-shrink: 0;
}
.pill.milestone {
  background: var(--primary-tint);
  color: var(--primary); font-weight: 600;
  border-left-color: var(--primary);
}
.pill.job-pill {
  background: color-mix(in srgb, var(--accent, #e0457b) 15%, transparent);
  color: var(--accent, #e0457b); font-weight: 600;
  border-left-color: var(--accent, #e0457b);
}
.pill.job-pill .pill-dot { display: none; }
.pill.is-holiday { cursor: default; opacity: 0.85; }
.entry.is-holiday { cursor: default; opacity: 0.9; }
.entry.is-holiday .entry-text { cursor: default; color: var(--text-soft); }
.cell-more {
  font-size: 11px; color: var(--text-mute); padding-left: 4px;
}

/* Bottom row of the day cell — holds the weather chip so the forecast
   sits below the entries instead of competing with the day number. */
.cell-foot {
  margin-top: auto;
  display: flex; justify-content: flex-end; align-items: center;
  padding-top: 2px;
}

/* ============================ Week time grid ============================
 * Renders the visible week as a 7-column / 14-hour-row grid. The grid uses
 * percentage-positioned event blocks so the hour rows resize fluidly with
 * the viewport — the whole 14-hour window fits without scrolling. The
 * Earlier/Later toolbar pans the start hour ±2h so the user can reach the
 * full 24-hour day without ever switching to a scroll model.
 * ====================================================================== */
.week-time-view {
  display: flex; flex-direction: column;
  flex: 1; min-height: 0; min-width: 0;
  background: var(--bg);
}
.wt-toolbar {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--bg);
}
.wt-btn {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600;
  color: var(--text-soft);
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.wt-btn:hover { background: var(--bg-hover); color: var(--text); border-color: var(--text-mute); }
.wt-btn-fit { margin-left: auto; }
.wt-range {
  font-size: 11px; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}
.wt-grid {
  display: grid;
  grid-template-columns: 56px repeat(7, 1fr);
  grid-template-rows: auto auto 1fr;
  background: var(--line);
  gap: 1px;
  flex: 1; min-height: 0; min-width: 0;
  overflow: hidden;
}
.wt-corner,
.wt-allday-label,
.wt-day-head,
.wt-allday,
.wt-hours-gutter,
.wt-day-col {
  background: var(--bg-elev);
  min-width: 0;
}
.wt-corner { /* top-left blank */ }
.wt-day-head {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  cursor: pointer;
  transition: background .12s ease;
}
.wt-day-head:hover { background: var(--bg-hover); }
/* Keep the weekday name / date / weather above the rounded highlight layer. */
.wt-day-head > * { position: relative; z-index: 1; }

/* Today / selected highlight — a soft, rounded chip on the header and a
   matching rounded lane down the column, instead of a hard square ring, so
   the active day sits comfortably with the rounded pills + cells. Painted as
   an inset ::after behind the content (z-index 0); scoped off on mobile,
   which keeps its own flat tint + "Today" pill. */
.wt-day-head.selected::after,
.wt-day-col.selected::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--selected-ring) 9%, var(--bg-elev));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--selected-ring) 62%, transparent);
  pointer-events: none;
  z-index: 0;
}
.wt-day-name {
  font-size: 10px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); font-weight: 700;
}
.wt-day-num {
  font-size: 13px; font-weight: 500; color: var(--text);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.wt-day-head.today .wt-day-num {
  background: var(--primary-fill); color: var(--on-primary);
  width: 22px; height: 22px;
  display: inline-grid; place-items: center;
  border-radius: 50%; font-weight: 700;
  font-size: 11px;
}
.wt-day-head.today .wt-day-name { color: var(--primary); }
.wt-day-wx { display: inline-flex; align-items: center; }
.wt-allday-label {
  font-size: 9px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); font-weight: 700;
  padding: 4px 6px; text-align: right;
  align-self: stretch;
  display: flex; align-items: flex-start; justify-content: flex-end;
}
.wt-allday {
  display: flex; flex-direction: column; gap: 2px;
  padding: 4px 6px;
  min-height: 22px; max-height: 88px;
  overflow-y: auto;
  cursor: pointer;
}
.wt-allday:hover { background: var(--bg-hover); }
.wt-hours-gutter {
  display: flex; flex-direction: column;
  font-variant-numeric: tabular-nums;
}
.wt-hour-label {
  flex: 1 1 0;
  font-size: 10px; color: var(--text-mute); font-weight: 600;
  padding: 2px 6px 0 0;
  text-align: right;
  border-top: 1px solid transparent;
  /* Pull the label up so it sits on the corresponding hour line in the
     day columns (lines are at the row's top). */
  margin-top: -1px;
}
.wt-hour-label:first-child { margin-top: 0; }
.wt-day-col {
  position: relative;
  cursor: pointer;
  overflow: hidden;
  transition: background .12s ease;
}
.wt-day-col:hover { background: var(--bg-hover); }
.wt-day-col.weekend {
  background: color-mix(in srgb, var(--bg-elev) 96%, var(--primary) 4%);
}
[data-theme="dark"] .wt-day-col.weekend {
  background: color-mix(in srgb, var(--bg-elev) 92%, var(--primary) 8%);
}
/* The selected column's rounded highlight is the shared ::after rule above;
   keep it on its own stacking context so the lane tucks behind events. */
.wt-day-col.selected { z-index: 1; }
.wt-hourline {
  position: absolute; left: 0; right: 0;
  /* Above the rounded selected-day highlight (::after, z-index 0). */
  z-index: 1;
  border-top: 1px solid var(--line);
  pointer-events: none;
}
.wt-now-line {
  position: absolute; left: 0; right: 0;
  border-top: 2px solid var(--primary);
  z-index: 2; pointer-events: none;
}
.wt-now-dot {
  position: absolute; left: -4px; top: -5px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--primary);
}
.wt-event {
  position: absolute; left: 4px; right: 4px;
  padding: 8px 10px;
  /* Floor short blocks so a 15-minute event still shows its time + title
     legibly; taller events grow naturally with their real duration. */
  min-height: 30px;
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-md);
  background: var(--bg-soft);
  color: var(--text);
  overflow: hidden;
  font-size: 11px; line-height: 1.25;
  cursor: pointer;
  z-index: 1;
  box-shadow: 0 1px 2px rgba(0,0,0,.06);
  transition: transform .08s, box-shadow .12s;
}
.wt-event:hover {
  box-shadow: 0 2px 6px rgba(0,0,0,.12);
  transform: translateY(-1px);
}
.wt-event-time {
  font-size: 12px; font-weight: 700;
  color: var(--text-soft);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}
.wt-event-text {
  font-size: 13px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
@media (max-width: 880px) {
  .wt-grid { grid-template-columns: 38px repeat(7, 1fr); }
  .wt-day-head { padding: 4px 4px; grid-template-columns: 1fr; justify-items: center; }
  .wt-day-wx { display: none; }
  .wt-allday-label { font-size: 0; padding: 4px; }
  .wt-hour-label { font-size: 9px; padding-right: 4px; }
  .wt-event-text { -webkit-line-clamp: 1; }
}

/* ============================ Day view ============================ */
/* Single-day surface: a rich hero header, an all-day strip, and a 24h
   scrolling timeline with lane-packed event blocks. Shares design tokens
   with the rest of the app. */
.day-view {
  display: flex; flex-direction: column;
  flex: 1; min-height: 0; min-width: 0;
  background: var(--bg);
}

/* ---- Hero header ---- */
.dv-hero {
  display: flex; align-items: center; gap: 18px;
  padding: 18px 22px;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(120% 140% at 0% 0%, var(--primary-tint), transparent 60%),
    var(--bg-elev);
}
.dv-hero-date { flex: 1; min-width: 0; }
.dv-hero-weekday {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--primary);
}
@keyframes pulseSubtle {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .85; transform: scale(1.03); }
}
.dv-today-badge {
  font-size: 10px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--on-primary); background: var(--primary-fill);
  padding: 2px 8px; border-radius: 999px;
  animation: pulseSubtle 2.4s ease-in-out infinite;
}
.dv-hero-line {
  display: flex; align-items: baseline; gap: 12px; margin-top: 2px;
}
.dv-hero-day {
  font-size: 52px; font-weight: 800; line-height: 1;
  color: var(--text); font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}
.dv-hero-month {
  font-size: 15px; font-weight: 600; line-height: 1.2;
  color: var(--text-soft);
}
.dv-hero-meta {
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
  text-align: right;
}
.dv-hero-wx { display: flex; }
.dv-stats { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
.dv-stat {
  font-size: 12px; color: var(--text-soft);
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px 10px;
}
.dv-stat strong { color: var(--text); font-weight: 700; }
.dv-stat-done strong { color: var(--success); }
.dv-stat-ms strong { color: var(--primary); }
.dv-stat-empty { color: var(--text-mute); font-style: italic; }
.dv-nav {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--bg-elev); color: var(--text-soft);
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s, transform .12s;
}
.dv-nav:hover {
  background: var(--primary-tint); color: var(--primary);
  border-color: var(--primary); transform: scale(1.06);
}

/* ---- All-day strip ---- */
.dv-allday {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 10px 22px;
  border-bottom: 1px solid var(--line);
  background: var(--bg);
}
.dv-allday-label {
  flex: none; width: 56px; padding-top: 4px;
  font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-mute);
}
.dv-allday-list { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; min-width: 0; }
.dv-chip {
  display: inline-flex; align-items: center; gap: 6px;
  max-width: 100%;
  font-size: 13px; color: var(--text);
  background: color-mix(in srgb, var(--entry-color, var(--primary)) 12%, var(--bg-elev));
  border: 1px solid color-mix(in srgb, var(--entry-color, var(--primary)) 32%, transparent);
  border-radius: 999px; padding: 4px 12px;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.dv-chip:hover { background: color-mix(in srgb, var(--entry-color, var(--primary)) 22%, var(--bg-elev)); }
.dv-chip .pill-dot {
  flex: none;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--entry-color, var(--primary));
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 8px; color: var(--on-primary); line-height: 1;
}
.dv-chip.is-done { opacity: .6; text-decoration: line-through; }
.dv-chip.is-done .pill-dot { background: var(--success); }
.dv-chip-ms {
  background: var(--primary-tint);
  border-color: color-mix(in srgb, var(--primary) 34%, transparent);
  color: var(--primary); font-weight: 600;
}
.dv-chip-holiday { font-style: italic; }

/* ---- Timeline ---- */
.dv-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; }
.dv-timeline { position: relative; display: flex; }
.dv-gutter { position: relative; flex: none; width: 64px; }
.dv-hour-label {
  position: absolute; left: 0; right: 8px;
  transform: translateY(-50%);
  text-align: right;
  font-size: 11px; font-weight: 600; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}
.dv-events { position: relative; flex: 1; min-width: 0; border-left: 1px solid var(--line); cursor: copy; }
.dv-hourline {
  position: absolute; left: 0; right: 0;
  border-top: 1px solid var(--line);
  pointer-events: none;
}

.dv-event {
  position: absolute;
  display: flex; gap: 0;
  overflow: hidden;
  border-radius: 8px;
  background: color-mix(in srgb, var(--entry-color) 14%, var(--bg-elev));
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: filter .12s, box-shadow .12s;
}
.dv-event:hover { filter: brightness(1.04); box-shadow: var(--shadow-md); z-index: 2; }
.dv-event-bar { flex: none; width: 4px; background: var(--entry-color); }
.dv-event-body { padding: 5px 9px; min-width: 0; overflow: hidden; }
.dv-event-time {
  display: flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 700; color: var(--entry-color);
  font-variant-numeric: tabular-nums;
}
.dv-event-text {
  font-size: 13px; color: var(--text); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.dv-event.is-tight .dv-event-body { padding: 2px 9px; display: flex; align-items: baseline; gap: 6px; }
.dv-event.is-tight .dv-event-text { -webkit-line-clamp: 1; }
.dv-event.is-done { opacity: .6; }
.dv-event.is-done .dv-event-text { text-decoration: line-through; }

.dv-now { position: absolute; left: 0; right: 0; border-top: 2px solid var(--danger); pointer-events: none; z-index: 3; }
.dv-now-dot {
  position: absolute; left: -5px; top: -5px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--danger);
}
.dv-empty {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; justify-content: center;
  padding-top: 40px;
  pointer-events: none;
}
.dv-empty span {
  font-size: 13px; color: var(--text-mute);
  background: var(--bg-elev); border: 1px dashed var(--line);
  border-radius: 999px; padding: 6px 16px;
}

@media (max-width: 880px) {
  .dv-hero { padding: 14px 14px; gap: 10px; }
  .dv-hero-day { font-size: 40px; }
  .dv-hero-meta { gap: 6px; }
  .dv-nav { width: 32px; height: 32px; }
  .dv-allday { padding: 8px 12px; gap: 8px; }
  .dv-allday-label { width: 40px; font-size: 10px; }
  .dv-gutter { width: 48px; }
  .dv-hour-label { font-size: 10px; right: 6px; }
}

/* ============================ Side panel ============================ */

/* Desktop: fixed slide-in drawer pinned to the right edge. It overlays
   the calendar so the grid keeps the full width underneath. The mobile
   block below (media query at the top of this file) flattens it back to
   a regular column when the tab UI takes over. */
.side {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
  position: fixed;
  /* Sit just below the topbar so the topbar's right-side buttons
     (Settings / Dev / Share / Today / the toggle itself) stay
     clickable while the drawer is open. 57px = topbar min-height (56)
     + the 1px border-bottom; bump if the topbar grows. */
  top: 57px;
  right: 0;
  width: min(380px, 100vw);
  height: calc(100vh - 57px);
  height: calc(100dvh - 57px);
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
  background: var(--bg-soft);
  border-left: 1px solid var(--line);
  border-top-left-radius: var(--radius-lg);
  box-shadow: -8px 0 24px -10px rgba(15, 23, 42, 0.22);
  overflow-y: auto;
  overscroll-behavior: contain;
  z-index: 61;
  transform: translateX(100%);
  transition: transform .25s ease;
}
[data-theme="dark"] .side {
  box-shadow: -8px 0 28px -10px rgba(0, 0, 0, 0.5);
}
.app[data-side-open="true"] .side {
  transform: translateX(0);
}

.side-close {
  position: sticky;
  top: 0;
  align-self: flex-end;
  display: inline-grid; place-items: center;
  width: 28px; height: 28px;
  border-radius: 8px; border: 1px solid var(--line);
  background: var(--bg-elev); color: var(--text-soft);
  cursor: pointer;
  margin: -4px -4px 4px 0;
  z-index: 1;
}
.side-close:hover { background: var(--bg-hover); color: var(--text); }

@media (max-width: 880px) {
  /* Mobile reverts to the tab-driven flow layout — no drawer, no fixed
     positioning. The close button is redundant when tabs are doing the
     navigating, so hide it. `display: contents` lets the side's children
     (day-card, ms-card, insights-card) participate directly in the
     layout's flex stack — without it, .side would be a flex column
     containing all three panes. */
  .side {
    display: contents;
    position: static;
    width: auto;
    height: auto;
    padding: 0;
    background: transparent;
    border-left: 0;
    border: 0;
    box-shadow: none;
    overflow: visible;
    transform: none;
    z-index: auto;
  }
  .side-close { display: none; }
  /* Mobile already has the tab strip for switching to the day / milestones
     panes — the topbar drawer toggle would be redundant and just steal
     space. */
  .side-toggle-btn { display: none !important; }
}

.card {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 16px;
}
.card-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px 12px; margin-bottom: 12px;
  /* Let a wide actions cluster (e.g. the day-card's two segmented controls +
     day-nav arrows) drop to its own row instead of crushing the title into a
     one-character-per-line sliver. */
  flex-wrap: wrap;
}
.card-head-text { min-width: 0; flex: 1 1 auto; }
.card-eyebrow {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); font-weight: 700; margin-bottom: 2px;
}
.card-title { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -0.015em; color: var(--text); }

.weather-chip {
  margin-top: 4px;
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 11px; color: var(--text-soft); font-weight: 600;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 1px 8px;
  width: fit-content;
}
.weather-glyph { font-size: 12px; }
.weather-hi { color: var(--text); }
.weather-lo { color: var(--text-mute); }
.weather-label { color: var(--text-mute); margin-left: 2px; display: none; }
.weather-chip:hover .weather-label { display: inline; }
.weather-loading { color: var(--text-mute); }

.day-card .day-actions { display: flex; flex-wrap: wrap; gap: 6px; flex-shrink: 0; margin-left: auto; max-width: 100%; justify-content: flex-end; }

/* Today's milestones strip */
.day-ms-strip {
  display: flex; flex-direction: column; gap: 6px;
  margin-bottom: 12px;
}
.day-ms-strip:empty { display: none; }
.day-ms {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: 10px;
  background: var(--primary-tint);
  border-left: 3px solid var(--primary);
  cursor: pointer;
  transition: filter .12s;
}
.day-ms:hover { filter: brightness(.98); }
.day-ms .star { color: var(--primary); font-weight: 700; }
.day-ms-title {
  font-weight: 600; color: var(--text);
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.day-ms.done .day-ms-title { text-decoration: line-through; color: var(--text-mute); }

/* Entry composer: trigger button + modal */
.add-entry-trigger {
  display: flex; align-items: center; gap: 10px;
  width: 100%; margin: 0 0 12px;
  padding: 10px 12px;
  background: var(--bg-soft);
  border: 1px dashed var(--line-strong, var(--line));
  border-radius: 12px;
  color: var(--text-mute);
  font: inherit; font-size: 13px; text-align: left;
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s, box-shadow .15s;
}
.add-entry-trigger:hover {
  border-color: var(--primary);
  color: var(--text);
  background: var(--primary-tint);
}
.add-entry-trigger:focus-visible {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.aet-icon {
  width: 26px; height: 26px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary); color: #fff;
  flex-shrink: 0;
}
.aet-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aet-hint {
  font-size: 11px; color: var(--text-mute);
  padding: 2px 6px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg-elev);
  flex-shrink: 0;
}
.add-entry-trigger:hover .aet-hint { border-color: var(--primary); color: var(--primary); }

/* Entry form (now lives inside the modal) */
.entry-form { position: relative; }
.entry-form.dropping {
  outline: 2px dashed var(--primary);
  outline-offset: 4px;
  border-radius: 12px;
  background: var(--primary-tint);
}

/* Entry composer modal — wider than the default modal, full-screen on phones */
.entry-modal { width: min(640px, calc(100vw - 32px)); }
.entry-modal .modal-head { gap: 10px; }
.entry-modal-date {
  font-size: 12px; color: var(--text-mute);
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex: 1; text-align: right;
  margin-right: 4px;
  overflow: hidden; text-overflow: ellipsis;
}
.entry-modal .entry-form { padding: 16px; }
.entry-modal #entryInput {
  min-height: 120px;
  max-height: 50vh;
  font-size: 15px;
}
.entry-modal .entry-add-btn {
  width: auto; height: 36px;
  padding: 0 14px;
  border-radius: 999px;
  gap: 6px;
}
.entry-add-label { font-weight: 600; font-size: 13px; }

@media (max-width: 880px) {
  /* Full-screen composer on mobile */
  .entry-modal {
    width: 100vw;
    max-width: 100vw;
    max-height: 100dvh;
    height: 100dvh;
    border-radius: 0;
    border: 0;
  }
  .entry-modal .modal-head {
    padding-top: max(14px, env(safe-area-inset-top));
  }
  .entry-modal .entry-form {
    padding: 14px;
    padding-bottom: max(14px, env(safe-area-inset-bottom));
    flex: 1; min-height: 0;
    display: flex; flex-direction: column;
    overflow: auto;
  }
  .entry-modal #entryInput {
    min-height: 30vh;
    max-height: none;
    flex: 1;
  }
  .entry-modal .entry-toolbar {
    margin-top: auto;
    padding-top: 8px;
  }
}

/* ============================ Rich entry editor ============================
   Centered modal on desktop, full-screen sheet on phones. Reuses
   .modal / .modal-head / .modal-body and the existing close machinery.
   Layout is a stack of small sections — each with an icon header — so the
   form reads top-to-bottom like a structured event card rather than a
   labelled stack of inputs. */
.entry-editor-modal { width: min(680px, calc(100vw - 32px)); }
.entry-editor-modal .modal-head {
  gap: 10px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--line);
}
.entry-editor-modal .modal-head h3 { font-size: 15px; }
.entry-editor-date {
  font-size: 12px; color: var(--text-mute);
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex: 1; text-align: right;
  margin-right: 4px;
  overflow: hidden; text-overflow: ellipsis;
}
.entry-editor-body {
  display: flex; flex-direction: column;
  gap: 0;
  padding: 0;
}

/* ---- Inputs share these baseline styles ---- */
.entry-editor-body input[type="text"],
.entry-editor-body input[type="date"],
.entry-editor-body input[type="time"],
.entry-editor-body input[type="number"],
.entry-editor-body textarea,
.entry-editor-body select {
  width: 100%;
  font: inherit;
  font-size: 14px;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--bg-elev);
  color: var(--text);
  box-sizing: border-box;
  transition: border-color .12s, box-shadow .12s, background .12s;
}
.entry-editor-body input:hover:not(:focus),
.entry-editor-body textarea:hover:not(:focus),
.entry-editor-body select:hover:not(:focus) {
  border-color: var(--line-strong);
}
.entry-editor-body input:focus,
.entry-editor-body textarea:focus,
.entry-editor-body select:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}
.entry-editor-body textarea { resize: vertical; min-height: 72px; line-height: 1.45; }

/* ---- Title: a big borderless heading at the top ---- */
.ee-title-input {
  border: 0 !important;
  background: transparent !important;
  font-size: 22px !important;
  font-weight: 700 !important;
  letter-spacing: -0.01em;
  padding: 18px 20px 10px !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}
.ee-title-input::placeholder { color: var(--text-mute); font-weight: 600; }
.ee-title-input:focus { box-shadow: none !important; background: transparent !important; }

/* ---- Section blocks ---- */
.ee-section {
  display: flex; flex-direction: column;
  gap: 8px;
  padding: 12px 20px;
  border-top: 1px solid var(--line);
}
.ee-section:last-of-type { padding-bottom: 16px; }
.ee-sec-head {
  display: flex; align-items: center;
  gap: 8px;
  color: var(--text-mute);
}
.ee-sec-icon { color: var(--text-mute); flex: 0 0 auto; }
.ee-sec-title {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-mute);
}
.ee-sec-body {
  display: flex; flex-wrap: wrap;
  gap: 10px;
  align-items: flex-start;
}

/* ---- Generic field (label above input) ---- */
.ee-field {
  display: flex; flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.ee-field > .ee-label {
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--text-mute);
}
.ee-grow { flex: 1; min-width: 140px; }

/* ---- When: date + all-day switch + time pair ---- */
.ee-allday-switch {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 8px;
  cursor: pointer;
  font-size: 12px;
  color: var(--text);
  user-select: none;
}
.ee-allday-switch input { position: absolute; opacity: 0; pointer-events: none; }
.ee-switch-track {
  position: relative; display: inline-block;
  width: 30px; height: 18px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: background .12s, border-color .12s;
}
.ee-switch-thumb {
  position: absolute; top: 1px; left: 1px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--text-mute);
  transition: transform .14s ease, background .12s;
}
.ee-allday-switch input:checked + .ee-switch-track {
  background: var(--primary);
  border-color: var(--primary);
}
.ee-allday-switch input:checked + .ee-switch-track .ee-switch-thumb {
  transform: translateX(12px);
  background: #fff;
}
.ee-allday-label { font-weight: 500; }

/* Inline toggle + wrapping description label (channel-notify, etc.).
   The base .switch is a fixed 44×24 box meant to stand alone; combined with
   .ee-switch it becomes a flex row so the descriptive .ee-switch-label sits
   beside the toggle and wraps, instead of overflowing the 44px box and
   colliding with the section below.
   NB: selector is `.switch.ee-switch` (specificity 0,2,0) on purpose — it must
   outrank the base `.switch { width:44px;height:24px }` rule, which appears
   LATER in this file and would otherwise win the source-order tie at (0,1,0)
   and re-clamp the label into the 44px box. */
.switch.ee-switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  width: auto; height: auto;   /* override .switch's fixed 44×24 */
  cursor: pointer;
}
.switch.ee-switch .switch-slider {
  position: relative; inset: auto;   /* in-flow, fixed-size track */
  display: inline-block;
  flex: 0 0 auto;
  width: 44px; height: 24px;
}
.switch.ee-switch .ee-switch-label {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13px;
  line-height: 1.4;
  color: var(--text);
}

.ee-time-pair {
  display: flex; align-items: flex-end;
  gap: 8px;
  flex: 1; min-width: 220px;
  transition: opacity .12s;
}
.ee-time-pair .ee-field { flex: 1; min-width: 0; }
.ee-time-arrow {
  color: var(--text-mute);
  padding: 0 2px 9px;
  font-size: 14px;
}
.ee-time-pair.disabled { opacity: 0.35; pointer-events: none; }

/* ---- Repeats: preset select + custom panel ---- */
.ee-recur-preset { max-width: 280px; }
.ee-recur-custom {
  display: flex; flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  width: 100%;
}
.ee-recur-row {
  display: flex; align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.ee-recur-prefix, .ee-recur-suffix {
  font-size: 13px; color: var(--text);
  font-weight: 500;
}
.ee-recur-row input[type="number"] {
  width: 64px !important;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.ee-recur-row select {
  width: auto !important;
  min-width: 110px;
}
.ee-weekdays {
  display: flex; gap: 4px;
  flex-wrap: wrap;
}
.ee-wd {
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--bg-elev);
  color: var(--text);
  cursor: pointer;
  font-size: 12px; font-weight: 600;
  transition: background .12s, color .12s, border-color .12s, transform .05s;
}
.ee-wd:hover { border-color: var(--line-strong); }
.ee-wd:active { transform: translateY(1px); }
.ee-wd.selected {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.ee-recur-summary {
  margin: 0;
  font-size: 12px;
  color: var(--text-mute);
  font-style: italic;
  min-height: 1.2em;
}

/* ---- Tags ---- */
.ee-tag-grid {
  display: flex; flex-wrap: wrap;
  gap: 6px;
  min-height: 36px;
  padding: 8px;
  width: 100%;
  border: 1px dashed var(--line);
  border-radius: var(--radius-md);
  background: var(--bg-soft);
}
.ee-tag-grid:empty::before {
  content: "Pick a tag below, or add a new one.";
  font-size: 12px; color: var(--text-mute);
  padding: 4px 6px;
}
.ee-tag-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-elev);
  cursor: pointer;
  font-size: 12px; font-weight: 500;
  transition: transform .05s, box-shadow .12s, border-color .12s, background .12s;
}
.ee-tag-pill:hover { border-color: var(--line-strong); }
.ee-tag-pill:active { transform: translateY(1px); }
.ee-tag-pill .ee-tag-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: currentColor;
  flex: 0 0 auto;
}
.ee-tag-pill.selected {
  border-color: currentColor;
  box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 28%, transparent);
  background: color-mix(in srgb, currentColor 14%, var(--bg-elev));
}
.ee-tag-pill input[type="color"] {
  width: 16px; height: 16px;
  padding: 0; border: 0; background: transparent;
  cursor: pointer;
  border-radius: 4px;
  appearance: none; -webkit-appearance: none;
  margin-left: 2px;
}
.ee-tag-pill input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.ee-tag-pill input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 4px; }

.ee-tag-new {
  display: flex; gap: 6px; align-items: center;
  width: 100%;
}
.ee-tag-new input[type="text"] { flex: 1; }
.ee-tag-new input[type="color"] {
  width: 38px; height: 38px;
  padding: 2px; border: 1px solid var(--line);
  background: var(--bg-elev);
  border-radius: var(--radius-md);
  cursor: pointer;
}

/* ---- Guests ---- */
.ee-guests-list {
  display: flex; flex-wrap: wrap; gap: 6px;
  width: 100%;
}
.ee-guest-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-elev);
  cursor: pointer;
  font-size: 12px; font-weight: 500;
  user-select: none;
  transition: background .12s, border-color .12s, color .12s;
}
.ee-guest-chip input {
  position: absolute; opacity: 0; pointer-events: none;
  width: 1px; height: 1px;
}
.ee-guest-chip.selected {
  background: var(--primary-tint);
  border-color: var(--primary);
  color: var(--primary);
  font-weight: 600;
}

/* ---- Footer ---- */
.ee-actions {
  display: flex; align-items: center; gap: 8px;
  padding: 14px 20px;
  border-top: 1px solid var(--line);
  background: var(--bg-elev);
}
.ee-spacer { flex: 1; }

/* "Done" toggle in the editor footer reuses the all-day switch styling,
   but skips the margin-left:auto since .ee-spacer handles layout. */
.ee-done-switch { margin-left: 0; }

/* Mobile: full-screen sheet, sticky footer. */
@media (max-width: 880px) {
  .entry-editor-modal {
    width: 100vw;
    max-width: 100vw;
    max-height: 100dvh;
    height: 100dvh;
    border-radius: 0;
    border: 0;
  }
  .entry-editor-modal .modal-head {
    padding-top: max(14px, env(safe-area-inset-top));
  }
  .entry-editor-body {
    flex: 1; min-height: 0;
    overflow: auto;
  }
  .ee-title-input { padding: 16px !important; font-size: 20px !important; }
  .ee-section { padding: 12px 16px; }
  .ee-actions {
    position: sticky; bottom: 0; z-index: 1;
    padding: 12px 16px max(12px, env(safe-area-inset-bottom));
    border-top: 1px solid var(--line);
  }
  /* On narrow screens stack date/time vertically. */
  .ee-time-pair { width: 100%; }
  .ee-grow { flex: 1 1 100%; }
}

/* ============================================================
   Rich entry editor as its OWN full page (mobile + desktop).
   The editor used to be a cramped ~680px floating card; now it
   takes over the whole viewport as a routable page so the form
   has room to breathe and reads top-to-bottom. Driven by
   openEntryEditor() → markPage("entry-editor", { force:true }),
   which sets body[data-page="entry-editor"] at every width.
   These rules live OUTSIDE any media query so the page look is
   identical on phone and desktop; the generic mobile
   body[data-page] rules layer on top below 880px (they also hide
   the topbar / calendar behind the page).
   ============================================================ */
body[data-page="entry-editor"] .modal-root {
  place-items: stretch;
  padding: 0;
}
/* No dimmed overlay — it's a page, not a dialog floating over content. */
body[data-page="entry-editor"] .modal-backdrop { display: none; }

body[data-page="entry-editor"] .entry-editor-modal {
  width: 100vw; max-width: 100vw;
  height: 100dvh; max-height: 100dvh;
  border: 0; border-radius: 0;
  box-shadow: none;
  animation: none;
  background: var(--bg);
}

/* Sticky page header: back arrow + title + date chip. */
body[data-page="entry-editor"] .entry-editor-modal > .modal-head {
  position: sticky; top: 0; z-index: 10;
  padding: 10px 16px;
  padding-top: max(10px, env(safe-area-inset-top));
}
/* The back arrow replaces the close-X as the page's dismiss affordance.
   It carries data-close, so the generic mobile rule that hides
   .modal-head > .iconbtn[data-close] would also hide it — force it on. */
.entry-editor-modal .modal-page-back { display: none; }
body[data-page="entry-editor"] .entry-editor-modal .modal-page-back {
  display: inline-flex !important;
  flex: 0 0 auto;
}
/* Drop the redundant close-X; the back arrow handles dismiss. */
body[data-page="entry-editor"] .entry-editor-modal > .modal-head > .iconbtn[data-close]:not(.modal-page-back) {
  display: none;
}

/* Scrollable body, content constrained to a readable centered column. */
body[data-page="entry-editor"] .entry-editor-body {
  flex: 1; min-height: 0;
  overflow: auto;
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding-bottom: max(24px, env(safe-area-inset-bottom));
}

/* More vertical air between sections than the old cramped modal. */
body[data-page="entry-editor"] .ee-title-input {
  padding: 28px 20px 14px !important;
  font-size: 26px !important;
}
body[data-page="entry-editor"] .ee-section { padding: 18px 20px; gap: 10px; }
body[data-page="entry-editor"] .ee-section:last-of-type { padding-bottom: 22px; }
body[data-page="entry-editor"] .ee-sec-body { gap: 12px; }
body[data-page="entry-editor"] .entry-editor-body input[type="text"],
body[data-page="entry-editor"] .entry-editor-body input[type="date"],
body[data-page="entry-editor"] .entry-editor-body input[type="time"],
body[data-page="entry-editor"] .entry-editor-body input[type="number"],
body[data-page="entry-editor"] .entry-editor-body textarea,
body[data-page="entry-editor"] .entry-editor-body select {
  font-size: 15px;
  padding: 11px 13px;
}

/* Footer: full-width sticky bar, its controls aligned to the same column. */
body[data-page="entry-editor"] .ee-actions {
  position: sticky; bottom: 0; z-index: 10;
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: 14px 20px max(14px, env(safe-area-inset-bottom));
}

/* Compact toolbar below the textarea: thin icon row + Add button. */
.entry-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  margin-top: 8px;
  position: relative;
}
.entry-toolbar-icons { display: flex; gap: 2px; }
.tool-btn {
  width: 30px; height: 30px;
  border-radius: 8px;
  border: 0;
  background: transparent;
  color: var(--text-mute);
  display: inline-flex; align-items: center; justify-content: center;
  position: relative;
  box-shadow: none;
  cursor: pointer;
  transition: color .12s, background .12s;
}
.tool-btn:hover { color: var(--primary); background: var(--bg-soft); }
.tool-btn:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 1px;
  color: var(--primary);
}
.tool-btn[aria-expanded="true"] { color: var(--primary); background: var(--primary-tint); }
.tool-btn.set { color: var(--primary); background: var(--primary-tint); }
.tool-btn.set::after {
  content: ""; position: absolute; right: 3px; top: 3px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--primary);
}
.mood-btn-glyph { font-size: 14px; line-height: 1; }
.mood-btn.set .mood-btn-glyph { font-size: 16px; }

.entry-add-btn {
  width: 34px; height: 34px;
  min-height: 0;
  padding: 0;
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
}

/* Popovers anchored above the toolbar icons. Each popover floats above the
   icon that opens it; left offsets match each button's position in the row
   (icons are ~30px wide with 2px gaps). */
.tool-pop {
  position: absolute;
  bottom: calc(100% + 6px);
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow-md);
  padding: 6px;
  z-index: 20;
  display: flex; gap: 4px; align-items: center;
  animation: pop .14s ease-out;
}
.tool-pop[hidden] { display: none; }
/* Tool popovers — JS sets `left` at open time based on the trigger button's
   actual offset, so the popovers stay aligned at any breakpoint. The default
   here only applies if JS hasn't run yet (graceful fallback). */
.time-pop, .mood-pop { left: 0; }
.time-pop input[type="time"] {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 4px 8px;
  outline: none;
  font-variant-numeric: tabular-nums;
}
.time-pop .link { font-size: 11px; color: var(--text-mute); }

/* Find-a-time popover — denser than the others; it's a mini-form. */
.find-time-pop {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  padding: 10px;
  width: 320px;
  max-width: calc(100vw - 32px);
}
.find-time-pop .ft-row {
  display: flex; gap: 6px; align-items: flex-end;
  flex-wrap: wrap;
}
.find-time-pop .ft-members {
  gap: 4px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 8px;
}
.find-time-pop .ft-empty {
  font-size: 12px;
  color: var(--text-mute);
}
.find-time-pop .ft-field {
  display: flex; flex-direction: column; gap: 3px;
  flex: 1; min-width: 0;
}
.find-time-pop .ft-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-mute);
}
.find-time-pop .ft-field input,
.find-time-pop .ft-field select {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 4px 6px;
  font: inherit;
  color: var(--text);
  outline: none;
  font-variant-numeric: tabular-nums;
  width: 100%;
  box-sizing: border-box;
}
.find-time-pop .ft-field input:focus,
.find-time-pop .ft-field select:focus {
  border-color: var(--primary);
}
.find-time-pop .btn.small { white-space: nowrap; }
.find-time-pop .ft-member-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 8px;
  border-radius: 999px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  font-size: 12px;
  cursor: pointer;
  user-select: none;
  color: var(--text);
}
.find-time-pop .ft-member-chip .ft-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ft-color, var(--text-mute));
}
.find-time-pop .ft-member-chip.active {
  background: var(--primary-tint);
  border-color: var(--primary);
  color: var(--primary);
}
.find-time-pop .ft-results {
  display: flex; flex-direction: column; gap: 4px;
  max-height: 180px;
  overflow-y: auto;
  border-top: 1px solid var(--line);
  padding-top: 8px;
}
.find-time-pop .ft-slot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  font-size: 12px;
  cursor: pointer;
  color: var(--text);
  text-align: left;
}
.find-time-pop .ft-slot:hover {
  border-color: var(--primary);
  color: var(--primary);
}
.find-time-pop .ft-slot.first {
  background: var(--primary-tint);
  border-color: var(--primary);
  color: var(--primary);
  font-weight: 600;
}
.find-time-pop .ft-slot-day {
  color: var(--text-mute);
  font-size: 11px;
  font-weight: 400;
}
.find-time-pop .ft-status {
  font-size: 12px;
  color: var(--text-mute);
}

/* Draft attachments above the entry input */
.draft-attachments {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-bottom: 6px;
}
.draft-att {
  position: relative; width: 44px; height: 44px;
  border-radius: 6px; overflow: hidden;
  background: var(--bg-soft); border: 1px solid var(--line);
}
.draft-att img { width: 100%; height: 100%; object-fit: cover; display: block; }
.draft-att-audio { display: flex; align-items: center; justify-content: center; height: 100%; font-size: 18px; }
.draft-att-x {
  position: absolute; top: 1px; right: 1px;
  width: 16px; height: 16px; border-radius: 50%;
  background: rgba(0,0,0,.6); color: white; border: 0;
  cursor: pointer; font-size: 11px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}

/* Attachment thumbs under entry text */
.att-row { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.att-thumb {
  width: 56px; height: 56px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  border-radius: 6px;
  padding: 0; cursor: pointer; overflow: hidden;
  transition: transform .12s;
}
.att-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.att-thumb:hover { transform: scale(1.04); }
.att-thumb.att-audio { font-size: 22px; display: flex; align-items: center; justify-content: center; }
.att-audio-wrap { display: inline-flex; align-items: center; gap: 4px; }
.entry.dropping { outline: 2px dashed var(--primary); outline-offset: 2px; }

/* Link attachment chip (entry day-list + editor) */
.att-link-wrap { display: inline-flex; align-items: center; gap: 4px; }
.att-link-chip {
  display: inline-flex; align-items: center; gap: 5px;
  max-width: 220px;
  padding: 4px 9px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  border-radius: 999px;
  font-size: 12px; color: var(--text);
  text-decoration: none;
  transition: border-color .12s, color .12s;
}
.att-link-chip:hover { border-color: var(--primary); color: var(--primary); }
.att-link-chip svg { flex: none; color: var(--text-mute); }
.att-link-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ===== Editor attachments section (#12) ===== */
.ee-attach-list { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.ee-attach-list:empty { margin-bottom: 0; }
.ee-attach-item { position: relative; display: inline-flex; align-items: center; }
.ee-attach-thumb {
  display: block; width: 56px; height: 56px;
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
}
.ee-attach-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ee-attach-link a, .ee-attach-audio {
  display: inline-flex; align-items: center; gap: 6px;
  max-width: 240px;
  padding: 6px 10px;
  border: 1px solid var(--line); border-radius: 999px;
  font-size: 12.5px; color: var(--text); text-decoration: none;
}
.ee-attach-link a span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ee-attach-link a:hover { border-color: var(--primary); color: var(--primary); }
.ee-attach-x {
  position: absolute; top: -6px; right: -6px;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--text-mute);
  font-size: 13px; line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.ee-attach-x:hover { color: var(--danger, #dc2626); border-color: var(--danger, #dc2626); }
.ee-attach-actions { display: flex; gap: 8px; }
.ee-attach-link-form { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.ee-attach-link-form input[type="url"] { flex: 1 1 160px; }
.ee-attach-link-form input[type="text"] { flex: 1 1 120px; }

/* ===== Day photos (family-visible photos attached to a calendar day) ===== */
.day-photos {
  margin: 8px 0 4px;
}
.day-photos-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 6px;
}
.day-photos-title {
  font-size: 11px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-mute);
}
.day-photos-add {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 4px;
  background: transparent; border: 1px solid var(--line);
  color: var(--text-mute); padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px; line-height: 1.4;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.day-photos-add:hover {
  color: var(--primary); border-color: var(--primary);
  background: var(--primary-tint);
}
.day-photos-strip {
  display: flex; flex-wrap: nowrap; overflow-x: auto;
  gap: 6px; padding-bottom: 2px;
  scrollbar-width: thin;
}
.day-photo {
  position: relative; flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
}
.day-photo-thumb {
  width: 88px; height: 88px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  border-radius: 8px;
  padding: 0; cursor: pointer; overflow: hidden;
  transition: transform .12s, border-color .12s;
}
.day-photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.day-photo-thumb:hover { transform: scale(1.03); border-color: var(--primary); }
.day-photo-by {
  font-size: 10px;
  color: var(--owner-color, var(--text-mute));
  max-width: 88px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.day-photos-strip:empty { display: none; }
.day-photos:has(.day-photos-strip:empty) .day-photos-head .day-photos-title { opacity: .55; }

/* ===== Per-day meals (#10) ===== */
.day-meals { margin: 8px 0 4px; }
.day-meals-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.day-meals-icon { color: var(--text-mute); flex: none; }
.day-meals-title {
  font-size: 11px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-mute);
}
.day-meals-edit {
  margin-left: auto;
  background: transparent; border: 1px solid var(--line);
  color: var(--text-mute); padding: 3px 10px;
  border-radius: 999px; font-size: 11px; line-height: 1.4; cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.day-meals-edit:hover { color: var(--primary); border-color: var(--primary); background: var(--primary-tint); }
.day-meals-summary { display: flex; flex-direction: column; gap: 4px; }
.day-meal-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 12.5px; }
.day-meal-row-other { opacity: .9; }
.day-meal-empty { font-size: 12px; color: var(--text-mute); }
.meal-slot { display: inline-flex; align-items: center; gap: 4px; color: var(--text); }
.meal-slot-k {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 4px;
  background: var(--bg-elev); color: var(--text-mute);
  font-size: 9px; font-weight: 700;
}
.meal-slot-note { color: var(--text-mute); font-style: italic; }
.day-meal-by {
  font-size: 10px; font-weight: 600;
  color: var(--owner-color, var(--text-mute));
  display: inline-flex; align-items: center; gap: 4px;
}
.day-meal-by::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--owner-color, var(--text-mute));
}
.day-meals-form { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.day-meals-form[hidden] { display: none; }
.day-meal-field { display: flex; flex-direction: column; gap: 3px; }
.day-meal-label {
  font-size: 10px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-mute);
}
.day-meal-field input { width: 100%; }
.day-meals-actions { display: flex; align-items: center; gap: 10px; justify-content: flex-end; }
.meal-favorites { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.meal-favorites[hidden] { display: none; }
.meal-fav-label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-mute); margin-right: 2px; }
.meal-fav-chip { display: inline-flex; align-items: center; background: var(--bg-soft); border-radius: 999px; overflow: hidden; }
.meal-fav-pick { border: 0; background: transparent; color: var(--text); font-size: 12px; padding: 4px 4px 4px 10px; cursor: pointer; }
.meal-fav-del { border: 0; background: transparent; color: var(--text-mute); font-size: 14px; line-height: 1; padding: 4px 8px 4px 4px; cursor: pointer; }
.meal-fav-del:hover { color: var(--danger, #c0392b); }
.meal-fav-add { margin-left: auto; }

.meal-week-modal { max-width: 560px; width: 100%; }
.meal-week-nav { display: flex; align-items: center; justify-content: center; gap: 14px; margin-bottom: 10px; }
.meal-week-range { font-weight: 650; font-size: 14px; min-width: 180px; text-align: center; }
.meal-week-grid { display: flex; flex-direction: column; gap: 10px; }
.meal-week-day { display: grid; grid-template-columns: 84px 1fr; grid-auto-rows: min-content; gap: 4px 8px; align-items: center; padding: 8px; border-radius: 10px; background: var(--bg-soft); }
.meal-week-day.is-today { outline: 2px solid color-mix(in srgb, var(--accent) 50%, transparent); }
.meal-week-daylabel { grid-row: 1 / span 3; font-size: 12px; font-weight: 650; color: var(--text-mute); }
.meal-week-input { width: 100%; }
.meal-week-actions { display: flex; align-items: center; gap: 12px; justify-content: flex-end; margin-top: 14px; }
.meal-week-status { margin-left: auto; font-size: 12px; color: var(--text-mute); }
.meal-week-actions .meal-week-status { margin-left: 0; margin-right: auto; }

.groceries-modal { max-width: 520px; width: 100%; }
.groc-form { display: flex; gap: 8px; margin-bottom: 12px; }
.groc-input { flex: 1; }
.groc-list { display: flex; flex-direction: column; gap: 4px; max-height: 52vh; overflow-y: auto; }
.groc-empty { color: var(--text-mute); font-size: 14px; padding: 10px 2px; }
.groc-row { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 9px; cursor: pointer; }
.groc-row:hover { background: var(--bg-soft); }
.groc-box { flex: none; width: 20px; height: 20px; border-radius: 6px; border: 2px solid var(--border); display: grid; place-items: center; }
.groc-row.checked .groc-box { background: var(--accent, #e0457b); border-color: var(--accent, #e0457b); }
.groc-row.checked .groc-box::after { content: "✓"; color: #fff; font-size: 13px; font-weight: 700; line-height: 1; }
.groc-text { flex: 1; font-size: 15px; }
.groc-row.checked .groc-text { text-decoration: line-through; color: var(--text-mute); }
.groc-del { flex: none; border: 0; background: transparent; color: var(--text-mute); font-size: 18px; line-height: 1; cursor: pointer; padding: 2px 6px; border-radius: 6px; opacity: 0; }
.groc-row:hover .groc-del { opacity: 1; }
.groc-del:hover { color: var(--danger, #c0392b); background: var(--bg-hover); }
.groc-foot { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.groc-count { font-size: 12px; color: var(--text-mute); }
.groc-foot .link { margin-left: auto; }

.journal-modal { max-width: 620px; width: 100%; }
.jrnl-editor { margin-bottom: 16px; }
.jrnl-editor-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.jrnl-editor-date { font-weight: 650; font-size: 14px; }
.jrnl-editor-head .jrnl-status { margin-left: auto; font-size: 12px; color: var(--text-mute); }
.jrnl-text { width: 100%; min-height: 130px; resize: vertical; line-height: 1.5; }
.jrnl-feed-head { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-mute); margin: 4px 2px 8px; }
.jrnl-feed { display: flex; flex-direction: column; gap: 6px; max-height: 44vh; overflow-y: auto; }
.jrnl-empty { color: var(--text-mute); font-size: 14px; padding: 8px 2px; }
.jrnl-card { display: flex; flex-direction: column; gap: 3px; text-align: left; width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-soft); cursor: pointer; }
.jrnl-card:hover { background: var(--bg-hover); }
.jrnl-card.active { border-color: color-mix(in srgb, var(--accent, #e0457b) 55%, transparent); background: color-mix(in srgb, var(--accent, #e0457b) 8%, var(--bg-soft)); }
.jrnl-card-date { font-size: 12px; font-weight: 650; color: var(--text); }
.jrnl-card-preview { font-size: 13px; color: var(--text-mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.food-modal { max-width: 560px; width: 100%; }
.food-datebar { display: flex; align-items: center; gap: 8px; justify-content: center; margin-bottom: 12px; }
.food-datebar .food-input { flex: 1; max-width: 220px; }
.food-form { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.food-input { width: 100%; }
.food-form-row { display: flex; gap: 8px; align-items: center; }
.food-form-row .food-input { flex: 1; }
.food-form-row button { flex: none; }
.food-status { font-size: 12px; color: var(--text-mute); min-height: 1em; }
.food-list { display: flex; flex-direction: column; gap: 6px; max-height: 46vh; overflow-y: auto; }
.food-empty { color: var(--text-mute); font-size: 14px; padding: 10px 2px; }
.food-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-soft); }
.food-row-main { flex: 1; min-width: 0; }
.food-row-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.food-meal { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; font-weight: 700; padding: 2px 7px; border-radius: 999px; background: var(--bg-hover); color: var(--text-mute); }
.food-meal-breakfast { background: color-mix(in srgb, #f6b73c 22%, transparent); color: #b6801a; }
.food-meal-lunch { background: color-mix(in srgb, #4ba86a 22%, transparent); color: #2e7d4a; }
.food-meal-dinner { background: color-mix(in srgb, #6d7de0 22%, transparent); color: #4a58c0; }
.food-meal-snack { background: color-mix(in srgb, #e0457b 20%, transparent); color: #c0356b; }
.food-time { font-size: 12px; color: var(--text-mute); font-variant-numeric: tabular-nums; }
.food-item { font-size: 14px; font-weight: 600; }
.food-notes { font-size: 13px; color: var(--text-mute); margin-top: 3px; white-space: pre-wrap; }

.jobs-modal { max-width: 600px; width: 100%; }
.jobs-form { display: flex; flex-direction: column; gap: 8px; margin: 10px 0 14px; }
.jobs-input { width: 100%; }
.jobs-form-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.jobs-form-row .jobs-input { width: auto; flex: 1; min-width: 140px; }
.jobs-form-row button { margin-left: auto; }
.jobs-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.jobs-chip { font-size: 12px; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--border); background: var(--bg-soft); color: var(--text); cursor: pointer; }
.jobs-chip:hover { background: var(--bg-hover); }
.jobs-advanced { font-size: 13px; }
.jobs-advanced summary { cursor: pointer; color: var(--text-mute); font-size: 12px; padding: 2px 0; }
.jobs-advanced .jobs-form-row { margin-top: 6px; }
.jobs-form-actions { display: flex; align-items: center; gap: 10px; }
.jobs-form-actions .btn { margin-left: auto; }
.jobs-status { font-size: 12px; color: var(--text-mute); min-height: 1em; }
.jobs-list { display: flex; flex-direction: column; gap: 8px; max-height: 50vh; overflow-y: auto; }
.jobs-empty { color: var(--text-mute); font-size: 14px; padding: 8px 2px; }
.job-row { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-soft); }
.job-row.job-off { opacity: .55; }
.job-main { flex: 1; min-width: 0; }
.job-title { font-weight: 650; font-size: 14px; }
.job-when { font-size: 12px; color: var(--text-mute); margin: 1px 0 3px; }
.job-prompt { font-size: 13px; color: var(--text); white-space: pre-wrap; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.job-actions { display: flex; flex-direction: column; gap: 4px; align-items: flex-end; flex: none; }

.recall-modal { max-width: 560px; width: 100%; }
.recall-form { display: flex; gap: 8px; margin: 10px 0 6px; }
.recall-input { flex: 1; }
.recall-results { display: flex; flex-direction: column; gap: 6px; max-height: 60vh; overflow-y: auto; }
.recall-empty { color: var(--text-mute); font-size: 14px; padding: 10px 2px; }
.recall-answer { font-size: 15px; line-height: 1.5; padding: 12px 14px; border-radius: 12px; background: color-mix(in srgb, var(--accent) 10%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent); margin-bottom: 4px; }
.recall-sub { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-mute); margin: 6px 2px 2px; }
.recall-item {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg-soft); color: var(--text); cursor: pointer;
}
.recall-item:hover { background: var(--bg-hover); }
.recall-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.recall-item-text { flex: 1; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recall-item-meta { font-size: 12px; color: var(--text-mute); white-space: nowrap; }
.day-meals-status { font-size: 11px; color: var(--text-mute); margin-right: auto; }

/* ===== Per-day lists, notes & chores (v46) ===== */
.day-items { margin: 8px 0 4px; }
.day-items-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.day-items-icon { color: var(--text-mute); flex: none; }
.day-items-title {
  font-size: 11px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-mute);
}
.day-items-summary {
  margin-left: auto; font-size: 11px; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}
.day-items-body { display: flex; flex-direction: column; gap: 10px; }
.dii-empty { font-size: 12px; color: var(--text-mute); }
.dii-group { display: flex; flex-direction: column; gap: 3px; }
.dii-group-head {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-mute);
  margin-bottom: 1px;
}
.dii-group-count {
  font-size: 9.5px; font-weight: 700; color: var(--text-mute);
  background: var(--bg-elev); border-radius: 999px;
  padding: 1px 6px; font-variant-numeric: tabular-nums;
}
.dii-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text);
  padding: 3px 4px; border-radius: 8px;
  transition: background .12s;
}
.dii-row:hover { background: var(--bg-hover); }
.dii-row:hover .dii-del { opacity: 1; }
.dii-check {
  flex: none; width: 18px; height: 18px;
  border: 1.5px solid var(--line); border-radius: 6px;
  background: transparent; cursor: pointer;
  display: inline-grid; place-items: center;
  color: transparent;
  transition: background .12s, border-color .12s, color .12s;
}
.dii-check:hover { border-color: var(--primary); }
.dii-row.is-done .dii-check {
  background: var(--primary-fill); border-color: var(--primary-fill);
  color: var(--on-primary);
}
.dii-note-bullet { flex: none; width: 18px; text-align: center; color: var(--text-mute); }
.dii-text { flex: 1 1 auto; min-width: 0; word-break: break-word; }
.dii-note .dii-text { white-space: pre-wrap; color: var(--text); }
.dii-row.is-done .dii-text { text-decoration: line-through; color: var(--text-mute); }
.dii-assignee, .dii-owner {
  flex: none; font-size: 10px; font-weight: 600;
  color: var(--owner-color, var(--text-mute));
  display: inline-flex; align-items: center; gap: 4px;
}
.dii-owner {
  background: color-mix(in srgb, var(--owner-color, var(--text-mute)) 14%, transparent);
  border-radius: 999px; padding: 1px 7px;
}
.dii-assignee-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--owner-color, var(--text-mute)); }
.dii-del {
  flex: none; width: 20px; height: 20px; border-radius: 6px;
  border: none; background: transparent; cursor: pointer;
  color: var(--text-mute); font-size: 16px; line-height: 1;
  opacity: 0; transition: opacity .12s, background .12s, color .12s;
}
.dii-del:hover { background: var(--danger-soft); color: var(--danger); }
/* Always reveal the delete affordance on touch (no hover). */
@media (hover: none) { .dii-del { opacity: .8; } }

.day-items-add { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.day-items-kinds { display: inline-flex; gap: 4px; }
.dii-kind {
  background: transparent; border: 1px solid var(--line);
  color: var(--text-mute); padding: 3px 12px;
  border-radius: 999px; font-size: 11px; line-height: 1.4; cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.dii-kind:hover { color: var(--primary); border-color: var(--primary); background: var(--primary-tint); }
.dii-kind.is-active {
  color: var(--on-primary); background: var(--primary-fill); border-color: var(--primary-fill);
}
.day-items-add-row { display: flex; align-items: center; gap: 8px; }
.day-items-input { flex: 1 1 auto; min-width: 0; }
.day-items-assignee { flex: none; max-width: 42%; }
.day-items-assignee[hidden] { display: none; }
.day-items-addbtn { flex: none; }

/* Drag handle (reorder) — pointer-based, so kill native touch scrolling on it. */
.dii-grip {
  flex: none; width: 16px; height: 20px;
  border: none; background: transparent; padding: 0;
  color: var(--text-mute); cursor: grab;
  touch-action: none; -webkit-user-select: none; user-select: none;
  display: inline-grid; place-items: center;
  opacity: 0; transition: opacity .12s;
}
.dii-row:hover .dii-grip { opacity: .55; }
.dii-grip:hover { opacity: 1; color: var(--text); }
.dii-grip:active { cursor: grabbing; }
.dii-grip-spacer { width: 16px; height: 20px; opacity: 0; cursor: default; }
@media (hover: none) { .dii-grip { opacity: .45; } }
.dii-row.dii-dragging {
  opacity: .9; background: var(--bg-elev);
  box-shadow: var(--shadow-md); border-radius: 8px;
}

/* Inline edit affordance (owner-only) — reveals with delete on hover/touch. */
.dii-edit {
  flex: none; width: 22px; height: 22px; border-radius: 6px;
  border: none; background: transparent; cursor: pointer;
  color: var(--text-mute);
  display: inline-grid; place-items: center;
  opacity: 0; transition: opacity .12s, background .12s, color .12s;
}
.dii-row:hover .dii-edit { opacity: 1; }
.dii-edit:hover { background: var(--primary-tint); color: var(--primary); }
.dii-row .dii-text[data-dii-edit]:not([data-dii-edit=""]) { cursor: text; }
@media (hover: none) { .dii-edit { opacity: .8; } }

/* Inline edit mode: input + save/cancel replace the text. */
.dii-row.is-editing { background: var(--bg-hover); }
.dii-edit-input { flex: 1 1 auto; min-width: 0; font-size: 13px; padding: 4px 8px; }
.dii-edit-save, .dii-edit-cancel {
  flex: none; width: 24px; height: 24px; border-radius: 6px;
  border: 1px solid var(--line); background: transparent; cursor: pointer;
  display: inline-grid; place-items: center; line-height: 1;
  transition: background .12s, color .12s, border-color .12s;
}
.dii-edit-save { color: var(--primary); }
.dii-edit-save:hover { background: var(--primary-fill); color: var(--on-primary); border-color: var(--primary-fill); }
.dii-edit-cancel { color: var(--text-mute); font-size: 16px; }
.dii-edit-cancel:hover { background: var(--danger-soft); color: var(--danger); border-color: transparent; }

/* ===== "On this day" memory strip ===== */
.day-memories {
  margin: 8px 0 4px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-soft);
}
.day-memories[hidden] { display: none; }
.day-memories-head {
  display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px;
}
.day-memories-title {
  font-size: 11px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--primary);
}
.day-memories-count {
  font-size: 11px; color: var(--text-mute);
}
.day-memories-strip {
  display: flex; flex-wrap: nowrap; overflow-x: auto;
  gap: 6px; padding-bottom: 2px;
  scrollbar-width: thin;
}
.day-memory {
  position: relative; flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  cursor: pointer;
}
.day-memory-thumb {
  width: 80px; height: 80px;
  border: 1px solid var(--line);
  background: var(--bg-elev);
  border-radius: 8px;
  padding: 0; cursor: pointer; overflow: hidden;
  transition: transform .12s, border-color .12s;
}
.day-memory-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.day-memory-thumb:hover { transform: scale(1.03); border-color: var(--primary); }
.day-memory-when {
  font-size: 10px; color: var(--text-mute);
  max-width: 80px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ===== Settings: Email photos in ===== */
#photoEmailRow {
  display: flex; align-items: center; gap: 12px;
  flex-wrap: wrap;
}
#photoEmailStatus code {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 12px;
  user-select: all;
}
.form-actions.inline-actions {
  display: inline-flex; gap: 6px; margin-left: auto;
}

/* ===== Entry comments / thread ===== */
.entry-comments-toggle {
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--text-mute);
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  line-height: 1.4;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.entry-comments-toggle:hover {
  color: var(--text);
  border-color: var(--primary);
  background: var(--primary-tint);
}
.entry-comments-toggle[aria-expanded="true"] {
  color: var(--primary);
  border-color: var(--primary);
  background: var(--primary-tint);
}
.entry-thread {
  flex-basis: 100%;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--line);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.entry-comment-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.entry-comment {
  display: flex;
  flex-direction: column;
  background: var(--bg-soft);
  border-radius: 8px;
  padding: 5px 8px;
  border-left: 2px solid var(--owner-color, var(--text-mute));
}
.entry-comment.is-mine {
  background: var(--primary-tint);
}
.entry-comment-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 11px;
}
.entry-comment-author {
  font-weight: 600;
  color: var(--owner-color, var(--text));
}
.entry-comment-time {
  color: var(--text-mute);
}
.entry-comment-del {
  margin-left: auto;
  background: transparent;
  border: 0;
  color: var(--text-mute);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 4px;
  opacity: 0;
  transition: opacity .12s;
}
.entry-comment:hover .entry-comment-del { opacity: 1; }
.entry-comment-del:hover { color: var(--danger, #c0392b); }
.entry-comment-body {
  font-size: 13px;
  margin-top: 2px;
  word-break: break-word;
}
.entry-comment-form {
  display: flex;
  align-items: center;
  gap: 4px;
}
.entry-comment-input {
  flex: 1;
  font: inherit;
  font-size: 13px;
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg);
  color: var(--text);
}
.entry-comment-input:focus {
  outline: none;
  border-color: var(--primary);
}
.entry-comment-mic,
.entry-comment-send {
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 50%;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-mute);
  transition: color .12s, border-color .12s, background .12s;
  font-size: 13px;
  padding: 0;
}
.entry-comment-mic:hover,
.entry-comment-send:hover {
  color: var(--primary);
  border-color: var(--primary);
  background: var(--primary-tint);
}
.entry-comment-mic.recording {
  color: #fff;
  background: var(--danger, #c0392b);
  border-color: var(--danger, #c0392b);
  animation: pulse-rec 1.1s ease-in-out infinite;
}
@keyframes pulse-rec {
  0%, 100% { box-shadow: 0 0 0 0 rgba(192,57,43,.6); }
  50%      { box-shadow: 0 0 0 5px rgba(192,57,43,0); }
}

/* ----- Appointment RSVP (invites) ----- */
.entry-rsvp {
  flex-basis: 100%;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--line);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}
.rsvp-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 6px;
  min-width: 0;
}
.rsvp-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 8px 1px 6px;
  border-radius: 999px;
  font-size: 11px;
  line-height: 1.5;
  border: 1px solid var(--line);
  color: var(--text-mute);
  background: var(--bg-soft);
  white-space: nowrap;
}
.rsvp-chip .rsvp-ico {
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
}
.rsvp-chip.rsvp-accepted  { color: var(--success); border-color: color-mix(in srgb, var(--success) 40%, var(--line)); }
.rsvp-chip.rsvp-declined  { color: var(--danger);  border-color: color-mix(in srgb, var(--danger) 40%, var(--line)); }
.rsvp-chip.rsvp-tentative { color: var(--warn);    border-color: color-mix(in srgb, var(--warn) 40%, var(--line)); }
.rsvp-chip.rsvp-invited   { color: var(--text-mute); }

.rsvp-actions {
  display: inline-flex;
  gap: 4px;
  margin-left: auto;
}
.rsvp-btn {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--text-mute);
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11px;
  line-height: 1.4;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.rsvp-btn:hover {
  color: var(--text);
  border-color: var(--primary);
  background: var(--primary-tint);
}
.rsvp-btn-accepted.is-active {
  color: var(--on-primary);
  background: var(--success);
  border-color: var(--success);
}
.rsvp-btn-declined.is-active {
  color: var(--on-primary);
  background: var(--danger);
  border-color: var(--danger);
}
.rsvp-btn-tentative.is-active {
  color: var(--on-primary);
  background: var(--warn);
  border-color: var(--warn);
}

/* Topbar Invitations indicator */
.invites-btn { position: relative; }
.invites-badge {
  position: absolute;
  top: 0;
  right: 0;
  transform: translate(35%, -35%);
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--primary-fill);
  color: var(--on-primary);
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
}

/* Lightbox */
.lightbox {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.85);
  z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: max(24px, env(safe-area-inset-top)) 16px max(24px, env(safe-area-inset-bottom));
}
.lightbox[hidden] { display: none; }
.lightbox-body {
  max-width: 95vw; max-height: 90vh;
  display: flex; align-items: center; justify-content: center;
}
.lightbox-body img {
  max-width: 95vw; max-height: 90vh;
  object-fit: contain; border-radius: 8px;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
}
.lightbox-body audio { width: min(80vw, 540px); }
.lightbox-close, .lightbox-del {
  position: absolute; top: 16px;
  background: rgba(255,255,255,.12); color: white;
  border: 1px solid rgba(255,255,255,.2);
  padding: 8px 14px; border-radius: 999px;
  cursor: pointer; font-weight: 600; font-size: 14px;
  backdrop-filter: blur(8px);
}
.lightbox-close { right: 16px; padding: 6px 12px; font-size: 18px; }
.lightbox-del { right: 64px; }
.lightbox-del:hover { background: rgba(255, 80, 80, .4); border-color: rgba(255, 80, 80, .6); }

/* ── Photo screensaver ─────────────────────────────────────────────────
   Full-screen slideshow. Two <img> layers crossfade; controls + caption
   fade out after a few idle seconds (.ss-idle) so the photo fills the
   screen uninterrupted. */
.screensaver {
  position: fixed; inset: 0;
  background: #000;
  z-index: 1200; /* above lightbox (1000) */
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  cursor: default;
}
.screensaver[hidden] { display: none; }
.screensaver.ss-idle { cursor: none; }
body.ss-open { overflow: hidden; }
.ss-stage {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
}
.ss-img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  opacity: 0;
  transition: opacity .9s ease;
  will-change: opacity;
}
.ss-img.is-active { opacity: 1; }
.ss-caption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 48px 24px 22px;
  text-align: center;
  color: #fff;
  font-size: 15px; font-weight: 600;
  letter-spacing: .01em;
  text-shadow: 0 1px 6px rgba(0,0,0,.8);
  background: linear-gradient(to top, rgba(0,0,0,.55), transparent);
  pointer-events: none;
  opacity: 1; transition: opacity .4s ease;
}
.ss-caption:empty { display: none; }
.ss-controls {
  position: absolute; left: 50%; bottom: 26px; transform: translateX(-50%);
  display: flex; align-items: center; gap: 14px;
  z-index: 2;
  opacity: 1; transition: opacity .4s ease;
}
.ss-btn {
  display: grid; place-items: center;
  width: 48px; height: 48px;
  border-radius: 999px;
  background: rgba(255,255,255,.14); color: #fff;
  border: 1px solid rgba(255,255,255,.22);
  cursor: pointer;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background .15s, transform .1s;
}
.ss-btn:hover { background: rgba(255,255,255,.26); }
.ss-btn:active { transform: scale(.94); }
.ss-close {
  position: absolute; top: 18px; right: 20px;
  width: 44px; height: 44px;
  border-radius: 999px;
  background: rgba(255,255,255,.14); color: #fff;
  border: 1px solid rgba(255,255,255,.22);
  font-size: 24px; line-height: 1; cursor: pointer;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  z-index: 2;
  transition: background .15s;
}
.ss-close:hover { background: rgba(255,80,80,.4); border-color: rgba(255,80,80,.6); }
/* Idle: hide chrome but keep the photo. */
.screensaver.ss-idle .ss-controls,
.screensaver.ss-idle .ss-caption,
.screensaver.ss-idle .ss-close { opacity: 0; pointer-events: none; }
.ss-empty {
  position: relative; z-index: 2;
  color: rgba(255,255,255,.85);
  text-align: center;
}
.ss-empty[hidden] { display: none; }
.ss-empty p { margin: 0; font-size: 20px; font-weight: 600; }
.ss-empty .ss-empty-sub { margin-top: 8px; font-size: 14px; font-weight: 400; color: rgba(255,255,255,.6); }
@media (prefers-reduced-motion: reduce) {
  .ss-img { transition: none; }
}
#entryInput {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 12px;
  outline: none; resize: none;
  transition: border-color .15s, background .15s, box-shadow .15s;
  font-family: inherit;
  font-size: 14px;
  line-height: 1.5;
  min-height: 44px;
  max-height: 220px;
  overflow-y: auto;
  width: 100%;
  box-sizing: border-box;
}
#entryInput:focus {
  border-color: var(--primary);
  background: var(--bg-elev);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* Mic record button — the elapsed-time chip floats above the button so it
   never overlaps the day-sections nav directly below the toolbar. */
.mic-btn { position: relative; }
.mic-btn.recording { color: var(--danger); animation: micPulse 1s infinite; }
.mic-btn.recording::after {
  content: attr(data-elapsed);
  position: absolute; left: 50%; bottom: calc(100% + 4px); transform: translateX(-50%);
  font-size: 10px; font-variant-numeric: tabular-nums;
  color: var(--danger); font-weight: 700;
  background: var(--bg-elev); padding: 1px 5px; border-radius: 4px;
  border: 1px solid var(--line);
  white-space: nowrap;
  pointer-events: none;
}
@keyframes micPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .5; }
}

/* Voice quick-add (dictation) button — visually distinct from the audio
   attachment mic. Primary-accented to signal it's the "smart" capture. */
.dictate-btn {
  position: relative;
  color: var(--primary);
  background: var(--primary-tint);
}
.dictate-btn:hover {
  color: var(--primary);
  background: var(--primary-tint);
  filter: brightness(0.97);
}
.dictate-btn.listening {
  color: var(--on-primary);
  background: var(--primary-fill);
  box-shadow: 0 0 0 4px var(--primary-tint);
}
.dictate-btn.listening::before {
  content: "";
  position: absolute; inset: -4px;
  border-radius: 10px;
  box-shadow: 0 0 0 0 var(--primary);
  animation: dictatePulse 1.4s ease-out infinite;
  pointer-events: none;
}
@keyframes dictatePulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 45%, transparent); }
  100% { box-shadow: 0 0 0 12px color-mix(in srgb, var(--primary) 0%, transparent); }
}

/* "Hey Lumi" wake-word toggle — lives inline with the dictate buttons.
   Small persistent indicator dot: hidden when off, faint pulse while
   listening for the wake word, solid while actively capturing a command. */
.lumi-toggle-btn {
  position: relative;
  color: var(--text-mute);
  background: transparent;
}
.lumi-toggle-btn:hover {
  color: var(--text);
  background: var(--bg-hover);
}
.lumi-toggle-btn[aria-pressed="true"] {
  color: var(--primary);
  background: var(--primary-tint);
}
.lumi-toggle-btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}
.lumi-dot {
  position: absolute;
  bottom: 2px; right: 2px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--text-mute);
  opacity: 0;
  transition: opacity .14s ease;
  pointer-events: none;
}
.lumi-toggle-btn.listening .lumi-dot {
  opacity: 0.6;
  background: var(--primary);
  animation: lumiBreathe 1.8s ease-in-out infinite;
}
.lumi-toggle-btn.capturing .lumi-dot {
  opacity: 1;
  background: var(--danger);
  animation: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 30%, transparent);
}
@keyframes lumiBreathe {
  0%, 100% { opacity: 0.25; transform: scale(0.85); }
  50%      { opacity: 0.85; transform: scale(1); }
}

/* Voice panel — appears under the entry input while dictating. */
.voice-panel {
  margin-top: 8px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-elev);
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: 8px;
  animation: voicePanelIn 0.16s ease-out;
}
@keyframes voicePanelIn {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: none; }
}
.voice-panel-head {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}
.voice-pulse {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--danger);
  animation: voiceDot 1s ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes voiceDot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .35; transform: scale(0.85); }
}
.voice-state {
  font-weight: 600; font-size: 13px;
  color: var(--text);
}
.voice-hint {
  font-size: 11px; color: var(--text-mute);
  margin-left: 4px;
}
.voice-actions {
  margin-left: auto;
  display: flex; gap: 6px;
}
.voice-btn {
  font-size: 12px; font-weight: 600;
  padding: 4px 10px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.voice-btn:hover { background: var(--bg-soft); }
.voice-btn.voice-stop {
  background: var(--primary-fill); color: var(--on-primary);
  border-color: var(--primary-fill);
}
.voice-btn.voice-stop:hover { filter: brightness(1.08); }
[data-theme="dark"] .voice-btn.voice-stop:hover { filter: brightness(1.15); }
.voice-transcript {
  font-size: 14px; line-height: 1.45;
  color: var(--text);
  min-height: 22px;
  white-space: pre-wrap;
  font-style: italic;
}
.voice-transcript:empty::before {
  content: 'Say something — e.g. "Dentist next Tuesday at 9am"';
  color: var(--text-mute);
  font-style: italic;
}
.voice-transcript .interim { opacity: 0.55; }
.voice-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.voice-chips:empty { display: none; }
.voice-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px;
  font-size: 11px; font-weight: 600;
  border-radius: 999px;
  background: var(--primary-tint);
  color: var(--primary);
  text-transform: capitalize;
}
.voice-chip.kind-milestone { background: color-mix(in srgb, var(--primary) 22%, transparent); }
.voice-chip-label {
  text-transform: uppercase;
  font-size: 9px; letter-spacing: .04em;
  opacity: 0.72;
}

/* Mood picker — now lives inside the mood popover */
.mood-pop { gap: 2px; padding: 4px; }
.mood-chip {
  background: none; border: 0; cursor: pointer;
  font-size: 20px; line-height: 1;
  padding: 4px 6px;
  border-radius: 6px;
  opacity: 0.55;
  filter: grayscale(.4);
  transition: opacity .12s, filter .12s, transform .12s, background .12s;
}
.mood-chip:hover { opacity: 1; filter: none; background: var(--bg-soft); }
.mood-chip.active { opacity: 1; filter: none; background: var(--primary-tint); transform: scale(1.15); }

/* Mood glyph on rendered entries */
.entry-meta-row {
  display: flex; align-items: center; gap: 8px;
  margin-top: 3px;
}
.entry-mood {
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  user-select: none;
  filter: saturate(1.1);
  opacity: .9;
}
.entry-mood:hover { opacity: 1; transform: scale(1.15); }

/* Insights mood tile */
.mood-tile-head { display: flex; align-items: center; gap: 16px; justify-content: space-between; }
.mood-value { display: flex; align-items: center; gap: 6px; }
.mood-glyph { font-size: 22px; line-height: 1; }
.mood-tile-sub { font-size: 11px; color: var(--text-mute); margin-top: 4px; }
.mood-spark { width: 140px; max-width: 50%; height: 36px; }

/* Entries list */
.entries { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.entry {
  /* See .pill — default to a neutral so untagged entries don't bleed accent
     into the day card. Tagged entries set --entry-color inline. */
  --entry-color: var(--text-mute);
  display: flex; align-items: flex-start; gap: 8px;
  width: 100%;
  padding: 8px 10px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--entry-color) 16%, var(--bg-soft));
  transition: background .12s;
  position: relative;
  animation: entryIn 0.2s ease-out;
}
@keyframes entryIn {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: none; }
}
.entry:hover { background: color-mix(in srgb, var(--entry-color) 26%, var(--bg-soft)); }
/* Holidays get the same tinted-pill treatment, driven by --holiday via --entry-color. */
.entry-text { flex: 1; min-width: 0; word-wrap: break-word; cursor: pointer; white-space: pre-wrap; }
.entry-text .tag {
  display: inline; font-weight: 600;
  color: var(--primary);
}
.entry-time {
  font-size: 11px; color: var(--text-mute);
  margin-top: 3px;
  font-variant-numeric: tabular-nums;
}
.entry-del {
  background: none; border: 0; cursor: pointer; color: var(--text-mute);
  padding: 4px 6px; border-radius: 6px;
  opacity: 0; transition: opacity .12s, color .12s, background .12s;
  flex-shrink: 0;
}
.entry:hover .entry-del,
.entry:focus-within .entry-del { opacity: 1; }
.entry-del:hover { color: var(--danger); background: var(--bg-elev); }

/* Todo-style checkbox on no-time entries. Sits left of the text, only
   appears when the entry has no happened_at + isn't all-day. */
.entry-check {
  flex-shrink: 0;
  width: 18px; height: 18px;
  margin-top: 2px;
  border-radius: 5px;
  border: 1.5px solid color-mix(in srgb, var(--entry-color) 60%, var(--text-mute));
  background: var(--bg-elev);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: transparent;
  transition: background .12s, color .12s, border-color .12s, transform .08s;
  padding: 0;
}
.entry-check:hover { border-color: var(--entry-color); background: color-mix(in srgb, var(--entry-color) 14%, var(--bg-elev)); }
.entry-check:active { transform: scale(.92); }
.entry-check.is-done {
  background: var(--entry-color);
  border-color: var(--entry-color);
  color: var(--on-primary, #fff);
}
.entry-check:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* Completed entry: dim + strikethrough the text. The chip stays visible
   on its original day; the checkbox is the undo path. */
.entry.is-done { opacity: .55; }
.entry.is-done .entry-text { text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--text-mute) 70%, transparent); }
.entry.is-done:hover { opacity: .85; }

/* Same treatment on grid pills so completed todos read as "done" at a glance. */
.pill.is-done { opacity: .5; text-decoration: line-through; text-decoration-color: color-mix(in srgb, currentColor 60%, transparent); }

/* Original-date chip shown in the Overdue group so each rolled-over
   todo carries its own date. */
.entry-origdate {
  font-size: 11px;
  color: var(--text-mute);
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--bg-elev);
  font-variant-numeric: tabular-nums;
}

/* "Overdue" group container — a labelled section above today's entries
   that surfaces uncompleted no-time todos from prior days. */
.entries-group {
  list-style: none;
  padding: 0;
  margin: 0 0 4px 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.entries-group-head {
  display: flex; align-items: center; gap: 8px;
  padding: 2px 4px;
}
.entries-group-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-weight: 600;
  color: var(--text-mute);
}
.entries-group-count {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-mute);
  background: var(--bg-elev);
  padding: 1px 6px;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
.entries-group-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex; flex-direction: column;
  gap: 6px;
}
/* The overdue list sits on a subtle tinted background so it visually
   separates from "today's stuff" without being noisy. */
.overdue-group .entries-group-title { color: var(--warn); }

/* ===== "By person" responsibility lanes (#9) ===== */
.layout-seg { margin-left: 6px; }
.person-lane { margin-bottom: 10px; }
.person-lane-head {
  border-bottom: 1px solid var(--line);
  padding-bottom: 6px;
}
.person-lane-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--owner-color, var(--text-mute));
  flex: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--owner-color, transparent) 18%, transparent);
}
.person-lane .entries-group-title { color: var(--owner-color, var(--text)); }
.person-lane-you {
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-mute);
}
.person-lane-unassigned .person-lane-dot { background: var(--text-mute); box-shadow: none; }
.person-lane-unassigned .entries-group-title { color: var(--text-mute); }
@media (max-width: 640px) {
  .layout-seg { order: 100; flex-basis: 100%; margin-top: 4px; margin-left: 0; }
}

/* Inline-edit textarea */
.entry-edit {
  width: 100%;
  background: var(--bg-elev);
  border: 1px solid var(--primary);
  border-radius: 8px;
  padding: 6px 8px;
  outline: none;
  resize: none;
  font-family: inherit;
  font-size: inherit;
  line-height: 1.45;
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.empty-day {
  text-align: center; padding: 16px 8px;
  color: var(--text-mute); font-size: 12px;
  border: 1px dashed var(--line); border-radius: 10px;
}

/* Milestones */
.milestones { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.milestone {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-elev);
  transition: background .12s, border-color .12s;
}
.milestone:hover { background: var(--bg-hover); border-color: var(--line-strong); }
.milestone.done .ms-title { text-decoration: line-through; color: var(--text-mute); }
.ms-check {
  appearance: none; -webkit-appearance: none;
  width: 18px; height: 18px; border-radius: 5px;
  border: 1.5px solid var(--line-strong); background: var(--bg-elev);
  cursor: pointer; flex-shrink: 0; margin-top: 1px;
  display: grid; place-items: center;
  transition: background .12s, border-color .12s;
}
.ms-check:hover { border-color: var(--primary); }
.ms-check:checked {
  background: var(--success); border-color: var(--success);
}
.ms-check:checked::after {
  content: ""; width: 4px; height: 8px;
  border: solid white; border-width: 0 2px 2px 0;
  transform: rotate(45deg) translate(-1px, -1px);
}
.ms-body { flex: 1; min-width: 0; cursor: pointer; }
.ms-title-row {
  display: flex; align-items: center; gap: 6px;
  min-width: 0;
}
.ms-title {
  font-weight: 600; font-size: 13px; word-wrap: break-word;
  flex: 1; min-width: 0;
}
.ms-meta {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin-top: 2px; font-size: 11px; color: var(--text-mute);
}
.ms-notes {
  margin-top: 3px;
  font-size: 11px;
  color: var(--text-soft);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ms-meta .due { color: var(--text-soft); font-weight: 500; }
.ms-meta .overdue { color: var(--danger); font-weight: 700; }
.ms-meta .soon { color: var(--warn); font-weight: 700; }
.ms-meta .completed { color: var(--success); font-weight: 700; }

.empty {
  color: var(--text-mute); font-size: 12px; padding: 8px 4px 0;
  text-align: center;
}

/* ============================ Footer ============================ */

.footer {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 16px;
  border-top: 1px solid var(--line);
  color: var(--text-mute); font-size: 11px;
  background: var(--bg);
}
.foot-left { display: flex; align-items: center; gap: 8px; }
.foot-right { display: flex; align-items: center; gap: 8px; }
.dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 25%, transparent);
  flex-shrink: 0;
}
.dot.saving {
  background: var(--warn);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--warn) 25%, transparent);
  animation: syncPulse 1.2s ease-in-out infinite;
}
.dot.error { background: var(--danger); box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 25%, transparent); }
@keyframes syncPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* ============================ Modal ============================ */

.modal-root {
  position: fixed; inset: 0; z-index: 50;
  display: grid; place-items: center;
  padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}
.modal-backdrop {
  position: absolute; inset: 0;
  background: color-mix(in srgb, #000 50%, transparent);
  backdrop-filter: blur(8px) saturate(120%);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
}
.modal {
  position: relative; z-index: 1;
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100dvh - 60px);
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  display: flex; flex-direction: column;
  animation: pop .18s ease;
}
@keyframes pop {
  from { transform: translateY(8px) scale(.98); opacity: 0; }
  to { transform: none; opacity: 1; }
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  padding: 14px 16px; border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.modal-head h3 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.modal-body { padding: 16px; overflow: auto; }
.modal-lead { color: var(--text-soft); margin: 0 0 14px; line-height: 1.5; }

/* Recurring-event delete scope chooser: a vertical stack of full-width
   choices (this / following / all) above the Cancel row. */
.recur-scope-choices {
  display: flex; flex-direction: column;
  gap: 8px;
  margin-bottom: 14px;
}
.recur-scope-opt {
  width: 100%;
  justify-content: flex-start;
  text-align: left;
  padding: 12px 14px;
  font-weight: 600;
}
.recur-scope-opt:last-child {
  color: var(--danger, #dc2626);
  border-color: color-mix(in srgb, var(--danger, #dc2626) 35%, var(--line));
}

/* Share modal */
.share-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
}
@media (max-width: 640px) { .share-grid { grid-template-columns: 1fr; } }
.share-tile {
  display: block; text-align: left;
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: var(--radius-md); padding: 14px;
  cursor: pointer; width: 100%;
  font: inherit; color: inherit;
  transition: background .12s, border-color .12s, transform .05s;
}
.share-tile:hover { background: var(--bg-hover); border-color: var(--line-strong); }
.share-tile:active { transform: translateY(1px); }
.tile-icon {
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--primary-tint); color: var(--primary);
  display: grid; place-items: center; margin-bottom: 10px;
}
.tile-title { font-weight: 700; font-size: 13px; margin-bottom: 2px; }
.tile-sub { font-size: 12px; color: var(--text-mute); }

.paste-pane { margin-top: 14px; }
.paste-pane summary {
  cursor: pointer; color: var(--text-soft); font-size: 12px;
  padding: 6px 0;
}
.paste-pane textarea {
  width: 100%; margin-top: 8px;
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 12px; outline: none;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; resize: vertical;
}
.paste-pane textarea:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring); }
.paste-actions {
  display: flex; align-items: center; gap: 10px; margin-top: 8px;
}
.paste-status { font-size: 12px; color: var(--text-mute); }
.paste-status.ok { color: var(--success); }
.paste-status.err { color: var(--danger); }
.paste-status.loading { color: var(--text-mute); }
.paste-status.loading::before {
  content: ""; display: inline-block; width: 10px; height: 10px;
  margin-right: 6px; vertical-align: -1px; border-radius: 50%;
  border: 2px solid var(--line-strong); border-top-color: var(--primary);
  animation: paste-status-spin 0.7s linear infinite;
}
@keyframes paste-status-spin { to { transform: rotate(360deg); } }

/* Import modal */
.import-summary {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: 10px; padding: 12px 14px; margin-bottom: 14px;
  font-size: 13px; color: var(--text-soft);
}
.import-summary strong { color: var(--text); }
.import-summary .row { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; }
.import-actions { display: flex; flex-direction: column; gap: 8px; }
.import-choice {
  display: block; text-align: left; width: 100%;
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: var(--radius-md); padding: 12px 14px;
  cursor: pointer; font: inherit; color: inherit;
  transition: background .12s, border-color .12s;
}
.import-choice:hover { background: var(--bg-hover); border-color: var(--line-strong); }
.import-choice.danger:hover { border-color: var(--danger); background: var(--danger-soft); }
.import-choice.danger .ic-title { color: var(--danger); }
.import-choice.ghost { background: transparent; }
.ic-title { font-weight: 700; font-size: 13px; }
.ic-sub { font-size: 12px; color: var(--text-mute); margin-top: 2px; }

/* Form fields */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.field-label { font-size: 12px; color: var(--text-soft); font-weight: 600; }
.field input, .field textarea {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 12px; outline: none;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.field input:focus, .field textarea:focus {
  border-color: var(--primary); background: var(--bg-elev);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.field textarea { resize: vertical; min-height: 70px; }

/* Dark mode: date/time picker icons */
[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type="time"]::-webkit-calendar-picker-indicator {
  filter: invert(.85);
}

.form-actions {
  display: flex; align-items: center; gap: 8px; margin-top: 6px;
  flex-wrap: wrap;
}
.spacer { flex: 1; }

.settings-stats {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 12px;
  color: var(--text-soft);
  margin-bottom: 12px;
  display: flex; flex-wrap: wrap; gap: 14px;
}
.settings-stats strong { color: var(--text); font-weight: 700; }

/* Active sessions panel inside Settings. */
.settings-section {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.settings-section-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.settings-section-title {
  margin: 0; font-size: 14px; font-weight: 700; color: var(--text);
}
.settings-section-sub {
  margin: 4px 0 10px; font-size: 12px; color: var(--text-mute); line-height: 1.4;
}
.sessions-list { list-style: none; padding: 0; margin: 0 0 10px; display: grid; gap: 8px; }
.sessions-empty {
  padding: 10px 12px; font-size: 12px; color: var(--text-mute);
  background: var(--bg-soft); border: 1px dashed var(--line); border-radius: 8px;
}
.session-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.session-meta { flex: 1; min-width: 0; }
.session-title {
  font-size: 13px; font-weight: 600; color: var(--text);
  display: flex; align-items: center; gap: 8px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.session-sub {
  font-size: 12px; color: var(--text-mute); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.session-sub code {
  font-family: inherit; background: transparent; padding: 0;
  color: var(--text-soft);
}
.session-tag {
  font-size: 11px; font-weight: 600; padding: 2px 6px; border-radius: 6px;
  background: var(--accent-soft, rgba(79,70,229,0.12));
  color: var(--accent, #4f46e5);
  letter-spacing: 0.02em;
}
.session-actions { flex-shrink: 0; }

.shortcuts { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.shortcuts li { display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--text-soft); }
.shortcuts li .keys { min-width: 80px; }
.shortcuts li > span:last-child { flex: 1; }

/* Toast */
.toast {
  position: fixed;
  bottom: calc(22px + env(safe-area-inset-bottom));
  left: 50%; transform: translateX(-50%);
  background: var(--text); color: var(--bg-elev);
  padding: 10px 16px; border-radius: 999px;
  font-size: 13px; font-weight: 600;
  box-shadow: var(--shadow-lg);
  z-index: 100;
  animation: toast .25s ease;
  display: flex; align-items: center; gap: 12px;
  max-width: calc(100vw - 32px);
}
.toast-action {
  background: transparent; border: 0; padding: 2px 4px;
  color: var(--primary); font-weight: 700; cursor: pointer;
  text-decoration: underline;
  font-size: 13px;
}
[data-theme="dark"] .toast-action { color: var(--accent); }
@keyframes toast {
  from { transform: translate(-50%, 8px); opacity: 0; }
  to { transform: translate(-50%, 0); opacity: 1; }
}
/* Phones: slide the toast left of the PTT FAB so they don't overlap. */
@media (max-width: 880px) {
  body[data-scene="calendar"]:not(.no-ptt) .toast {
    right: calc(96px + env(safe-area-inset-right));
    left: 16px;
    transform: none;
    max-width: calc(100vw - 112px);
    animation: none;
  }
}

/* ============================ Year view (12-month grid) ============================ */

.year-view {
  padding: 16px;
  overflow-y: auto;
}
.year-months-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}
@media (max-width: 1180px) {
  .year-months-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .year-months-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.ym-card {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.ym-card.current {
  border-color: color-mix(in srgb, var(--primary) 60%, var(--line));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent) inset;
}
.ym-head {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 2px 4px;
  text-align: left;
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  cursor: pointer;
  border-radius: 6px;
  transition: background .12s ease, color .12s ease;
}
.ym-head:hover { background: var(--bg-soft); color: var(--primary); }
.ym-head:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.ym-dow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  font-size: 10px;
  color: var(--text-mute);
  text-transform: uppercase;
  letter-spacing: .05em;
  font-weight: 600;
  text-align: center;
}
.ym-dow > span { padding: 2px 0; }
.ym-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.ym-day {
  appearance: none;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 11px;
  line-height: 1;
  min-height: 26px;
  padding: 0;
  border-radius: 6px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: background .1s ease, border-color .12s ease, transform .08s ease;
}
.ym-day.out { visibility: hidden; cursor: default; }
.ym-day:hover { border-color: var(--text-mute); }
.ym-day:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.ym-day.l1 { background: color-mix(in srgb, var(--primary) 12%, transparent); }
.ym-day.l2 { background: color-mix(in srgb, var(--primary) 26%, transparent); }
.ym-day.l3 { background: color-mix(in srgb, var(--primary) 44%, transparent); }
.ym-day.l4 { background: color-mix(in srgb, var(--primary) 64%, transparent); color: #fff; }
.ym-day.today {
  background: var(--primary);
  color: #fff;
  font-weight: 700;
}
.ym-day.selected:not(.today) {
  border-color: var(--primary);
}
.ym-day.milestone::after {
  content: "";
  position: absolute;
  bottom: 2px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--warn);
}
.ym-num { pointer-events: none; }

/* ============================ NLP preview ============================ */

.nlp-preview {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin-top: 6px;
  padding: 6px 10px;
  background: var(--primary-tint);
  border-radius: 8px;
  font-size: 11px;
  color: var(--text-soft);
  animation: pop .15s ease;
}
.nlp-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 8px;
  font-weight: 600;
  color: var(--text);
}
.nlp-chip .nlp-label { color: var(--text-mute); font-weight: 500; margin-right: 2px; }

/* ============================ On this day list ============================ */

.otd-count {
  margin-left: auto;
  font-size: 11px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 999px; padding: 1px 8px;
  color: var(--text-mute); font-weight: 600;
  text-transform: none; letter-spacing: 0;
}
.otd-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.otd-item {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 10px;
  background: var(--bg-elev);
  border-radius: 8px;
  border-left: 3px solid var(--accent);
}
.otd-when {
  font-size: 11px; color: var(--text-mute); font-weight: 600;
}
.otd-text {
  white-space: pre-wrap; word-wrap: break-word;
  color: var(--text);
}

/* ============================ Day section tabs ============================ */

.day-sections {
  display: flex; gap: 4px;
  margin: 0 0 8px;
  padding: 4px;
  background: var(--bg-soft);
  border-radius: 10px;
  border: 1px solid var(--line);
}
.day-sec-tab {
  flex: 1;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px;
  background: none; border: 0; cursor: pointer;
  padding: 6px 10px; border-radius: 7px;
  color: var(--text-mute);
  font-size: 12px; font-weight: 600;
  transition: color .12s, background .12s;
  position: relative;
}
.day-sec-tab:hover { color: var(--text); }
.day-sec-tab.active {
  background: var(--bg-elev);
  color: var(--primary);
  box-shadow: var(--shadow-sm);
}
.day-sec-tab.has-content { color: var(--text); }
.day-sec-tab.active.has-content { color: var(--primary); }
.day-sec-tab:not(.has-content):not(.active) { opacity: 0.55; }
.day-section-empty {
  color: var(--text-mute);
  font-size: 12px;
  font-style: italic;
  list-style: none;
  padding: 4px 0;
}
.day-sec-count {
  font-size: 10px; font-variant-numeric: tabular-nums;
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 999px; padding: 0 5px; min-width: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-mute);
}
.day-sec-tab.active .day-sec-count { background: var(--primary-tint); color: var(--primary); border-color: var(--primary-tint); }
.day-sec-count:empty { display: none; }
.day-sec-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--primary);
}
.day-sec-label { white-space: nowrap; }

.day-section-panels { margin-bottom: 0; }
.day-section-panels:has([data-section-panel]:not([hidden])) { margin-bottom: 12px; }
.day-section {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 0;
}
.day-section[hidden] { display: none; }
.day-section-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 8px;
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); font-weight: 700;
}
.day-section-title { color: var(--text-mute); }

/* Resurface list (inside the "Past" section panel) */
.resurface-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.resurface-item {
  cursor: pointer;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--bg-elev);
  border-left: 3px solid var(--accent, var(--primary));
  transition: filter .12s;
}
.resurface-item:hover { filter: brightness(.98); }
.resurface-when { font-size: 11px; color: var(--text-mute); font-weight: 600; margin-bottom: 2px; }
.resurface-text { color: var(--text); white-space: pre-wrap; word-wrap: break-word; }

/* ============================ Year in Review ============================ */

.year-review-modal { max-width: 760px; width: min(95vw, 760px); }
.year-review-year {
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: 8px;
  padding: 4px 10px; font-weight: 700; color: var(--text); cursor: pointer;
  font-size: 14px;
}

.yr-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.yr-card {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 16px;
  min-height: 96px;
}
.yr-card-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); font-weight: 700; margin-bottom: 8px;
}
.yr-card-value { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; color: var(--text); }
.yr-card-sub { font-size: 12px; color: var(--text-mute); margin-top: 4px; }

.yr-headline {
  grid-column: 1 / -1;
  background: linear-gradient(135deg, var(--primary), var(--accent, var(--primary)));
  color: white; border: 0;
  text-align: center;
}
.yr-headline-big { font-size: 64px; font-weight: 800; letter-spacing: -0.04em; line-height: 1; }
.yr-headline-label { font-size: 14px; font-weight: 600; opacity: .9; margin-top: 4px; }
.yr-headline-sub { font-size: 12px; opacity: .8; margin-top: 8px; }

.yr-months { grid-column: 1 / -1; }
.yr-month-grid {
  display: grid; grid-template-columns: repeat(12, 1fr);
  gap: 4px; height: 80px; align-items: end;
  margin-top: 8px;
}
.yr-month { display: flex; flex-direction: column; align-items: center; justify-content: end; gap: 4px; }
.yr-month-bar {
  width: 70%; background: linear-gradient(180deg, var(--primary), var(--accent));
  border-radius: 4px; min-height: 2px;
  transition: filter .15s;
}
.yr-month-bar:hover { filter: brightness(1.2); }
.yr-month-label { font-size: 10px; color: var(--text-mute); font-weight: 700; }

.yr-tag-row {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 0;
  font-size: 13px;
}
.yr-tag-rank { color: var(--text-mute); font-weight: 700; font-size: 11px; width: 18px; }
.yr-tag-name { flex: 1; font-weight: 700; }
.yr-tag-count { color: var(--text-mute); font-variant-numeric: tabular-nums; font-weight: 700; }

.yr-list { margin: 8px 0 0; padding-left: 18px; font-size: 13px; }
.yr-list li { margin: 3px 0; }

.yr-mood-grid { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.yr-mood-chip {
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 10px;
  font-size: 13px; font-weight: 700;
}

.yr-longest { grid-column: 1 / -1; }
.yr-longest-text {
  margin-top: 6px;
  padding: 10px 12px;
  background: var(--bg-elev); border-left: 3px solid var(--primary); border-radius: 0 8px 8px 0;
  color: var(--text);
  font-style: italic;
  white-space: pre-wrap;
  max-height: 180px; overflow-y: auto;
}
.yr-empty { color: var(--text-mute); font-size: 12px; font-style: italic; }

@media (max-width: 600px) {
  .yr-grid { grid-template-columns: 1fr; }
  .yr-month-grid { height: 60px; }
  .yr-headline-big { font-size: 48px; }
}

/* ============================ Markdown bits ============================ */

.entry-text .md-h, .otd-text .md-h, .resurface-text .md-h {
  font-size: 14px; font-weight: 700;
  margin: 6px 0 2px;
  letter-spacing: -0.01em;
}
.md-ul {
  margin: 4px 0 4px 18px;
  padding: 0;
  list-style: disc;
}
.md-ul li { margin: 2px 0; }
.md-q {
  margin: 6px 0;
  padding: 4px 10px;
  border-left: 3px solid var(--line);
  color: var(--text-soft);
  background: var(--bg-elev);
  border-radius: 0 8px 8px 0;
}
.md-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 90%;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 4px;
}
.md-a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; }
.md-a:hover { filter: brightness(.9); }

/* ============================ Journal (private) ============================ */

.journal-private {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-mute);
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 8px;
}
.journal-status {
  margin-left: auto;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
  min-height: 14px;
  text-transform: none;
  letter-spacing: 0;
}
.journal-status.saving { color: var(--text-mute); }
.journal-status.ok     { color: var(--primary); }
.journal-status.err    { color: var(--danger); }
.journal-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  font-family: inherit;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
  resize: vertical;
  min-height: 110px;
  max-height: 60vh;
  outline: none;
  transition: border-color .12s, box-shadow .12s, min-height .18s;
}
.journal-input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
  min-height: 160px;
}
.journal-input::placeholder { color: var(--text-mute); font-style: italic; }
/* Empty + unfocused: the input collapses to a quieter resting state so the
   journal pane doesn't dominate the day card on days with no entry. */
.journal-input:placeholder-shown:not(:focus) {
  min-height: 72px;
  background: var(--bg-soft);
}

.journal-prompt {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px;
  margin-bottom: 8px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text-soft);
  font-size: 13px;
  font-style: italic;
  cursor: text;
  transition: border-color .12s;
}
.journal-prompt:hover { border-color: var(--line-strong); }
.journal-prompt-label {
  font-size: 9px; text-transform: uppercase; letter-spacing: .08em;
  font-weight: 700; color: var(--primary); font-style: normal;
  background: var(--primary-tint);
  border-radius: 999px;
  padding: 2px 8px;
  flex-shrink: 0;
}
.journal-prompt-text { flex: 1; min-width: 0; }
.journal-prompt-skip {
  background: var(--bg-elev); border: 1px solid var(--line); cursor: pointer;
  color: var(--text-mute);
  width: 24px; height: 24px; border-radius: 50%;
  display: inline-grid; place-items: center;
  font-style: normal;
  transition: color .12s, border-color .12s, transform .2s, background .12s;
  flex-shrink: 0;
}
.journal-prompt-skip:hover {
  color: var(--primary);
  border-color: var(--primary);
  background: var(--primary-tint);
  transform: rotate(-60deg);
}
.journal-prompt-skip:focus-visible { outline-offset: 1px; }

/* ============================ Insights ============================ */

.insights-card .insights-seg { margin-left: auto; }

.insights {
  display: flex; flex-direction: column; gap: 10px;
}

/* Compact 4-up stat strip */
.ins-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 8px 4px;
}
.ins-stat {
  display: flex; flex-direction: column; align-items: center;
  padding: 2px 4px;
  border-right: 1px solid var(--line);
}
.ins-stat:last-child { border-right: 0; }
.ins-stat-v {
  font-size: 18px; font-weight: 700; letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
  color: var(--text); line-height: 1.1;
}
.ins-stat-l {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-mute); font-weight: 700;
  margin-top: 2px;
}

/* Mood mini-tile */
.ins-mood {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 8px 12px;
}
.ins-mood-glyph { font-size: 26px; line-height: 1; }
.ins-mood-stat { display: flex; flex-direction: column; min-width: 0; }
.ins-mood-avg {
  font-size: 16px; font-weight: 700; letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums; color: var(--text);
}
.ins-mood-of { font-size: 11px; font-weight: 600; color: var(--text-mute); margin-left: 2px; }
.ins-mood-n { font-size: 10px; color: var(--text-mute); font-weight: 600; }
.ins-mood-spark { margin-left: auto; width: 100px; }
.ins-mood-spark .mood-spark { width: 100%; height: 28px; max-width: none; }

/* Section heading + content blocks */
.ins-section {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 8px 12px;
}
.ins-section-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-mute); font-weight: 700;
  margin-bottom: 6px;
}

/* Up next compact list */
.ins-upnext { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.ins-upnext li {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 6px; border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
}
.ins-upnext li:hover { background: var(--bg-hover); }
.ins-upnext-title { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ins-upnext-due { font-size: 11px; font-weight: 700; }
.ins-upnext-due.overdue { color: var(--danger); }
.ins-upnext-due.soon    { color: var(--warn); }
.ins-upnext-due.due     { color: var(--text-soft); }

.top-tags { display: flex; flex-direction: column; gap: 4px; }
.top-tag {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 8px; align-items: center;
}
.top-tag-name {
  font-weight: 600; font-size: 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.top-tag-bar {
  height: 6px; border-radius: 3px;
  background: var(--bg-soft);
  overflow: hidden;
}
.top-tag-bar > i {
  display: block; height: 100%; border-radius: 3px;
  background: var(--tt-color, var(--primary));
}
.top-tag-count {
  font-size: 11px; color: var(--text-mute); font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.insights-empty { color: var(--text-mute); font-size: 12px; text-align: center; padding: 12px; }

/* Milestone progress bar */
.ms-progress-wrap { margin-top: 6px; }
.ms-progress {
  height: 4px; border-radius: 2px;
  background: var(--bg-soft); overflow: hidden;
}
.ms-progress > i {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--primary), var(--accent));
  transition: width .25s ease;
  border-radius: 2px;
}
.ms-progress-meta {
  display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
  font-size: 11px; color: var(--text-mute);
  margin-top: 5px;
  font-variant-numeric: tabular-nums;
}
.ms-progress-num { font-weight: 600; color: var(--text-soft); }
.ms-progress-last { color: var(--text-mute); }
.ms-proj-inline {
  margin-left: auto;
  font-weight: 700;
  font-size: 10px; letter-spacing: .02em;
  padding: 1px 6px; border-radius: 999px;
  background: var(--bg-soft);
  color: var(--text-soft);
  cursor: help;
}
.ms-proj-inline.on-track { color: var(--primary); background: var(--primary-tint); }
.ms-proj-inline.behind   { color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); }

.ms-recur-chip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px;
  font-size: 11px; font-weight: 700;
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--text-mute);
  flex-shrink: 0;
  cursor: help;
}

.habit-grid {
  margin-top: 6px;
  display: grid;
  grid-template-columns: repeat(30, 1fr);
  gap: 2px;
  max-height: 10px;
}
.habit-cell {
  display: block; width: 100%; height: 8px;
  background: var(--bg-soft);
  border-radius: 2px;
  opacity: 0.4;
  transition: opacity .12s, transform .12s;
}
.habit-cell.hit { opacity: 1; }
.habit-cell:hover { transform: scaleY(1.6); opacity: 1; }
.ms-track-chip {
  display: inline-flex; align-items: center;
  background: var(--primary-tint); color: var(--primary);
  border-radius: 999px; padding: 1px 7px;
  font-size: 10px; font-weight: 700;
}

/* ============================ Command palette ============================ */

.palette-modal {
  width: min(640px, calc(100vw - 32px));
  max-height: min(560px, calc(100dvh - 80px));
  align-self: start;
  margin-top: 12vh;
  display: flex; flex-direction: column;
}
.palette-input-row {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}
.palette-icon { color: var(--text-mute); flex-shrink: 0; }
#paletteInput {
  flex: 1; min-width: 0;
  background: transparent; border: 0; outline: none;
  font-size: 16px;
  color: var(--text);
}
.palette-hint {
  flex-shrink: 0;
}
.palette-results {
  flex: 1;
  overflow-y: auto;
  padding: 6px;
}
.palette-group-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); font-weight: 700;
  padding: 8px 10px 4px;
}
.palette-row {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.palette-row[aria-selected="true"] {
  background: var(--primary-tint);
}
.palette-row .pi {
  width: 28px; height: 28px;
  border-radius: 8px;
  background: var(--bg-soft);
  display: grid; place-items: center;
  color: var(--text-soft);
  flex-shrink: 0;
}
.palette-row[aria-selected="true"] .pi {
  background: var(--bg-elev); color: var(--primary);
}
.palette-row .pt {
  flex: 1; min-width: 0;
  font-size: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.palette-row .pt .psecondary {
  display: block;
  font-size: 11px;
  color: var(--text-mute);
  margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.palette-row .pkbd {
  font-size: 10px; color: var(--text-mute);
}
.palette-row mark {
  background: color-mix(in srgb, var(--warn) 30%, transparent);
  color: inherit;
  border-radius: 3px;
  padding: 0 2px;
}
.palette-foot {
  border-top: 1px solid var(--line);
  padding: 8px 14px;
  font-size: 11px;
  color: var(--text-mute);
  display: flex; gap: 16px;
  flex-wrap: wrap;
}
.palette-empty {
  padding: 20px;
  text-align: center;
  color: var(--text-mute);
  font-size: 13px;
}

/* Field row + hints (for milestone modal) */
.field-row { display: grid; grid-template-columns: 1fr 110px; gap: 10px; }
.field-narrow input { text-align: center; font-variant-numeric: tabular-nums; }
.field-hint { color: var(--text-mute); font-weight: 500; font-size: 11px; }
.field-hint-block {
  font-size: 11px; color: var(--text-mute);
  margin: -8px 0 12px;
}

/* Milestone notification image */
.ms-image-section { gap: 8px; }
.ms-image-row { display: flex; align-items: center; gap: 10px; }
.ms-image-status { font-size: 11px; color: var(--text-mute); }
.ms-image-preview {
  margin-top: 6px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  max-width: 280px;
}
.ms-image-preview img { display: block; width: 100%; height: auto; }

/* ============================ Print ============================ */

@media print {
  @page { size: landscape; margin: 12mm; }
  body { background: white; color: black; }
  .topbar, .footer, .side, .modal-root, .toast, .mobile-tabs, .focusbar { display: none !important; }
  .app { display: block; padding: 0; max-width: none; }
  .layout { display: block; }
  .cal-panel { border: none; box-shadow: none; }
  .cell { min-height: 110px; }
  .cell.today .day-num { background: black; color: white; }
  .pill { background: #f4f4f4 !important; color: black !important; border-left-color: #888 !important; }
  .pill.milestone { background: #e8e8ff !important; }
}

/* ============================================================
   Chat — "Ask your calendar" conversational agent
   ============================================================ */

.chat-btn { color: var(--primary); }
.chat-btn:hover { background: var(--primary-tint); }

.chat-modal {
  width: min(620px, calc(100vw - 24px));
  height: min(720px, calc(100dvh - 40px));
  max-height: calc(100dvh - 40px);
}
.chat-modal .modal-head { gap: 6px; }
.chat-modal .modal-head h3 { flex: 1; }
.chat-clear { color: var(--text-mute); }
.chat-clear:hover { color: var(--primary); background: var(--primary-tint); }

.chat-body {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
}
.chat-suggestions {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 12px 16px 0;
}
.chat-chip {
  font-size: 12px; font-weight: 500;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--text-soft);
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s, transform .12s;
}
.chat-chip:hover {
  background: var(--primary-tint);
  color: var(--primary);
  border-color: var(--primary);
}
.chat-chip:active { transform: scale(0.97); }

.chat-messages {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 12px;
  scroll-behavior: smooth;
}
.chat-msg {
  display: flex; flex-direction: column; gap: 4px;
  max-width: 86%;
  animation: chatMsgIn 0.18s ease-out;
}
@keyframes chatMsgIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
.chat-msg.user { align-self: flex-end; }
.chat-msg.assistant { align-self: flex-start; }

.chat-bubble {
  padding: 10px 14px;
  font-size: 14px; line-height: 1.5;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.chat-msg.user .chat-bubble {
  background: var(--primary-fill);
  color: var(--on-primary);
  border-radius: 16px 16px 4px 16px;
}
.chat-msg.assistant .chat-bubble {
  background: var(--bg-soft);
  color: var(--text);
  border-radius: 16px 16px 16px 4px;
}
.chat-msg.assistant .chat-bubble:empty::before {
  content: "…";
  color: var(--text-mute);
  letter-spacing: 0.2em;
  font-weight: 700;
  animation: chatDots 1.2s steps(3, end) infinite;
}
@keyframes chatDots {
  0%, 100% { opacity: 0.3; }
  50%      { opacity: 1; }
}

.chat-tools {
  display: flex; flex-direction: column; gap: 2px;
  margin-bottom: 2px;
}
.chat-tools:empty { display: none; }
.chat-tool {
  font-size: 11px; color: var(--text-mute);
  display: inline-flex; align-items: center; gap: 6px;
  padding-left: 4px;
}
.chat-tool::before {
  content: "";
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-mute);
  display: inline-block;
  flex-shrink: 0;
}
.chat-tool.running::before {
  background: var(--primary);
  animation: chatToolPulse 0.9s ease-in-out infinite;
}
@keyframes chatToolPulse {
  0%, 100% { opacity: 0.4; transform: scale(0.85); }
  50%      { opacity: 1;   transform: scale(1.15); }
}

.chat-input-row {
  display: flex; align-items: flex-end; gap: 8px;
  padding: 10px 12px;
  border-top: 1px solid var(--line);
  background: var(--bg-elev);
  flex-shrink: 0;
}
.chat-input-row textarea {
  flex: 1;
  resize: none;
  font: inherit;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-soft);
  color: var(--text);
  max-height: 140px;
  line-height: 1.4;
  outline: none;
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.chat-input-row textarea::placeholder { color: var(--text-mute); }
.chat-input-row textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.chat-send {
  padding: 8px 14px;
  border-radius: 12px;
  align-self: stretch;
}

/* Schedule-by-voice mic in the composer */
.chat-mic {
  align-self: stretch;
  flex-shrink: 0;
  width: 40px;
  border-radius: 12px;
  color: var(--text-mute);
  transition: color .12s, background .12s, box-shadow .12s, transform .12s;
}
.chat-mic:hover { color: var(--primary); background: var(--primary-tint); }
.chat-mic.listening {
  color: #fff;
  background: var(--danger);
  border-color: var(--danger);
  animation: pulse-rec 1.1s ease-in-out infinite;
}
.chat-mic.busy { color: var(--primary); background: var(--primary-tint); }
.chat-mic[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

/* Header mute toggle — swap the speaker icon by state */
.chat-speak-toggle { color: var(--text-mute); }
.chat-speak-toggle:hover { color: var(--primary); background: var(--primary-tint); }
.chat-speak-toggle .icon-off { display: none; }
.chat-speak-toggle.muted { color: var(--danger); }
.chat-speak-toggle.muted .icon-on { display: none; }
.chat-speak-toggle.muted .icon-off { display: inline; }

/* Voice state bar — idle→listening→thinking→speaking */
.chat-voice {
  display: flex; align-items: center; gap: 10px;
  margin: 0 12px 8px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-soft);
  font-size: 13px;
  color: var(--text);
}
.chat-voice[hidden] { display: none; }
.chat-voice-pulse {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--danger); flex-shrink: 0;
  animation: pulse-rec 1.1s ease-in-out infinite;
}
.chat-voice[data-phase="thinking"] .chat-voice-pulse { background: var(--primary); animation: pulseSubtle 1s ease-in-out infinite; }
.chat-voice[data-phase="speaking"] .chat-voice-pulse { background: var(--primary-fill); animation: pulseSubtle 1s ease-in-out infinite; }
.chat-voice-state { font-weight: 600; flex-shrink: 0; }
.chat-voice-transcript {
  flex: 1; min-width: 0;
  color: var(--text-mute);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chat-voice-stop {
  flex-shrink: 0;
  font: inherit; font-size: 12px; font-weight: 600;
  padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-elev); color: var(--text);
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.chat-voice-stop:hover { background: var(--danger-soft); color: var(--danger); border-color: var(--danger); }

/* Year-in-review modal — controls cluster on the right */
.year-review-modal .modal-head { gap: 8px; }
.year-review-modal .modal-head h3 { flex: 1; }
.yr-share-btn { display: inline-flex; align-items: center; gap: 6px; }

/* Settings — push notification opt-in row */
.settings-row {
  display: flex; align-items: center; gap: 16px;
  padding: 12px 0;
}
.settings-row-text { flex: 1; }
.settings-row-title { font-weight: 600; font-size: 14px; color: var(--text); }
.settings-row-sub { font-size: 12px; color: var(--text-mute); margin-top: 2px; line-height: 1.4; }
.switch { position: relative; display: inline-block; width: 44px; height: 24px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch-slider {
  position: absolute; cursor: pointer; inset: 0;
  background: var(--bg-hover);
  border-radius: 999px;
  transition: background .14s;
}
.switch-slider::before {
  content: ""; position: absolute;
  width: 18px; height: 18px;
  left: 3px; top: 3px;
  background: #fff; border-radius: 50%;
  transition: transform .14s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}
.switch input:checked + .switch-slider { background: var(--primary); }
.switch input:checked + .switch-slider::before { transform: translateX(20px); }
.switch input:focus-visible + .switch-slider { box-shadow: 0 0 0 3px var(--focus-ring); }
.switch input:disabled + .switch-slider { opacity: 0.5; cursor: not-allowed; }

/* ============================================================
   Quick-add popover (click a day → add an entry, Google-Cal style)
   ============================================================ */
.quick-add-pop {
  position: fixed;
  z-index: 60;
  width: min(300px, calc(100vw - 24px));
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow-lg);
  padding: 12px;
  display: flex; flex-direction: column; gap: 10px;
  animation: qaPopIn 0.14s ease-out;
}
@keyframes qaPopIn {
  from { opacity: 0; transform: scale(0.96) translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
.qa-head {
  display: flex; justify-content: space-between; align-items: center;
}
.qa-date {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--primary);
}
.qa-close {
  background: none; border: 0; cursor: pointer;
  color: var(--text-mute);
  width: 22px; height: 22px;
  display: inline-grid; place-items: center;
  font-size: 18px; line-height: 1;
  border-radius: 6px;
  transition: color .12s, background .12s;
}
.qa-close:hover { color: var(--text); background: var(--bg-soft); }
.qa-close:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.quick-add-pop input[type="text"] {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
  font: inherit; font-size: 14px;
  outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.quick-add-pop input[type="text"]:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.qa-preview {
  display: flex; flex-wrap: wrap; gap: 4px;
}
.qa-preview .nlp-chip { font-size: 11px; padding: 2px 7px; }
.qa-actions {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
}
.qa-hint {
  font-size: 10px; color: var(--text-mute);
  flex: 1;
}

/* ============================================================
   Drag-to-reschedule — entry pills are draggable in the grid
   ============================================================ */
.cell .pill[draggable="true"] {
  cursor: grab;
  user-select: none;
}
.cell .pill[draggable="true"]:active {
  cursor: grabbing;
}
.cell .pill.dragging {
  opacity: 0.35;
  transform: scale(0.97);
}
.cell.drop-target {
  background: var(--primary-tint);
  box-shadow: inset 0 0 0 2px var(--primary);
  z-index: 2;  /* above sibling cells so the ring isn't clipped */
}

/* ============================================================
   Skeleton loaders — shown during the initial loadAllFromDb()
   pass so users see structure instead of a blank flash.
   Replaced as soon as renderAll() runs.
   ============================================================ */
.skeleton {
  background: linear-gradient(
    90deg,
    var(--bg-soft) 0%,
    var(--bg-hover) 50%,
    var(--bg-soft) 100%
  );
  background-size: 200% 100%;
  animation: skelShimmer 1.4s ease-in-out infinite;
  border-radius: 6px;
  color: transparent;
  user-select: none;
  pointer-events: none;
}
@keyframes skelShimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}
.skel-num   { display: inline-block; width: 16px; height: 12px; border-radius: 3px; }
.skel-pill  { display: block; height: 12px; margin-top: 2px; border-radius: 4px; }
.skel-line  { display: block; height: 12px; border-radius: 4px; }
.skel-line.short  { width: 35%; }
.skel-line.medium { width: 60%; }
.skel-line.long   { width: 85%; }
.skel-block {
  display: block; height: 60px; border-radius: 10px; margin-bottom: 8px;
}

/* Skeleton cells should look like ordinary cells, just empty + shimmery. */
.cell.skel-cell { cursor: default; }
.cell.skel-cell:hover { background: var(--bg-elev); }

/* Skeleton entry/milestone rows borrow the real row shape so the layout
   doesn't jump when real content arrives. */
.entry.skel-row, .milestone.skel-row {
  background: var(--bg-soft);
  border-color: var(--line);
  cursor: default;
  animation: none;        /* don't double-animate with entry enter */
}
.entry.skel-row { border-left-color: var(--line-strong); }

/* ============================================================
   Family / household section
   ============================================================ */
.family-pane { display: flex; flex-direction: column; gap: 10px; padding: 6px 0; }
.family-empty {
  font-size: 13px; color: var(--text-mute); line-height: 1.5;
}
.family-empty-sub {
  font-size: 12px; color: var(--text-mute); padding: 6px 0;
}
.family-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.family-actions-foot { margin-top: 4px; }
.family-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.family-title { font-weight: 600; font-size: 15px; color: var(--text); }
.family-count { font-size: 12px; color: var(--text-mute); margin-left: auto; }
.family-section-sub {
  font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-mute); margin-top: 4px;
}
.family-members, .family-invites {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.family-member, .family-invite {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 13px;
}
.family-row-main { flex: 1; min-width: 0; }
.family-member-name { color: var(--text); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.family-member-sub { font-size: 11px; color: var(--text-mute); margin-top: 2px; }
.family-row-actions { display: flex; gap: 10px; align-items: center; }
.family-tag {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 6px; border-radius: 999px;
  background: var(--bg-hover); color: var(--text-mute);
}
.family-tag.admin {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent);
}
.family-tag.kid {
  background: color-mix(in srgb, var(--good, #2e9e5b) 18%, transparent);
  color: var(--good, #2e9e5b);
}
.family-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; letter-spacing: .08em;
  color: var(--text);
}
.family-invite-sub { font-size: 11px; color: var(--text-mute); }

/* ============================================================
   "About me" — personal context panel (Settings → About me)

   Two presentation modes:
   - Empty state: a one-liner + a quickadd "gym" button, followed by
     all four add-row forms so the user can add to any group.
   - Populated: each non-empty group renders as a card-style section
     with rows + an add-row form, then a single "Add another" form
     for kinds that don't have a group yet.
   ============================================================ */
.about-pane {
  display: flex; flex-direction: column;
  gap: 16px; padding: 4px 0;
}

.about-empty {
  background: var(--bg-soft);
  border: 1px dashed var(--line);
  border-radius: 10px;
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 10px;
  align-items: flex-start;
}
.about-empty-msg {
  margin: 0; font-size: 13px; line-height: 1.5; color: var(--text-soft);
}
.about-empty-msg code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
}

.about-group {
  display: flex; flex-direction: column; gap: 8px;
}
.about-group-head {
  display: flex; align-items: baseline; gap: 8px;
}
.about-group-title {
  margin: 0;
  font-size: 13px; font-weight: 700;
  color: var(--text);
  text-transform: uppercase; letter-spacing: .04em;
}
.about-group-count {
  font-size: 11px; color: var(--text-mute);
  background: var(--bg-soft);
  border-radius: 999px; padding: 1px 8px;
}

.about-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.about-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.about-row-main {
  flex: 1; min-width: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
}
.about-key {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; font-weight: 700;
  color: var(--text);
}
.about-value {
  appearance: none; background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  padding: 2px 6px; margin: -2px -6px; /* hover halo without shifting layout */
  font: inherit; font-size: 13px;
  color: var(--text-soft); text-align: left;
  cursor: text;
  transition: background .12s, border-color .12s, color .12s;
  max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.about-value:hover {
  background: var(--bg-hover);
  color: var(--text);
}
.about-value:focus-visible {
  background: var(--bg-elev);
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.about-value-edit {
  flex: 1; min-width: 120px;
  background: var(--bg-elev);
  border: 1px solid var(--primary);
  border-radius: 6px;
  padding: 4px 8px;
  font: inherit; font-size: 13px;
  color: var(--text);
  box-shadow: 0 0 0 3px var(--focus-ring);
  outline: none;
}
.about-row-editing {
  background: var(--bg-elev);
}

.about-row-tags {
  display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap;
}
.about-scope-chip {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 6px; border-radius: 999px;
  background: var(--bg-hover); color: var(--text-mute);
  white-space: nowrap;
}
.about-scope-chip.about-scope-family {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
}
.about-learned-chip {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary);
  white-space: nowrap;
  border: 1px solid transparent;
  cursor: pointer;
  font-family: inherit;
  transition: background .12s, border-color .12s;
}
button.about-learned-chip:hover {
  background: color-mix(in srgb, var(--primary) 22%, transparent);
  border-color: color-mix(in srgb, var(--primary) 40%, transparent);
}
.about-confirmed-chip {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--success, #10b981) 12%, transparent);
  color: var(--success, #10b981);
  white-space: nowrap;
}
.about-usage-chip {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-mute);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.about-usage-chip.about-usage-never {
  color: color-mix(in srgb, var(--text-mute) 70%, transparent);
  font-style: italic;
}
.about-stale-chip {
  appearance: none; cursor: pointer; font-family: inherit;
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--warn, #f59e0b) 14%, transparent);
  color: var(--warn, #f59e0b);
  border: 1px solid color-mix(in srgb, var(--warn, #f59e0b) 30%, transparent);
  white-space: nowrap;
  transition: background .12s;
}
.about-stale-chip:hover {
  background: color-mix(in srgb, var(--warn, #f59e0b) 22%, transparent);
}

.about-example-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.about-example-chip {
  appearance: none; cursor: pointer; font-family: inherit;
  font-size: 12px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  color: var(--text);
  transition: background .12s, border-color .12s;
}
.about-example-chip:hover {
  background: var(--bg-hover);
  border-color: var(--primary);
  color: var(--primary);
}

.about-del {
  appearance: none; background: transparent; border: 1px solid transparent;
  color: var(--text-mute);
  width: 30px; height: 30px;
  border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  flex: 0 0 auto;
  transition: background .12s, color .12s, border-color .12s;
}
.about-del:hover {
  background: var(--bg-hover);
  color: var(--danger);
}
.about-del:focus-visible {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.about-del-armed {
  width: auto;
  padding: 4px 10px;
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em;
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 35%, var(--line));
}
.about-del-armed:hover {
  background: color-mix(in srgb, var(--danger) 20%, transparent);
}

/* Add-row form — sits at the bottom of every group. */
.about-add {
  background: var(--bg-soft);
  border: 1px dashed var(--line);
  border-radius: 10px;
  padding: 8px 10px;
}
.about-add-head {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-mute);
  margin-bottom: 6px;
}
.about-add-grid {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) minmax(160px, 2fr) auto auto;
  gap: 8px; align-items: stretch;
}
.about-add-grid-wide {
  grid-template-columns: minmax(100px, .8fr) minmax(120px, 1fr) minmax(160px, 2fr) auto auto;
}
.about-add-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.about-add input,
.about-add select {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 7px 10px;
  font: inherit; font-size: 13px;
  color: var(--text);
  outline: none;
  transition: border-color .12s, box-shadow .12s, background .12s;
  min-width: 0; width: 100%;
}
.about-add input:focus,
.about-add select:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.about-add-submit {
  align-self: stretch;
  white-space: nowrap;
}
.about-add-err {
  margin-top: 6px;
  font-size: 12px;
  color: var(--danger);
}

/* Scope radio toggle — two pill buttons. */
.about-scope-toggle {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg-elev);
  padding: 0;
  display: inline-flex;
  align-self: stretch;
  margin: 0;
}
.about-scope-toggle[disabled],
.about-scope-toggle:has(input[disabled]) {
  /* Keep visible (per spec) — hint via opacity. */
  opacity: .6;
}
.about-scope-opt {
  display: inline-flex; align-items: center;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 12px; color: var(--text-soft);
  border-radius: 8px;
  user-select: none;
}
.about-scope-opt input {
  /* Hide the native radio; the parent label gets the toggled look. */
  position: absolute; opacity: 0; pointer-events: none;
}
.about-scope-opt:has(input:checked) {
  background: var(--primary-tint);
  color: var(--primary);
  font-weight: 600;
}
.about-scope-opt:has(input:focus-visible) {
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.about-scope-opt[aria-disabled="true"] {
  cursor: not-allowed;
  color: var(--text-mute);
}

/* Place-only extra fields (address / phone / url) — second row inside
   the .about-add form when kind === 'place'. */
.about-add-extra {
  display: grid;
  grid-template-columns: minmax(160px, 2fr) minmax(120px, 1fr) minmax(140px, 1.4fr);
  gap: 8px;
  margin-top: 8px;
}
.about-add-extra .about-add-cell { gap: 4px; }

/* Place row's secondary line — address / phone / url shown below the
   value when populated. Compact, low-contrast, single-line w/ dot
   separators. */
.about-row-details {
  flex: 1 1 100%;
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 6px;
  margin-top: 2px;
  font-size: 12px;
  color: var(--text-mute);
  min-width: 0;
}
.about-place-detail {
  color: var(--text-soft);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
}
a.about-place-detail { color: var(--primary); }
a.about-place-detail:hover { text-decoration: underline; }
.about-place-sep {
  color: var(--text-mute);
  font-weight: 700;
}
.about-row-details-empty { margin-top: 4px; }
.about-place-add-details {
  appearance: none;
  background: transparent;
  border: 1px dashed var(--line);
  color: var(--text-mute);
  font: inherit;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  cursor: pointer;
  transition: color .12s, border-color .12s, background .12s;
}
.about-place-add-details:hover {
  color: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 50%, var(--line));
  background: color-mix(in srgb, var(--primary) 6%, transparent);
}

/* In-row edit form for place rows. Replaces the row's normal contents
   while editing — Save commits, Cancel/Esc restores. */
.about-row-editing-place {
  display: block;        /* override the row's flex layout for the form */
  padding: 10px;
}
.about-place-edit {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  align-items: stretch;
}
.about-place-edit-head {
  grid-column: 1 / -1;
  margin-bottom: 2px;
}
.about-place-edit-name { grid-column: 1 / -1; }
.about-place-edit input {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 7px 10px;
  font: inherit; font-size: 13px;
  color: var(--text);
  outline: none;
  transition: border-color .12s, box-shadow .12s;
  width: 100%;
}
.about-place-edit input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.about-place-edit-actions {
  grid-column: 1 / -1;
  display: flex; justify-content: flex-end; gap: 8px;
  margin-top: 2px;
}

/* Mobile: stack form fields vertically. */
@media (max-width: 640px) {
  .about-add-grid,
  .about-add-grid-wide,
  .about-add-extra,
  .about-place-edit {
    grid-template-columns: 1fr;
  }
  .about-scope-toggle { align-self: flex-start; }
  .about-add-submit { justify-self: stretch; }
  .about-row { flex-wrap: wrap; }
  .about-value { white-space: normal; }
}

/* ============================================================
   Owner chips (rendered when 2+ household members)
   ============================================================ */
.owner-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; line-height: 1;
  padding: 2px 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--owner-color) 14%, transparent);
  color: var(--owner-color);
  white-space: nowrap;
}
.owner-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--owner-color); display: inline-block;
}
.owner-mini-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--owner-color); display: inline-block;
  flex-shrink: 0;
}
.scope-seg { margin-left: auto; }

/* ============================================================
   Developer-view-specific styles
   The shared shell now lives under .app-view (see "App view shell"
   below). The rules below cover the bits that only the dev view
   ships — forms, sync cards, charts, projects/goals lists.
   ============================================================ */
.dev-form { display: flex; flex-direction: column; gap: 12px; }
.dev-row {
  display: flex; flex-wrap: wrap; gap: 12px;
}
.dev-row > .field { flex: 1 1 200px; min-width: 0; }
.dev-color-field { flex: 0 0 80px; }
.dev-color-field input[type="color"] {
  width: 100%; height: 36px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-soft);
}
.dev-advanced summary {
  cursor: pointer; font-size: 13px; color: var(--text-mute);
  user-select: none;
}
.dev-advanced[open] summary { color: var(--text); margin-bottom: 8px; }
.dev-actions {
  display: flex; align-items: center; gap: 8px;
}
.dev-actions .spacer { flex: 1; }
.dev-form-status {
  font-size: 12px; color: var(--text-mute);
  min-height: 14px;
}

.dev-sync-row {
  display: flex; flex-wrap: wrap; gap: 12px;
  border-top: 1px solid var(--line);
  padding-top: 14px;
}
.dev-sync-card {
  flex: 1 1 240px;
  padding: 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line); border-radius: 10px;
  display: flex; flex-direction: column; gap: 8px;
  align-items: flex-start;
}
.dev-sync-name { font-weight: 600; color: var(--text); font-size: 14px; }
.dev-sync-meta { font-size: 12px; color: var(--text-mute); }
.dev-sync-result {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; color: var(--text-mute);
  background: var(--bg-soft);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 10px;
  white-space: pre-wrap; word-break: break-all;
}
.dev-sync-errs {
  margin: 6px 0 0; padding-left: 18px;
  color: var(--danger, #b91c1c);
}
.dev-sync-err { font-size: 11px; }

.dev-projects-list { display: flex; flex-direction: column; gap: 6px; }
.dev-project-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line); border-radius: 10px;
}
.dev-project-row.archived { opacity: .6; }
.dev-project-row.editing { align-items: flex-start; }
.dev-edit-project { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.dev-project-swatch {
  display: inline-block;
  width: 14px; height: 14px; border-radius: 4px;
  box-shadow: 0 0 0 1px rgba(0,0,0,.06) inset;
  flex-shrink: 0;
}
.dev-project-main { flex: 1; min-width: 0; }
.dev-project-name { color: var(--text); font-size: 14px; font-weight: 600; }
.dev-project-sub { font-size: 12px; color: var(--text-mute); margin-top: 2px; }
.dev-project-actions { display: flex; gap: 12px; align-items: center; }
.dev-tag-archived {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  padding: 1px 6px; border-radius: 999px;
  background: var(--bg-hover); color: var(--text-mute);
  margin-left: 4px;
}
.dev-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.dev-muted { color: var(--text-mute); }

.dev-goals-list { display: flex; flex-direction: column; gap: 6px; }
.dev-goal-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 10px 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line); border-radius: 10px;
}
.dev-goal-row.done { opacity: .55; }
.dev-goal-row.done .dev-goal-text { text-decoration: line-through; }
.dev-goal-check { padding-top: 2px; }
.dev-goal-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.dev-goal-text { color: var(--text); font-size: 14px; }
.dev-goal-sub { font-size: 12px; }
.dev-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px;
  padding: 2px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--dev-chip) 14%, transparent);
  color: var(--dev-chip, var(--text-mute));
}
.dev-progress {
  height: 6px; border-radius: 4px; overflow: hidden;
  background: var(--bg-hover);
  margin-top: 4px;
}
.dev-progress-fill {
  height: 100%;
  background: var(--primary-fill);
  transition: width .25s ease;
}
.dev-progress-meta { font-size: 11px; color: var(--text-mute); }

.dev-empty {
  padding: 14px;
  text-align: center;
  font-size: 13px; color: var(--text-mute);
  background: var(--bg-soft);
  border: 1px dashed var(--line); border-radius: 8px;
}
.dev-empty.small { padding: 8px; font-size: 12px; }

.dev-dash-totals {
  display: flex; gap: 16px;
  font-size: 13px; color: var(--text-mute);
}
.dev-dash-totals strong { color: var(--text); font-weight: 700; margin-right: 2px; }
.dev-chart-block {
  display: flex; flex-direction: column; gap: 4px;
  margin-top: 8px;
}
.dev-chart-title {
  font-size: 12px; color: var(--text-mute);
  text-transform: uppercase; letter-spacing: .04em;
}
.dev-chart {
  width: 100%; min-height: 130px;
  background: var(--bg-soft);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 6px;
}
.dev-chart svg {
  display: block;
  width: 100%; height: auto;
}
.dev-chart-axis { stroke: var(--line); stroke-width: 1; }
.dev-chart-x, .dev-chart-y {
  font-size: 9px; fill: var(--text-mute);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.dev-chart-x { text-anchor: start; }
.dev-chart-y { text-anchor: start; }

.dev-table {
  width: 100%; border-collapse: collapse;
  font-size: 13px;
}
.dev-table th, .dev-table td {
  text-align: left; padding: 6px 8px;
  border-bottom: 1px solid var(--line);
}
.dev-table th { font-weight: 600; color: var(--text-mute); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
.dev-table td.num, .dev-table th.num { text-align: right; font-variant-numeric: tabular-nums; }

@media (max-width: 880px) {
  .dev-row > .field { flex-basis: 100%; }
  .dev-sync-row { flex-direction: column; }
}

/* ============================================================
   App view shell — shared by #settingsView and #devView.
   The top-level view replaces .layout when shown, giving each
   surface a dedicated header + tab nav + body. Left rail on
   desktop, horizontal scroll-snap pill strip on mobile.
   ============================================================ */
.app-view {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 0;
  padding: 16px 20px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom));
  overflow-y: auto;
}

.app-view-title {
  margin: 0;
  font-size: 22px; font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}
.app-view-close {
  position: absolute;
  top: 16px; right: 20px;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-muted);
  z-index: 5;
}
.app-view-close:hover { background: var(--bg-hover); color: var(--text); }

/* Mobile-only page header inside .app-view. Hidden on desktop — the
   close-X (top-right) + the side-rail title already serve that role.
   When the page is acting as a dedicated mobile scene (see the
   `body[data-scene="settings"]` rules at the mobile breakpoint below),
   this becomes the fixed top-bar with a back arrow + title. */
.app-view-mobile-head { display: none; }

/* Shell layout: left rail (220px) + content. On mobile collapses
   to a stack with a horizontal pill strip on top. */
.app-view-shell {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
  max-width: 980px;
  width: 100%;
  margin: 0 auto;
  padding: 0 4px 32px;
}

/* Left column: title card stacked above the tab nav. */
.app-view-side {
  position: sticky;
  top: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-self: start;
  min-width: 0;
}
.app-view-side-head {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 12px 14px;
  box-shadow: var(--shadow-sm);
}

.app-view-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 8px;
  box-shadow: var(--shadow-sm);
}
.app-view-tab {
  display: flex; align-items: center;
  text-align: left;
  border: 0;
  background: transparent;
  color: var(--text-soft);
  padding: 10px 12px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  min-height: 38px;
  transition: background .12s ease, color .12s ease;
}
.app-view-tab:hover { background: var(--bg-hover); color: var(--text); }
.app-view-tab.active,
.app-view-tab[aria-selected="true"] {
  background: var(--primary-tint);
  color: var(--primary);
}

/* Thin rule separating the sub-page tabs from the Developer launchpad. */
.app-view-nav-sep {
  height: 1px;
  margin: 6px 10px;
  background: var(--line);
}
/* Developer launchpad — a peer-scene opener, not a sub-page tab. Shares the
   tab metrics but reads as an action: muted by default, chevron pushed right. */
.app-view-launch {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  color: var(--text-soft);
  padding: 10px 12px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  min-height: 38px;
  transition: background .12s ease, color .12s ease;
}
.app-view-launch:hover { background: var(--bg-hover); color: var(--text); }
.app-view-launch svg { flex: none; opacity: .6; }
/* The Developer launchpad + its separator are server-gated (meta.developerMode).
   `display: flex` above would otherwise beat the UA's [hidden] rule, so restate
   it here — this is what actually keeps the entry off a production instance. */
.app-view-launch[hidden],
.app-view-nav-sep[hidden] { display: none; }

.app-view-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}
.app-view-page {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.app-view-page[hidden] { display: none; }

.app-view-card {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  box-shadow: var(--shadow-sm);
}
.app-view-card-head { display: flex; flex-direction: column; gap: 4px; }
.app-view-card-head-row {
  flex-direction: row;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.app-view-card-head-row > div { flex: 1; min-width: 0; }
.app-view-card-title {
  margin: 0;
  font-size: 15px; font-weight: 700;
  color: var(--text);
  letter-spacing: -0.005em;
}
.app-view-card-sub {
  margin: 0;
  font-size: 13px;
  color: var(--text-soft);
  line-height: 1.45;
}
.app-view-card-foot {
  margin: 0;
  font-size: 12px;
  color: var(--text-mute);
}
.app-view-card .field { margin-bottom: 0; }
.app-view-card .field-help {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  color: var(--text-mute);
  margin-top: 2px;
}
.app-view-card .field-help .link {
  font-size: 12px; padding: 2px 4px;
  color: var(--primary);
}

/* Dangerzone card variant — subtle red tinted border. */
.app-view-card.danger-card {
  border-color: color-mix(in srgb, var(--danger) 35%, var(--line));
}

/* Save bar pinned at the bottom of the settings form. */
.app-view-savebar {
  display: flex;
  align-items: center;
  gap: 12px;
  position: sticky;
  bottom: 0;
  padding: 12px 16px;
  background: color-mix(in srgb, var(--bg-elev) 92%, transparent);
  backdrop-filter: blur(6px);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  z-index: 5;
  padding-bottom: max(12px, env(safe-area-inset-bottom));
}
.app-view-savebar-hint {
  font-size: 12px; color: var(--text-mute);
}

/* Chart grid: side-by-side on desktop, stacked on mobile. */
.dev-chart-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

/* Push row inside the new card surface needs tighter framing. */
.app-view-card .push-row {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  display: flex; align-items: center; gap: 14px;
}
.app-view-card .push-row .settings-row-text { flex: 1; min-width: 0; }

/* Library stats reuse the existing chip styling but with more breathing room. */
.app-view-card .settings-stats {
  margin-bottom: 0;
  background: var(--bg-soft);
}

/* Mobile breakpoint: collapse rail to a horizontal pill strip. */
@media (max-width: 900px) {
  .app-view { padding-left: 8px; padding-right: 8px; }
  .app-view-title { font-size: 18px; }
  .app-view-close { top: 8px; right: 8px; }
  .app-view-shell {
    grid-template-columns: 1fr;
    gap: 14px;
    padding: 0;
  }
  .app-view-side {
    position: static;
    gap: 8px;
  }
  .app-view-side-head { padding: 8px 12px; }
  .app-view-nav {
    position: sticky;
    top: 4px;
    z-index: 30;
    flex-direction: row;
    gap: 6px;
    padding: 6px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    background: color-mix(in srgb, var(--bg-elev) 94%, transparent);
    backdrop-filter: blur(6px);
  }
  .app-view-nav::-webkit-scrollbar { display: none; }
  .app-view-tab {
    flex: 0 0 auto;
    scroll-snap-align: start;
    padding: 9px 14px;
    min-height: 36px;
    border-radius: 999px;
    white-space: nowrap;
  }
  /* In the horizontal scroller the separator becomes a vertical rule and the
     launchpad a pill that matches the tabs. */
  .app-view-nav-sep {
    height: auto;
    width: 1px;
    margin: 6px 2px;
    align-self: stretch;
  }
  .app-view-launch {
    flex: 0 0 auto;
    scroll-snap-align: start;
    width: auto;
    justify-content: center;
    padding: 9px 14px;
    min-height: 36px;
    border-radius: 999px;
    white-space: nowrap;
  }
  .app-view-card { padding: 16px; gap: 12px; }
  .app-view-card-title { font-size: 14px; }
  .app-view-card-head-row { flex-direction: column; }
  .app-view-savebar { border-radius: 10px; padding: 10px 12px; }
  .dev-chart-grid { grid-template-columns: 1fr; }
}

/* Tighter tabs on very small phones — give every other control more room. */
@media (max-width: 480px) {
  .app-view-title { font-size: 17px; }
  .app-view-card { padding: 14px; }
}

/* Sessions list inside the new card — drop the old top border. */
.app-view-card .sessions-list { margin: 0; }
.app-view-card .settings-section { border-top: 0; margin-top: 0; padding-top: 0; }

/* ============================================================
   Mobile full-screen page treatment for top-level scenes
   (currently just Settings — Dev stays desktop-only). At the
   mobile breakpoint we hide the topbar/mobile-tabs and turn the
   scene into a dedicated page with its own back-arrow header.
   Desktop is unaffected: the existing modal-ish .app-view layout
   with the top-right close X stays exactly as it was.

   This pattern is intended to generalize to other scenes (chat,
   year-review, etc.) — wire them through setScene(name) so the
   body[data-scene="<name>"] selector activates the same chrome.
   ============================================================ */
@media (max-width: 880px) {
  body[data-scene="settings"] .topbar,
  body[data-scene="settings"] .mobile-tabs { display: none !important; }

  /* Suppress the desktop close-X and the side-rail's "Settings"
     title — the mobile head subsumes both. */
  body[data-scene="settings"] .app-view-close,
  body[data-scene="settings"] .app-view-side-head { display: none; }

  /* Show + style the mobile page header. Sticky so it stays in
     place as the form scrolls underneath. */
  body[data-scene="settings"] .app-view-mobile-head {
    display: flex;
    align-items: center;
    gap: 6px;
    position: sticky;
    top: 0;
    z-index: 40;
    padding: 6px 8px;
    padding-top: max(6px, env(safe-area-inset-top));
    background: color-mix(in srgb, var(--bg-elev) 96%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--line);
    margin: 0 -8px 8px;
  }
  body[data-scene="settings"] .app-view-back {
    width: 40px; height: 40px;
    color: var(--text);
  }
  body[data-scene="settings"] .app-view-back:hover { background: var(--bg-hover); }
  body[data-scene="settings"] .app-view-mobile-title {
    margin: 0;
    font-size: 17px; font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
  }

  /* Drop the top padding so the sticky header sits flush, and let
     the view fill the visible space (no calendar/topbar above it). */
  body[data-scene="settings"] .app-view {
    padding-top: 0;
    gap: 0;
  }

  /* Tighten the sticky tab strip now that the page header is what
     defines the top edge — the rail collapses, and the tabs sit
     right under the header without a redundant gap. */
  body[data-scene="settings"] .app-view-side {
    margin-top: 4px;
  }

  /* Push the sticky tab strip down so it doesn't slide under the
     new sticky page header. ~52px = back-arrow + paddings; the
     env() term accounts for the notch padding the header consumes. */
  body[data-scene="settings"] .app-view-nav {
    top: calc(52px + env(safe-area-inset-top));
  }
}

/* ============================================================
   Issue #3 — mobile modal-as-page treatment.

   On mobile (≤880px) the chat / milestone / year-review / help /
   palette modals stop floating over the calendar and become
   full-screen pages instead. The modal DOM stays in place (so
   the chat's SSE stream, the year-review's canvas export, and
   the milestone form state are never remounted); we just
   promote its presentation via `body[data-page="<name>"]`.

   Each target modal gets a sticky `.modal-mobile-head` with a
   back-arrow that matches the Settings page chrome from #2 —
   tapping it routes through `data-close` → closeAllModals(),
   which pops the page hash via history.back(). The device back
   gesture follows the same path via the popstate listener.

   The base rule below hides the mobile head everywhere; the
   media block below it turns it on per active page.
   ============================================================ */
.modal-mobile-head { display: none; }

@media (max-width: 880px) {
  /* While a page is active, the calendar shell shouldn't render
     at all — no layout cost, no animations, no SSE-driven
     repaints behind the scenes. The settings/dev paths handle
     this themselves via `body[data-scene]`. */
  body[data-page] .topbar,
  body[data-page] .mobile-tabs,
  body[data-page] .focusbar,
  body[data-page] main.layout { display: none !important; }

  /* The focusbar sits at z-index 55 — above .modal-root (z 50) — so its
     bottom strip paints OVER a centered dialog and clips the dialog's
     bottom action row (e.g. the "Stop feed" button on the finish-feed
     sheet). Full-screen pages already hide the bar via the rule above;
     plain centered dialogs (confirm, recur-scope, finish-feed…) don't set
     data-page, so hide the bar for them too while their modal is open. The
     backdrop already blocks the bar's taps, so nothing is lost. */
  body:has(.modal-root:not([hidden])) .focusbar { display: none !important; }

  /* Every non-calendar scene (settings, dev, planner, insights, baby) fully
     replaces the calendar on phones. renderScene() sets `hidden` on
     main.layout, but the mobile `.layout { display: flex !important }` rule
     ties `[hidden]`'s specificity and wins on source order — so the calendar's
     flex:1 pane keeps rendering and splits the screen 50/50 with the scene
     ("half page under the calendar"). This one higher-specificity hide covers
     every scene, so each opens as a true full-screen page. */
  body[data-scene]:not([data-scene="calendar"]) main.layout { display: none !important; }

  /* The PTT FAB floats over the whole app (position:fixed, bottom-right).
     Inside any modal-as-page it's redundant — the user is in a focused
     sub-page with its own controls — and it visually overlaps actionable
     controls pinned to the bottom-right (e.g. the Lists modal's "Add" /
     "Add list" buttons, the chat input row). `body[data-page]` is set by
     markPage() only while a modal-as-page is open on mobile, so hide the
     FAB for all of them at once. */
  body[data-page] .ptt-fab { display: none; }

  /* The active page's modal stretches to fill the viewport.
     Modal-root has padding: 0 already on mobile (see the
     full-screen entry/notes/editor block above), so the modal
     itself just needs to drop its centered-card sizing. The
     `:not([hidden])` is what targets only the active modal —
     closeAllModals leaves the others hidden, so this selector
     resolves to exactly one element. */
  body[data-page] .modal:not([hidden]) {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
    border: 0;
    animation: none;
  }

  /* Show the sticky mobile head inside the active page modal.
     Mirrors `.app-view-mobile-head` from the Settings page so
     the chrome feels identical across the two patterns. */
  body[data-page] .modal:not([hidden]) > .modal-mobile-head {
    display: flex;
    align-items: center;
    gap: 6px;
    position: sticky;
    top: 0;
    z-index: 40;
    padding: 6px 8px;
    padding-top: max(6px, env(safe-area-inset-top));
    background: color-mix(in srgb, var(--bg-elev) 96%, transparent);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--line);
    flex-shrink: 0;
  }
  body[data-page] .modal-page-back {
    width: 40px; height: 40px;
    color: var(--text);
  }
  body[data-page] .modal-page-back:hover { background: var(--bg-hover); }
  body[data-page] .modal-mobile-title {
    margin: 0;
    font-size: 17px; font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
  }

  /* Hide the original .modal-head close-X and (when present) the
     close-X inside the palette — the back arrow subsumes both.
     Keep the .modal-head itself visible: it still holds the
     section title and (for year-review) the year selector +
     "Save image" button, which the user wants under the head. */
  body[data-page] .modal:not([hidden]) > .modal-head > .iconbtn[data-close] {
    display: none;
  }

  /* Chat page: let the chat-body fill the page. The base
     .chat-modal already does `flex-direction: column`; this just
     drops the max-height so it can stretch with the page. */
  body[data-page="chat"] #chatModal .chat-body {
    flex: 1;
    min-height: 0;
  }

  /* Year-review can be tall (12 month strips + tag bars + photo
     mosaic). The default .modal-body has overflow: auto already,
     but make sure the inner body fills + scrolls cleanly. */
  body[data-page="year-review"] #yearReviewModal #yearReviewBody {
    flex: 1;
    min-height: 0;
  }

  /* Year-review's head crams 3 controls + a close X. On the
     mobile page we hid the X (above), but the year selector +
     "Save image" button still need room. Let them wrap. */
  body[data-page="year-review"] #yearReviewModal > .modal-head {
    flex-wrap: wrap;
    row-gap: 6px;
  }

  /* Palette gets a flex column so input + results fill the
     page below the head. */
  body[data-page="palette"] #paletteModal {
    display: flex;
    flex-direction: column;
  }
  body[data-page="palette"] #paletteModal .palette-results {
    flex: 1;
    min-height: 0;
    overflow: auto;
  }

  /* Milestone form: the existing .form-actions is pinned at the
     bottom of the form; let the form flex so the actions stay
     reachable above the home-indicator. */
  body[data-page="milestone"] #msModal {
    display: flex;
    flex-direction: column;
  }
  body[data-page="milestone"] #msModal > #msForm {
    flex: 1;
    min-height: 0;
    overflow: auto;
    padding-bottom: max(16px, env(safe-area-inset-bottom));
  }

  /* Notes / lists / routines pages: their .modal-head only carries a
     title + subtitle + close-X — all subsumed by the back-arrow
     mobile-head. Hide it so the title isn't shown twice. */
  body[data-page="notes"] #notesModal > .modal-head,
  body[data-page="lists"] #listsModal > .modal-head,
  body[data-page="routines"] #routinesModal > .modal-head,
  /* Batch-2 pages whose head is only a title + close-X — both subsumed by
     the back-arrow mobile-head, so hide the head to avoid a doubled title. */
  body[data-page="share"] #shareModal > .modal-head,
  body[data-page="import"] #importModal > .modal-head,
  body[data-page="subscribe"] #subscribeModal > .modal-head,
  body[data-page="paste"] #pasteAnythingModal > .modal-head,
  body[data-page="meal-week"] #mealWeekModal > .modal-head,
  body[data-page="recall"] #recallModal > .modal-head,
  body[data-page="jobs"] #jobsModal > .modal-head,
  body[data-page="capsule"] #capsuleModal > .modal-head { display: none; }

  /* Entry composer + capsules list keep their head (they carry a chip / a
     "New capsule" button), but the h3 duplicates the back-header title, so
     hide just the h3. */
  body[data-page="entry"] #entryModal > .modal-head > #entryModalTitle,
  body[data-page="capsules"] #capsulesModal > .modal-head > #capsulesTitle,
  body[data-page="chronicle"] #chronicleModal > .modal-head > #chronicleTitle { display: none; }
  body[data-page="entry"] #entryModal > .modal-head,
  body[data-page="capsules"] #capsulesModal > .modal-head,
  body[data-page="chronicle"] #chronicleModal > .modal-head { justify-content: flex-start; }

  /* routines-body lacks flex:1 in its base rule (unlike notes/lists);
     give it room so the list fills the page and scrolls internally. */
  body[data-page="routines"] #routinesModal .routines-body {
    flex: 1;
    min-height: 0;
  }

  /* Newly page-promoted modals (issue #3, batch 2): entry composer, share
     sheet, import/subscribe/paste-anything, meal-week planner, recall, and
     scheduled-jobs. The generic `body[data-page] .modal` rule above already
     stretches each to fill the viewport; here we let their scrollable body
     fill the space under the sticky back-header and scroll internally so the
     action rows at the bottom stay reachable above the home indicator.
     `.modal` is already `display:flex; flex-direction:column`, so flex:1 on
     the body is all that's needed. The original `.modal-head` stays visible
     (it carries the title + any inline controls); the back-arrow subsumes its
     close-X, which the generic rule hides. */
  body[data-page="entry"]     #entryModal          > .modal-body,
  body[data-page="share"]     #shareModal          > .modal-body,
  body[data-page="import"]    #importModal         > .modal-body,
  body[data-page="subscribe"] #subscribeModal      > .modal-body,
  body[data-page="paste"]     #pasteAnythingModal  > .modal-body,
  body[data-page="meal-week"] #mealWeekModal       > .modal-body,
  body[data-page="recall"]    #recallModal         > .modal-body,
  body[data-page="jobs"]      #jobsModal           > .modal-body,
  body[data-page="capsule"]   #capsuleModal        > .modal-body,
  body[data-page="capsules"]  #capsulesModal       > .modal-body,
  body[data-page="chronicle"] #chronicleModal      > .modal-body {
    flex: 1;
    min-height: 0;
    padding-bottom: max(16px, env(safe-area-inset-bottom));
  }

  /* The entry composer's scrollable region is the <form>, which carries the
     .modal-body class directly. Its toolbar popovers (time / mood / find-time)
     are absolutely positioned against the toolbar; on a full-page composer
     give the textarea room to grow while keeping the toolbar in view. */
  body[data-page="entry"] #entryModal > .entry-form { padding-bottom: max(16px, env(safe-area-inset-bottom)); }
  body[data-page="entry"] #entryModal #entryInput { min-height: 30dvh; }
}

/* ============================================================
   Developer — token KPI, host filter chips, per-entry session
   detail drawer, and the session detail modal. Lives at the
   bottom of the file so it overrides earlier .dev-* rules
   without re-declaring base layout.
   ============================================================ */

/* Token + USD KPI pills inside .dev-dash-totals strip. */
.dev-tokens-kpi {
  font-variant-numeric: tabular-nums;
}

/* Host filter chips above the chart grid. Only rendered when there's
   more than one host with sessions; otherwise the element is hidden. */
.dev-host-filter {
  display: flex; gap: 6px; flex-wrap: wrap;
  align-items: center;
  padding: 8px 0 12px;
  font-size: 12px;
}
.dev-host-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--text);
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.dev-host-chip:hover { background: color-mix(in srgb, var(--accent) 8%, var(--bg-soft)); }
.dev-host-chip.active {
  background: color-mix(in srgb, var(--accent) 18%, var(--bg-soft));
  border-color: color-mix(in srgb, var(--accent) 40%, var(--line));
}
.dev-host-chip-count {
  font-size: 11px; color: var(--text-mute);
  background: var(--bg-elev); border-radius: 999px;
  padding: 0 6px;
}

/* "view sessions" inline button on a dev-mirrored entry's meta row. */
.entry-dev-sessions-btn {
  border: 1px solid var(--line);
  background: transparent;
  border-radius: 6px;
  padding: 1px 8px;
  font-size: 11px;
  color: var(--text-mute);
  cursor: pointer;
  margin-left: 6px;
}
.entry-dev-sessions-btn:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--text);
}
.entry.dev-entry .entry-text { color: var(--text); }

/* Per-entry expanded session detail drawer. */
.dev-entry-detail {
  margin-top: 6px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  font-size: 12px;
}
.dev-entry-detail-head {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  padding-bottom: 6px;
  border-bottom: 1px dashed var(--line);
  margin-bottom: 6px;
  color: var(--text-mute);
}
.dev-entry-detail-head strong { color: var(--text); font-weight: 600; }
.dev-entry-detail-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.dev-entry-detail-item {
  display: grid;
  grid-template-columns: 60px 1fr 50px 60px 60px;
  gap: 8px;
  width: 100%;
  align-items: center;
  padding: 4px 6px;
  border: 0;
  background: transparent;
  border-radius: 6px;
  font: inherit;
  color: var(--text);
  cursor: pointer;
  text-align: left;
  font-variant-numeric: tabular-nums;
}
.dev-entry-detail-item:hover { background: var(--bg-elev); }
.dev-entry-detail-time { color: var(--text-mute); font-size: 11px; }
.dev-entry-detail-host { font-size: 11px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dev-entry-detail-mins { text-align: right; }
.dev-entry-detail-tokens { text-align: right; }
.dev-entry-detail-usd { text-align: right; color: var(--text-mute); }

/* Session detail modal — appended to <body> when a session is clicked. */
.dev-session-modal {
  position: fixed; inset: 0; z-index: 1000;
  background: color-mix(in srgb, #000 50%, transparent);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.dev-session-modal-card {
  background: var(--bg-elev);
  color: var(--text);
  border-radius: 14px;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg, 0 20px 60px rgba(0,0,0,0.3));
  max-width: 560px; width: 100%;
  max-height: 80vh; overflow: auto;
}
.dev-session-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}
.dev-session-modal-head h3 {
  margin: 0; font-size: 16px; font-weight: 600;
  display: flex; gap: 10px; align-items: baseline;
}
.dev-session-modal-head .dev-muted {
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.dev-session-modal-body {
  padding: 16px;
  display: flex; flex-direction: column; gap: 14px;
}
.dev-session-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px 18px;
  font-size: 13px;
}
.dev-session-grid > div > div:first-child { font-size: 11px; color: var(--text-mute); margin-bottom: 2px; }
.dev-session-grid > div > div:last-child { font-variant-numeric: tabular-nums; }
.dev-session-models {
  font-size: 12px;
  padding-top: 8px; border-top: 1px dashed var(--line);
}
.dev-session-models code {
  background: var(--bg-soft); padding: 1px 6px; border-radius: 4px;
  font-size: 11px; margin-right: 4px;
}
.dev-session-path {
  font-size: 11px; color: var(--text-mute);
  padding-top: 8px; border-top: 1px dashed var(--line);
  word-break: break-all;
}
.dev-session-path code {
  font-size: 11px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

@media (max-width: 600px) {
  .dev-session-grid { grid-template-columns: 1fr; }
  .dev-entry-detail-item {
    grid-template-columns: 50px 1fr 50px 50px;
  }
  .dev-entry-detail-usd { display: none; }
}

/* ============================================================
   Push-to-talk FAB — always-available hold-to-speak button.
   Bottom-right, safe-area-aware, with held/pulse states.
   The wake-word toolbar button (#lumiToggleBtn) covers the
   hands-free path; this covers the explicit "tap & hold" path.
   ============================================================ */
.ptt-fab {
  position: fixed;
  right: calc(20px + env(safe-area-inset-right, 0px));
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--bg-elev);
  color: var(--text);
  box-shadow: var(--shadow-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  z-index: 70;
  cursor: pointer;
  transition: transform .14s ease, background .14s ease, box-shadow .14s ease, color .14s ease;
  -webkit-tap-highlight-color: transparent;
  touch-action: none; /* avoid scroll-cancel on touchstart during hold */
  user-select: none;
}
.ptt-fab:hover {
  background: var(--bg-hover);
}
.ptt-fab:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
}
.ptt-fab .ptt-ring {
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  border: 2px solid var(--primary-fill, var(--primary));
}
.ptt-fab.held {
  transform: scale(1.08);
  background: var(--primary-fill, var(--primary));
  color: var(--on-primary, #fff);
  border-color: transparent;
  box-shadow: var(--shadow-lg);
}
.ptt-fab.held .ptt-ring {
  opacity: 1;
  animation: pttRing 1.2s ease-out infinite;
}
@keyframes pttRing {
  0%   { transform: scale(1); opacity: 0.55; }
  100% { transform: scale(1.35); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ptt-fab { transition: background .14s ease, color .14s ease; }
  .ptt-fab.held { transform: none; }
  .ptt-fab.held .ptt-ring { animation: none; opacity: 0.4; }
}
/* Hidden by user preference (Settings toggle off) or via the global
   body flag (e.g. inside a modal that takes over the whole viewport). */
.ptt-fab[hidden] { display: none !important; }
body.no-ptt .ptt-fab { display: none !important; }
/* Hide the FAB outside the calendar scene (Settings / Developer take
   over the viewport and have their own save bars / toolbars). */
body[data-scene]:not([data-scene="calendar"]) .ptt-fab { display: none !important; }

/* On phones the bottom focus-nav (.focusbar, ~64px tall incl. safe-area) sits
   at the viewport bottom edge. The FAB only appears on the calendar scene —
   where the focusbar is always present — so lift it clear of the bar (plus a
   comfortable gap) instead of overlapping the focus tabs. */
@media (max-width: 880px) {
  .ptt-fab {
    bottom: calc(84px + env(safe-area-inset-bottom, 0px));
  }
}

@media (max-width: 480px) {
  .ptt-fab {
    width: 60px;
    height: 60px;
    right: calc(16px + env(safe-area-inset-right, 0px));
    /* Still clear the focusbar (~64px); a slightly tighter gap on small phones. */
    bottom: calc(80px + env(safe-area-inset-bottom, 0px));
  }
}

/* =====================================================================
   Family Notes (household bulletin board)
   ===================================================================== */

.notes-btn:hover { color: var(--primary); background: var(--primary-tint); }

.notes-modal {
  width: min(640px, calc(100vw - 24px));
  height: min(760px, calc(100dvh - 40px));
  max-height: calc(100dvh - 40px);
}

/* ===== Household lists + chores (#8) ===== */
.lists-modal {
  width: min(680px, calc(100vw - 24px));
  height: min(780px, calc(100dvh - 40px));
  max-height: calc(100dvh - 40px);
}
.lists-modal .modal-head { gap: 8px; align-items: baseline; }
.lists-modal .modal-head h3 { flex: 0 0 auto; }
.lists-modal-sub {
  font-size: 12px; color: var(--text-mute);
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lists-body {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  padding: 14px 16px 16px; gap: 14px;
  overflow-y: auto;
}
.list-create { display: flex; gap: 8px; flex-wrap: wrap; }
.list-create input[type="text"] { flex: 1 1 180px; }
.list-create select { flex: 0 0 auto; }
.lists-container { display: flex; flex-direction: column; gap: 14px; }
.lists-empty { font-size: 13px; color: var(--text-mute); text-align: center; padding: 20px 0; }
.list-card {
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--bg-soft); padding: 12px 12px 10px;
}
.list-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.list-card-title { margin: 0; font-size: 14px; font-weight: 600; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-card-count { font-size: 11px; color: var(--text-mute); font-variant-numeric: tabular-nums; }
.list-kind-badge {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  padding: 2px 7px; border-radius: 999px;
  background: var(--bg-elev); color: var(--text-mute);
}
.list-kind-chores { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary); }
.list-card-del {
  background: transparent; border: none; color: var(--text-mute);
  cursor: pointer; padding: 2px; border-radius: 6px; display: inline-flex;
}
.list-card-del:hover { color: var(--danger, #dc2626); }
.list-items { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.list-empty { font-size: 12px; color: var(--text-mute); padding: 4px 2px; }
.list-item {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 4px; border-radius: 8px;
}
.list-item:hover { background: var(--bg-elev); }
.list-item-check {
  flex: none; width: 20px; height: 20px;
  border: 1.5px solid var(--line); border-radius: 6px;
  background: var(--bg); color: var(--primary);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
}
.list-item.is-checked .list-item-check { background: var(--primary); border-color: var(--primary); color: #fff; }
.list-item.is-chore .list-item-check { border-radius: 50%; }
.list-item-text { flex: 1; min-width: 0; font-size: 13.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-item.is-checked .list-item-text { text-decoration: line-through; color: var(--text-mute); }
.list-item-recur {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--primary); background: color-mix(in srgb, var(--primary) 14%, transparent);
  padding: 1px 6px; border-radius: 999px; flex: none;
}
.list-item-assignee {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 11px; font-weight: 600; color: var(--owner-color, var(--text-mute));
  flex: none;
}
.list-item-assignee::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--owner-color, var(--text-mute));
}
.list-item-assignee svg { margin-left: 1px; }
.list-item-del {
  flex: none; background: transparent; border: none; color: var(--text-mute);
  font-size: 16px; line-height: 1; cursor: pointer; padding: 0 4px; opacity: 0;
  transition: opacity .12s, color .12s;
}
.list-item:hover .list-item-del { opacity: 1; }
.list-item-del:hover { color: var(--danger, #dc2626); }
/* Touch devices have no hover, so the reveal-on-hover delete would be
   invisible/unusable — keep it visible (and a bit bigger) on coarse pointers. */
@media (hover: none) {
  .list-item-del { opacity: 0.6; font-size: 20px; padding: 0 6px; }
}
.list-add-item { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.list-add-text { flex: 1 1 140px; min-width: 0; }
.list-add-recur { flex: 1 1 auto; min-width: 0; font-size: 12px; }
.list-add-item > .btn { flex: 0 0 auto; }
/* Chore rows carry three controls (text · rotation · Add). On a narrow card
   give the text its own line so the "Rotate weekly" select + Add button never
   run off screen. :has() targets only the chore form; plain lists keep their
   compact [text][Add] row. Desktop cards are wide enough to stay single-row. */
@media (max-width: 640px) {
  .list-add-item:has(.list-add-recur) .list-add-text { flex-basis: 100%; }
}

/* Mobile polish for the Lists & chores modal-as-page. Bottom-anchored
   controls clear the home-bar via safe-area padding; the check / delete /
   "Add" controls all reach a ≥44px touch target; and the create + add-item
   forms lay out cleanly instead of reading as a squeezed desktop form. */
@media (max-width: 880px) {
  .lists-body {
    padding-bottom: max(16px, env(safe-area-inset-bottom));
    gap: 16px;
  }
  .lists-container { gap: 12px; }
  .list-card { padding: 12px 12px 12px; }
  .list-card-head { gap: 10px; }

  /* Create-list form: name on its own line, then [type][Add list] sharing
     the second row with the type select filling the free space. */
  .list-create select { flex: 1 1 auto; min-width: 0; }
  .list-create .btn { flex: 0 0 auto; min-height: 44px; }

  /* Roomier tap rows and a full-height "Add" button on the item forms. */
  .list-item { padding: 8px 4px; gap: 10px; }
  .list-add-item { gap: 8px; }
  .list-add-item > .btn { min-height: 44px; }

  /* Expand the interactive controls to a 44px hit area with a centered
     transparent overlay — the drawn box (checkbox, "×", trash) keeps its
     compact size, only the tappable region grows, so nothing looks bloated. */
  .lists-modal .list-item-check,
  .lists-modal .list-item-del,
  .lists-modal .list-card-del { position: relative; }
  .lists-modal .list-item-check::after,
  .lists-modal .list-item-del::after,
  .lists-modal .list-card-del::after {
    content: ""; position: absolute;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 44px; height: 44px;
  }
}
.notes-modal .modal-head { gap: 8px; align-items: baseline; }
.notes-modal .modal-head h3 { flex: 0 0 auto; }
.notes-modal-sub {
  font-size: 12px;
  color: var(--text-mute);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.notes-body {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  padding: 14px 16px 16px;
  gap: 14px;
}

/* --- compose row --------------------------------------------------- */
.note-compose {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-soft);
}
.note-compose textarea {
  resize: vertical;
  font: inherit;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-elev);
  color: var(--text);
  min-height: 56px;
  line-height: 1.45;
  outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.note-compose textarea::placeholder { color: var(--text-mute); }
.note-compose textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.note-compose-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
}
.note-pin-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-soft);
  cursor: pointer;
  user-select: none;
}
.note-pin-toggle input { accent-color: var(--primary); }

/* --- list ---------------------------------------------------------- */
.notes-list {
  flex: 1; min-height: 0;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 10px;
  padding-right: 2px;
}

.note-card {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-elev);
  padding: 10px 12px 12px;
  display: flex; flex-direction: column; gap: 6px;
  transition: border-color .12s, box-shadow .12s;
  animation: noteCardIn 0.16s ease-out;
}
@keyframes noteCardIn {
  from { opacity: 0; transform: translateY(2px); }
  to   { opacity: 1; transform: none; }
}
.note-card.is-pinned {
  border-color: var(--primary);
  background: var(--primary-tint);
}
.note-card-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px;
  color: var(--text-mute);
}
.note-author {
  font-weight: 600; color: var(--text);
  border-left: 3px solid var(--owner-color, var(--primary));
  padding-left: 6px;
}
.note-time { flex: 1; }
.note-pin-btn,
.note-edit-btn,
.note-del-btn {
  background: transparent;
  border: 0;
  color: var(--text-mute);
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 6px;
  font-size: 12px;
  line-height: 1.2;
  transition: background .12s, color .12s;
}
.note-pin-btn:hover,
.note-edit-btn:hover { color: var(--primary); background: var(--primary-tint); }
.note-del-btn:hover { color: var(--danger); background: rgba(220, 38, 38, 0.08); }
.note-pin-btn.is-on { color: var(--primary); }

.note-body {
  font-size: 14px; line-height: 1.5;
  color: var(--text);
  white-space: pre-wrap;
  word-wrap: break-word;
}

.note-edit-area {
  display: flex; flex-direction: column; gap: 6px;
}
.note-edit-area textarea {
  resize: vertical;
  font: inherit;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg-soft);
  color: var(--text);
  min-height: 48px;
  line-height: 1.45;
  outline: none;
}
.note-edit-area textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.note-edit-actions {
  display: flex; gap: 6px; justify-content: flex-end;
}
.note-edit-actions .btn {
  font-size: 12px;
  padding: 5px 10px;
}

.notes-empty {
  text-align: center;
  font-size: 13px;
  color: var(--text-mute);
  padding: 28px 12px;
}

@media (max-width: 880px) {
  .notes-modal {
    width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
  }
  .notes-modal .modal-head {
    padding-top: calc(12px + env(safe-area-inset-top, 0px));
  }
  /* Swap the DOM-order (compose top, list below) so the compose form sits
     above the iOS keyboard and the list scrolls beneath. */
  .notes-body {
    flex-direction: column-reverse;
    padding-bottom: 0;
  }
  .notes-body .notes-list {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
  }
  .notes-body .note-compose {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 0 -16px;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
    background: var(--bg-elev);
    border: 0;
    border-top: 1px solid var(--line);
    border-radius: 0;
  }
}

/* ---------- Voice debug overlay --------------------------------------
   Toggled via ?voiceDebug=1 or localStorage[family-calendar.voice.debug]=1.
   Stays out of the way (bottom-left, dismissible) but surfaces every step
   of the dictate / wake-word / push-to-talk pipelines so staging issues
   are visible without DevTools.
*/
.voice-debug {
  position: fixed;
  left: 12px;
  bottom: 12px;
  z-index: 9999;
  width: min(420px, calc(100vw - 24px));
  max-height: 45vh;
  display: flex;
  flex-direction: column;
  background: rgba(15, 17, 22, 0.92);
  color: #e5e7eb;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
  font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  backdrop-filter: blur(6px);
}
.voice-debug[hidden] { display: none !important; }
.voice-debug-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
  flex-wrap: wrap;
}
.voice-debug-title {
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #d1d5db;
}
.voice-debug-chip {
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(255,255,255,0.08);
  font-size: 10px;
  color: #d1d5db;
}
.voice-debug-chip.ok    { background: rgba(34,197,94,0.22);  color: #bbf7d0; }
.voice-debug-chip.warn  { background: rgba(234,179,8,0.22);  color: #fde68a; }
.voice-debug-chip.bad   { background: rgba(239,68,68,0.22);  color: #fecaca; }
.voice-debug-actions { margin-left: auto; display: flex; gap: 4px; }
.voice-debug-btn {
  border: 1px solid rgba(255,255,255,0.15);
  background: transparent;
  color: #e5e7eb;
  padding: 2px 8px;
  border-radius: 6px;
  font: inherit;
  cursor: pointer;
}
.voice-debug-btn:hover { background: rgba(255,255,255,0.08); }
.voice-debug-log {
  flex: 1;
  overflow-y: auto;
  padding: 6px 8px;
  margin: 0;
  list-style: none;
}
.voice-debug-log li {
  padding: 2px 0;
  border-bottom: 1px dotted rgba(255,255,255,0.06);
  word-break: break-word;
  white-space: pre-wrap;
}
.voice-debug-log li:last-child { border-bottom: 0; }
.voice-debug-log .t   { color: #9ca3af; }
.voice-debug-log .cat { color: #93c5fd; font-weight: 600; margin: 0 6px; }
.voice-debug-log .warn .cat  { color: #fde68a; }
.voice-debug-log .error .cat { color: #fca5a5; }
.voice-debug-log .ok .cat    { color: #86efac; }

/* ===========================================================================
   Planner — personal daily-routine / time-blocking scene + routine editor.
   A full-page scene (body[data-scene="planner"]) like Settings/Dev. Uses the
   design tokens throughout; the only hardcoded colors live in the JS category
   palette and arrive here as the --cat-color / --routine-color custom props.
   =========================================================================== */
.planner-view {
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* Override .app-view's padding/gap/scroll — the planner owns its own
     header + an internally-scrolling timeline body. */
  padding: 0;
  gap: 0;
  overflow: hidden;
  background: var(--bg);
  animation: viewFadeIn .22s ease-out;
}

.planner-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-elev);
}
.planner-back { flex: 0 0 auto; }
.planner-datenav {
  display: flex; align-items: center; gap: 6px;
  flex: 1 1 auto; min-width: 0;
}
.planner-date-title {
  margin: 0;
  font-size: 17px; font-weight: 700; letter-spacing: -0.01em;
  color: var(--text);
  min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.planner-today-btn { margin-left: 4px; }
.planner-head-right {
  display: flex; align-items: center; gap: 14px;
  flex: 0 0 auto;
}

/* Adherence ring */
.planner-ring { position: relative; width: 44px; height: 44px; flex: 0 0 auto; }
.planner-ring-track { stroke: var(--bg-soft); }
.planner-ring-fill {
  stroke: var(--primary);
  transition: stroke-dashoffset .4s ease;
}
.planner-ring-label {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700;
  color: var(--text); font-variant-numeric: tabular-nums;
}

/* Adherence sparkline */
.planner-spark {
  display: flex; align-items: flex-end; gap: 3px;
  height: 30px; padding: 0 2px;
}
.planner-spark-bar {
  position: relative;
  width: 7px; min-height: 3px;
  border-radius: 3px;
  background: var(--bg-soft);
  overflow: hidden;
  display: flex; align-items: flex-end;
}
.planner-spark-fill {
  width: 100%;
  background: var(--primary);
  border-radius: 3px;
  opacity: .55;
}
.planner-spark-bar.is-today { outline: 1.5px solid var(--primary); outline-offset: 1px; }
.planner-spark-bar.is-today .planner-spark-fill { opacity: 1; }

/* Timeline body */
.planner-body {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto;
  padding: 16px 18px 40px;
}
.planner-timeline { position: relative; margin: 0 auto; max-width: 880px; }

.planner-grid { position: absolute; inset: 0; pointer-events: none; }
.planner-hour { position: absolute; left: 0; right: 0; display: flex; align-items: center; gap: 8px; }
.planner-hour-label {
  width: 52px; flex: 0 0 52px; text-align: right;
  font-size: 11px; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
  transform: translateY(-50%);
}
.planner-hour-line { flex: 1; height: 1px; background: var(--line); transform: translateY(-50%); }

/* Now-line (today only) */
.planner-now { position: absolute; left: 52px; right: 0; display: flex; align-items: center; z-index: 5; pointer-events: none; }
.planner-now-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--danger); margin-left: -4px; box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 22%, transparent); }
.planner-now-line { flex: 1; height: 2px; background: var(--danger); }

/* Blocks */
.planner-block {
  position: absolute;
  display: flex; align-items: stretch; gap: 6px;
  background: color-mix(in srgb, var(--cat-color) 9%, var(--bg-elev));
  border: 1px solid color-mix(in srgb, var(--cat-color) 30%, var(--line));
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .12s, opacity .15s, transform .05s;
}
.planner-block:hover { box-shadow: var(--shadow-md); }
.planner-block-stripe { width: 4px; flex: 0 0 4px; background: var(--cat-color); }
.planner-block.in-progress {
  border-color: var(--cat-color);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--cat-color) 35%, transparent), var(--shadow-md);
}
.planner-block.status-done { opacity: .62; }
.planner-block.status-skipped {
  opacity: .7;
  background:
    repeating-linear-gradient(135deg, transparent 0 6px, color-mix(in srgb, var(--text-mute) 10%, transparent) 6px 12px),
    var(--bg-soft);
  border-color: var(--line);
}
.planner-block.status-skipped .planner-block-stripe { background: var(--text-mute); }

.planner-block-check {
  align-self: flex-start;
  margin: 7px 0 0 6px;
  width: 22px; height: 22px; flex: 0 0 22px;
  border-radius: 7px;
  border: 1.5px solid color-mix(in srgb, var(--cat-color) 45%, var(--line));
  background: var(--bg-elev);
  color: var(--on-primary);
  display: grid; place-items: center;
  cursor: pointer;
  transition: background .12s, border-color .12s, transform .05s;
}
.planner-block-check:hover { border-color: var(--cat-color); }
.planner-block-check[aria-pressed="true"] {
  background: var(--cat-color);
  border-color: var(--cat-color);
}
.planner-block-check:active { transform: scale(.92); }

.planner-block-main {
  flex: 1 1 auto; min-width: 0;
  padding: 6px 4px 6px 0;
  display: flex; flex-direction: column; gap: 2px;
  justify-content: center;
}
.planner-block-top { display: flex; align-items: center; gap: 6px; min-width: 0; }
.planner-block-icon { font-size: 14px; flex: 0 0 auto; line-height: 1; }
.planner-block-title {
  font-size: 13px; font-weight: 700; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.planner-block.status-done .planner-block-title { text-decoration: line-through; }
.planner-block-streak {
  flex: 0 0 auto;
  font-size: 11px; font-weight: 700;
  color: var(--warn);
  font-variant-numeric: tabular-nums;
}
.planner-block-meta { display: flex; align-items: center; gap: 8px; min-width: 0; }
.planner-block-time { font-size: 11px; color: var(--text-soft); font-variant-numeric: tabular-nums; white-space: nowrap; }
.planner-block-routine {
  font-size: 10px; font-weight: 600;
  color: var(--routine-color, var(--text-mute));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.planner-block-skip {
  align-self: flex-start;
  margin: 7px 6px 0 0;
  width: 22px; height: 22px; flex: 0 0 22px;
  border-radius: 7px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-mute);
  display: grid; place-items: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s, background .12s, color .12s;
}
.planner-block:hover .planner-block-skip,
.planner-block.status-skipped .planner-block-skip { opacity: 1; }
.planner-block-skip:hover { background: var(--bg-hover); color: var(--text); }
.planner-block-skip[aria-pressed="true"] { color: var(--text-soft); opacity: 1; }

/* Empty state */
.planner-empty {
  max-width: 460px; margin: 60px auto;
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.planner-empty-icon {
  width: 64px; height: 64px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--primary-tint); color: var(--primary);
}
.planner-empty h2 { margin: 4px 0 0; font-size: 18px; font-weight: 700; color: var(--text); }
.planner-empty p { margin: 0; color: var(--text-soft); line-height: 1.55; font-size: 14px; }
.planner-empty .btn { margin-top: 6px; }

/* ---- Routine editor modal ---- */
.routines-modal { width: min(620px, calc(100vw - 32px)); }
.routines-modal .modal-head { gap: 8px; align-items: baseline; }
.routines-modal .modal-head h3 { flex: 0 0 auto; }
.routines-modal-sub { font-size: 12px; color: var(--text-mute); margin-right: auto; }
.routines-body { padding: 16px; overflow: auto; display: flex; flex-direction: column; gap: 14px; }
.routines-toolbar { display: flex; gap: 8px; flex-wrap: wrap; }
.routines-container { display: flex; flex-direction: column; gap: 12px; }
.routines-empty { color: var(--text-mute); font-size: 13px; text-align: center; padding: 18px 8px; }

.routine-card {
  border: 1px solid var(--line);
  border-left: 3px solid var(--routine-color, var(--primary));
  border-radius: var(--radius-md);
  background: var(--bg-elev);
  overflow: hidden;
}
.routine-card-head { display: flex; align-items: center; gap: 8px; padding: 8px 10px; flex-wrap: wrap; }
.routine-expand {
  border: 0; background: transparent; color: var(--text-soft);
  width: 26px; height: 26px; flex: 0 0 auto;
  display: grid; place-items: center; cursor: pointer; border-radius: 6px;
}
.routine-expand:hover { background: var(--bg-hover); color: var(--text); }
.routine-chevron { transition: transform .15s ease; }
.routine-card.is-open .routine-chevron { transform: rotate(90deg); }
.routine-swatch {
  width: 24px; height: 24px; flex: 0 0 auto;
  padding: 0; border: 1px solid var(--line); border-radius: 6px;
  background: none; cursor: pointer;
}
.routine-swatch::-webkit-color-swatch-wrapper { padding: 2px; }
.routine-swatch::-webkit-color-swatch { border: 0; border-radius: 4px; }
.routine-name {
  flex: 1 1 140px; min-width: 0;
  border: 1px solid transparent; background: transparent;
  font-size: 14px; font-weight: 700; color: var(--text);
  padding: 4px 6px; border-radius: 7px;
  font-family: inherit;
}
.routine-name:hover { background: var(--bg-soft); }
.routine-name:focus { background: var(--bg-soft); border-color: var(--line-strong); outline: none; }
.routine-count { font-size: 11px; color: var(--text-mute); flex: 0 0 auto; }
.routine-active {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--text-soft); cursor: pointer; flex: 0 0 auto;
}
.routine-active input { accent-color: var(--primary); }

.routine-blocks {
  display: flex; flex-direction: column; gap: 10px;
  padding: 4px 10px 12px;
  border-top: 1px solid var(--line);
}
.routine-blocks-empty { color: var(--text-mute); font-size: 13px; margin: 4px 0; }
.routine-block {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-soft);
  padding: 8px 10px;
  display: flex; flex-direction: column; gap: 8px;
}
.routine-block-row { display: flex; align-items: center; gap: 8px; }
.routine-block-times { flex-wrap: wrap; }
.routine-block-title {
  flex: 1 1 auto; min-width: 0;
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg-elev); color: var(--text);
  padding: 6px 8px; font-size: 13px; font-weight: 600; font-family: inherit;
}
.routine-field { display: flex; flex-direction: column; gap: 3px; font-size: 10px; color: var(--text-mute); }
.routine-field > span { text-transform: uppercase; letter-spacing: .05em; font-weight: 700; }
.routine-field input, .routine-field select {
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg-elev); color: var(--text);
  padding: 5px 7px; font-size: 12px; font-family: inherit;
}
.routine-field-icon input { width: 48px; text-align: center; }
.routine-block-days { flex-wrap: wrap; gap: 6px; }
.routine-block-days-lbl { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; font-weight: 700; color: var(--text-mute); }
.routine-dow { display: inline-flex; gap: 4px; }
.routine-dow-chip {
  width: 26px; height: 26px; border-radius: 7px;
  border: 1px solid var(--line); background: var(--bg-elev);
  color: var(--text-mute); font-size: 11px; font-weight: 700; cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.routine-dow-chip:hover { background: var(--bg-hover); }
.routine-dow-chip.on {
  background: var(--primary-fill); color: var(--on-primary); border-color: var(--primary-fill);
}
.routine-block-notes {
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg-elev); color: var(--text);
  padding: 5px 8px; font-size: 12px; font-family: inherit;
}
.routine-block-del { width: 28px; height: 28px; flex: 0 0 auto; color: var(--text-mute); }
.routine-block-del:hover { color: var(--danger); border-color: var(--danger); }
.routine-add-block { align-self: flex-start; }

/* Template gallery */
.routine-templates-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.routine-templates-title { font-size: 14px; font-weight: 700; color: var(--text); }
.routine-templates-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.rt-tpl {
  text-align: left;
  border: 1px solid var(--line);
  border-left: 3px solid var(--routine-color, var(--primary));
  border-radius: var(--radius-md);
  background: var(--bg-soft);
  padding: 12px 14px;
  cursor: pointer; font: inherit; color: inherit;
  display: flex; flex-direction: column; gap: 5px;
  transition: background .12s, border-color .12s, transform .05s;
}
.rt-tpl:hover { background: var(--bg-hover); border-left-color: var(--routine-color, var(--primary)); transform: translateY(-1px); }
.rt-tpl:active { transform: translateY(0); }
.rt-tpl-name { font-size: 14px; font-weight: 700; color: var(--text); }
.rt-tpl-desc { font-size: 12px; color: var(--text-soft); line-height: 1.45; }
.rt-tpl-dots { display: flex; align-items: center; gap: 4px; margin-top: 4px; }
.rt-tpl-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.rt-tpl-count { margin-left: auto; font-size: 11px; color: var(--text-mute); }

@media (max-width: 880px) {
  /* Hide the calendar topbar + tabs while the planner scene is up so it
     reads as a dedicated mobile page (same treatment as Settings). */
  body[data-scene="planner"] .topbar,
  body[data-scene="planner"] .mobile-tabs { display: none !important; }

  /* Canonical mobile scene header (back chevron + centered title) — the same
     chrome as Settings / Baby / Water / Meds and the Lists modal-page, so
     hopping between these full-screen pages feels like one app. The mobile
     head owns "back", so the inline "Calendar" ghost button is redundant. */
  body[data-scene="planner"] .planner-back { display: none; }
  body[data-scene="planner"] .app-view-mobile-head {
    display: flex; align-items: center; gap: 6px;
    position: sticky; top: 0; z-index: 40;
    padding: 6px 8px;
    padding-top: max(6px, env(safe-area-inset-top));
    background: color-mix(in srgb, var(--bg-elev) 96%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--line);
  }
  body[data-scene="planner"] .app-view-back { width: 40px; height: 40px; color: var(--text); }
  body[data-scene="planner"] .app-view-back:hover { background: var(--bg-hover); }
  body[data-scene="planner"] .app-view-mobile-title {
    margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; color: var(--text);
  }

  /* The planner's own controls (date-nav + adherence ring + Edit routines) now
     sit as a solid sub-bar directly beneath the mobile head — no second
     sticky/blur bar competing with it. */
  .planner-head { padding: 8px 12px; gap: 8px; }
  .planner-date-title { font-size: 15px; }
  .planner-head-right { gap: 10px; flex: 1 1 100%; justify-content: flex-start; order: 3; }
  .planner-edit-btn { margin-left: auto; }
  .planner-body { padding: 12px 10px 40px; }
  .planner-block-skip { opacity: 1; } /* no hover on touch — always show */
  .routine-templates-grid { grid-template-columns: 1fr; }
}

/* ===========================================================================
   Mobile redesign (overrides — kept at the end so they win specificity races)
   ===========================================================================

   Goal: a phone-first calendar that follows the patterns of Apple/Google/
   Fantastical — agenda-forward, big tap targets, no horizontal pinching.
   We override scattered earlier mobile rules in one place so the whole
   mobile experience is auditable from this block.

   Breakpoint strategy:
     ≤880px → mobile/tablet (everything below)
     ≤480px → small phones (tighter spacing only) */

@media (max-width: 880px) {
  /* ---------- Layout shell ----------
     `.side` mobile reset (display: contents, position: static, etc.) and
     `.side-close` hiding both live next to the desktop rule (search for
     "Side panel" earlier in this file) so the natural cascade wins.
     Keep .side-toggle-btn forced-hidden here in case any later rule
     reintroduces it. */
  .side-toggle-btn { display: none !important; }

  /* Layout becomes a single column flex stack so the active pane gets the
     full vertical space without grid auto-rows splitting it among hidden
     siblings. */
  .layout {
    display: flex !important;
    flex-direction: column;
    height: 100%;
    min-height: 0;
  }
  [data-pane] { display: none; }
  [data-pane].pane-active {
    display: flex !important;
    flex-direction: column;
    flex: 1;
    min-height: 0;
  }

  /* Full-screen mobile modals (.entry-modal, .entry-editor-modal,
     .notes-modal) want to reach 100vw — drop modal-root's inset so the
     backdrop isn't visible behind the modal's edges. */
  .modal-root { padding: 0; }

  /* Reserve room at the bottom of scrolling day/milestones panes so the
     PTT FAB doesn't cover the last entry or the Add-an-entry trigger. */
  .card.day-card[data-pane].pane-active,
  .ms-card[data-pane].pane-active,
  .insights-card[data-pane].pane-active {
    padding-bottom: calc(96px + env(safe-area-inset-bottom));
  }

  /* ---------- Topbar ----------
     Two rows on phones:
       Row 1: [Today] [<] [>] Title ........ [icons]
       Row 2: full-width [ Month | Week | Year ]
     Previously the view switcher was hidden on phones — that was wrong;
     a calendar app without a view switcher is a list. */
  .topbar {
    flex-wrap: wrap;
    padding: calc(6px + env(safe-area-inset-top, 0px)) 10px 6px;
    gap: 8px;
    min-height: auto;
  }
  .topbar-left {
    gap: 6px;
    flex: 1 1 auto;
    order: 1;
    min-width: 0;
  }
  .topbar-right {
    gap: 4px;
    order: 2;
    flex: 0 0 auto;
    margin-left: auto;
  }
  /* View switcher is desktop-only. On phones it ate a whole second row, so
     Day/Week/Month/Year now live in the ⋯ More menu (and the default view is
     set in Settings → Calendar). Hiding it keeps the topbar to ONE line. */
  .view-seg { display: none !important; }
  .topbar-divider { display: none; }
  /* Phone topbar-right = [More ⋯] only (+ invites badge when pending).
     Every other action — Settings and the Baby-calendar toggle included —
     folds into the More menu so the title keeps room and nothing wraps to a
     second row on a ~360px screen. */
  .topbar #chatBtn,
  .topbar #notesBtn,
  .topbar #listsBtn,
  .topbar #plannerBtn,
  .topbar #insightsBtn,
  .topbar #jobsBtn,
  .topbar #shareBtn,
  .topbar #ambientBtn,
  .topbar #screensaverBtn,
  .topbar #settingsBtn,
  .topbar #babyCalBtn,
  .topbar .side-toggle-btn { display: none; }
  .topbar .topbar-more-btn { display: inline-grid; }
  .topbar-title {
    font-size: 16px;
    font-weight: 600;
    min-width: 0;
    flex: 1 1 auto;
  }
  .today-btn {
    padding: 6px 12px;
    min-height: 34px;
    font-size: 13px;
    flex-shrink: 0;
  }
  .topbar .iconbtn { width: 36px; height: 36px; }
  .nav-arrow { width: 34px; height: 34px; }
  /* Hide the brand icon on phones — Today is the brand replacement, and
     the topbar real estate is precious. */
  .brand-mark { display: none; }

  /* ---------- Mobile pane tabs ----------
     The topbar's view switcher (Month/Week/Year) is the primary mode
     control on phones now. The Calendar/Day/Milestones tabs are still
     navigable, but we only show them as a slim bottom strip when the user
     is OFF the calendar pane (so they can get back). On the calendar pane,
     tapping a date is the way to the day sheet — no tab needed. */
  .mobile-tabs {
    display: none !important;
  }
  .app[data-mobile-pane="day"] .mobile-tabs,
  .app[data-mobile-pane="milestones"] .mobile-tabs {
    display: flex !important;
    position: sticky;
    top: 0;
    z-index: 50;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
    border-top: 0;
    padding: 0;
    margin: 0;
    background: var(--bg);
    box-shadow: 0 1px 0 var(--line);
  }
  .mtab {
    padding: 12px 8px;
    border-radius: 0;
    font-size: 13px;
    border-bottom: 2px solid transparent;
  }
  .mtab.active {
    background: transparent;
    color: var(--primary);
    border-bottom-color: var(--primary);
  }

  /* ---------- Calendar panel container ---------- */
  .cal-panel {
    margin: 0 !important;
    border-radius: 0 !important;
    border: 0 !important;
    background: var(--bg);
  }

  /* ---------- Weekday header (month view) ----------
     Make the abbreviated day labels readable but compact. */
  .weekdays > div {
    padding: 8px 0;
    font-size: 11px;
    text-align: center;
    font-weight: 700;
  }

  /* ---------- Month grid cells ----------
     The old rule packed pills with the full event text into ~50px-wide
     cells — illegible. Switch to a "title + colored dots" pattern: each
     entry is just a colored dot, with the day number and count.  Tap a
     day and the side panel auto-pops as a bottom sheet. */
  .grid {
    grid-auto-rows: minmax(56px, 1fr);
    gap: 1px;
  }
  .cell {
    padding: 4px 4px 6px;
    gap: 2px;
    min-height: 56px;
    align-items: stretch;
  }
  .cell-head {
    grid-template-columns: auto auto;
    justify-content: center;
    align-items: center;
    gap: 4px;
    margin-bottom: 2px;
  }
  .cell-head .day-num {
    justify-self: auto;
    font-size: 14px;
  }
  .cell.today .day-num {
    width: 24px;
    height: 24px;
    font-size: 12px;
  }
  .cell-head .cell-head-right {
    justify-self: auto;
    margin-top: 0;
  }
  .cell-head .wx-chip { display: none; }
  .cell-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 14px;
    height: 14px;
    padding: 0 4px;
    border-radius: 7px;
    background: var(--bg-soft);
    color: var(--text-mute);
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
  }

  /* First pill renders the title as one-line truncated text; the rest
     collapse to compact dots beneath it (up to four; anything beyond is
     summarised by ".cell-more"). */
  .cell-list {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-content: flex-start;
    gap: 3px;
    padding-top: 1px;
  }
  .cell .pill {
    width: 5px;
    height: 5px;
    min-width: 0;
    padding: 0;
    border-radius: 50%;
    background: var(--entry-color);
    color: transparent;
    overflow: hidden;
    flex: 0 0 auto;
    line-height: 0;
    font-size: 0;
  }
  .cell .pill > * { display: none; }
  .cell .pill:first-of-type {
    width: 100%;
    height: auto;
    min-height: 16px;
    border-radius: 4px;
    padding: 1px 4px;
    background: color-mix(in srgb, var(--entry-color) 16%, var(--bg-soft));
    color: var(--text);
    font-size: 11px;
    line-height: 1.25;
    font-weight: 600;
    white-space: nowrap;
    text-overflow: ellipsis;
    border-left: 2px solid var(--entry-color);
  }
  .cell .pill:first-of-type.milestone {
    background: color-mix(in srgb, var(--warn) 16%, var(--bg-soft));
    border-left-color: var(--warn);
  }
  .cell .pill:first-of-type.is-holiday {
    background: color-mix(in srgb, var(--holiday, var(--text-mute)) 16%, var(--bg-soft));
    border-left-color: var(--holiday, var(--text-mute));
  }
  .cell .pill.milestone {
    background: var(--warn);
  }
  .cell .pill.is-holiday {
    background: var(--holiday, var(--text-mute));
  }
  .cell .pill.is-done {
    opacity: .5;
  }
  .cell-more {
    margin-top: 0;
    font-size: 10px;
    text-align: center;
    color: var(--text-mute);
    font-weight: 600;
    line-height: 1;
  }

  /* When overflow indicator is present, keep the first pill visible but
     hide the dot row so the title + "+N more" stack reads cleanly. */
  .cell.has-overflow .cell-list .pill:not(:first-of-type) { display: none; }

  /* Selected day gets a stronger ring so the user can see which day will
     show in the bottom sheet. */
  .cell.selected {
    box-shadow: inset 0 0 0 2px var(--primary);
    background: color-mix(in srgb, var(--primary) 8%, var(--bg-elev));
  }

  /* ---------- Week view: vertical day stack ----------
     The 7-column timed grid is unusable on a 375px screen (≈48px per day).
     Hide the time-grid structure entirely and let the agenda fallback (the
     #weekTimeView ::after fallback we render below) take over. The
     JS-generated grid still fills #wtGrid; we restyle it as a vertical
     stack. */
  .week-time-view { overflow-y: auto; }
  /* Earlier/Later/Fit only steer the desktop hour-grid; the vertical
     agenda below has no hour scrolling for them to control. */
  .wt-toolbar { display: none; }
  .wt-grid {
    display: flex !important;
    flex-direction: column;
    grid-template-columns: none !important;
    grid-template-rows: none !important;
    background: var(--bg) !important;
    gap: 0 !important;
    overflow: visible;
  }
  /* The corner/allday-label/gutter pieces are scaffolding for the desktop
     grid layout — they have no place in the vertical stack. */
  .wt-corner,
  .wt-allday-label,
  .wt-hours-gutter { display: none !important; }
  /* Day header becomes a section heading. */
  .wt-day-head {
    display: flex !important;
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
    padding: 14px 16px 6px;
    border-top: 1px solid var(--line);
    background: var(--bg);
    grid-template-columns: none !important;
  }
  .wt-day-head:first-of-type { border-top: 0; }
  .wt-day-name {
    font-size: 11px;
    letter-spacing: .12em;
    color: var(--text-mute);
  }
  .wt-day-head.today .wt-day-name { color: var(--primary); }
  .wt-day-num {
    font-size: 22px;
    font-weight: 700;
    color: var(--text);
    line-height: 1;
  }
  .wt-day-head.today .wt-day-num {
    width: auto;
    height: auto;
    background: transparent;
    color: var(--primary);
    font-size: 22px;
    padding: 0;
    border-radius: 0;
    font-weight: 800;
  }
  .wt-day-wx { margin-left: auto; }

  /* All-day strip becomes a horizontal list under the day header. */
  .wt-allday {
    flex-direction: column;
    gap: 4px;
    padding: 4px 16px 4px;
    max-height: none;
    background: var(--bg);
    overflow: visible;
  }
  .wt-allday:empty { display: none; } /* still hide empty all-day strip; day-col now shows placeholder */
  .wt-allday .pill {
    font-size: 13px;
    padding: 6px 10px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--entry-color) 14%, var(--bg-soft));
    color: var(--text);
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
    line-height: 1.4;
    width: auto;
    height: auto;
    display: flex;
    align-items: center;
    gap: 6px;
  }
  .wt-allday .pill > * { display: inline; }
  .wt-allday .pill .pill-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--entry-color);
    flex-shrink: 0;
  }

  /* Day column → vertical agenda. Drop position-based pixel layout; let
     the timed blocks flow as a list with their time label as a prefix.
     Now the entry text is fully visible. */
  .wt-day-col {
    position: static;
    padding: 0 16px 14px;
    overflow: visible;
    min-height: 0;
    background: var(--bg) !important;
    border: 0 !important;
    box-shadow: none !important;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .wt-day-col:empty {
    min-height: 28px;
    padding-top: 0;
  }
  .wt-day-col:empty::before {
    content: "Nothing scheduled";
    font-size: 12px;
    color: var(--text-mute);
    font-style: italic;
  }
  /* Today marker chip — small "Today" pill next to the day name. */
  .wt-day-head.today .wt-day-name::after {
    content: "Today";
    margin-left: 6px;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--primary-fill);
    color: var(--on-primary);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
  }
  .wt-day-col.weekend { background: var(--bg) !important; }
  .wt-day-col.selected {
    box-shadow: none !important;
    background: color-mix(in srgb, var(--primary) 5%, var(--bg)) !important;
  }
  /* The desktop rounded-chip highlight doesn't fit the stacked mobile rows
     (and ::before is taken by the empty-state placeholder), so drop it here —
     mobile keeps the flat tint above + the "Today" pill on the day name. */
  .wt-day-head.selected::after,
  .wt-day-col.selected::after { content: none; }
  .wt-hourline, .wt-now-line { display: none !important; }
  .wt-event {
    position: static !important;
    left: auto !important; right: auto !important;
    top: auto !important; height: auto !important;
    width: 100%;
    padding: 10px 12px;
    border-radius: var(--radius-md);
    border-left-width: 4px;
    background: var(--bg-elev) !important;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: 2px;
  }
  .wt-event-time {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-soft);
    letter-spacing: .02em;
  }
  .wt-event-text {
    -webkit-line-clamp: unset;
    display: block;
    font-size: 15px;
    line-height: 1.35;
    white-space: normal;
    overflow: visible;
  }

  /* ---------- Year view ----------
     The 12-month grid stays, but on phones we want 2 columns with bigger
     day-cells (40px) so they're tappable. Drop the mini-day-of-week strip
     to claw back vertical space. */
  .year-view { padding: 8px 8px 12px; }
  .year-months-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }
  .ym-card {
    padding: 10px 8px 10px;
    border-radius: 12px;
    gap: 4px;
  }
  .ym-head {
    font-size: 14px;
    padding: 4px 6px;
    text-align: center;
    font-weight: 700;
  }
  .ym-card.current .ym-head { color: var(--primary); }
  .ym-dow > span, .ym-day { font-size: 10px; }
  .ym-dow {
    display: grid;
    font-size: 8px;
    opacity: .55;
  }
  .ym-day {
    min-height: 24px;
    font-size: 11px;
    border-radius: 4px;
  }
  .ym-day.today {
    background: var(--primary-fill);
    color: var(--on-primary);
  }
  /* Single-column when the screen is REALLY narrow (≤360px) */
}

/* Phones at ≤480 get a single-column year view — two columns of 7-day
   mini-grids each ~175px wide produce 24×25px tap targets, too cramped. */
@media (max-width: 480px) {
  .year-months-grid {
    grid-template-columns: 1fr;
  }
  .ym-day { min-height: 32px; font-size: 13px; }
}

@media (max-width: 480px) {
  /* Small-phone tightenings */
  .topbar { padding-left: 8px; padding-right: 8px; gap: 6px; }
  .topbar-title { font-size: 15px; }
  .topbar-left { gap: 4px; }
  .today-btn { padding: 5px 10px; }
  .view-seg .seg-btn { padding: 5px 10px; font-size: 11px; }

  .cell { padding: 3px 2px 5px; }
  .grid { grid-auto-rows: minmax(52px, 1fr); }
  .cell.today .day-num { width: 22px; height: 22px; font-size: 11px; }

  .wt-day-head { padding: 12px 12px 4px; }
  .wt-allday, .wt-day-col { padding-left: 12px; padding-right: 12px; }
}

/* The push-to-talk FAB (.ptt-fab) is the primary "fast entry" affordance
   on mobile — long-press to dictate. The other fast paths (tap a day cell
   → entry editor; mobile-tabs → Day → "Add an entry…") cover keyboard
   users. We intentionally do not stack a second "+" FAB on top of the
   PTT FAB; one floating action is enough on a phone. */

/* ============================================================
   Wave-1 mobile UX pass: consolidated touch-target sizes,
   hover-only affordance fallbacks, and iOS-zoom prevention.
   Lives at the bottom so it overrides earlier desktop defaults.
   ============================================================ */
@media (max-width: 480px) {
  /* Topbar iconbtn already bumped to 36×36 at this breakpoint above;
     general iconbtn (e.g. inside cards / modals) gets the same hit area. */
  .iconbtn { width: 40px; height: 40px; }
  .topbar .iconbtn { width: 40px; height: 40px; }

  .btn.small { min-height: 36px; padding: 8px 14px; }
  .link.small {
    min-height: 36px;
    padding: 8px 10px;
    display: inline-flex;
    align-items: center;
  }

  .day-sec-tab { padding: 12px 6px; }

  .accent-swatch { width: 40px; height: 40px; }

  .switch { width: 48px; height: 28px; }
  .switch-slider::before { width: 20px; height: 20px; }
  .switch input:checked + .switch-slider::before { transform: translateX(20px); }

  .ee-switch-track { width: 36px; height: 22px; }
  .ee-switch-thumb { width: 18px; height: 18px; }
  .ee-allday-switch input:checked + .ee-switch-track .ee-switch-thumb { transform: translateX(14px); }

  .ee-wd { width: 36px; height: 36px; font-size: 13px; }

  .ee-tag-pill input[type="color"] { width: 22px; height: 22px; }

  .about-del { width: 40px; height: 40px; }

  .app-view-tab { min-height: 44px; padding: 12px 14px; }

  .draft-att-x { width: 22px; height: 22px; font-size: 14px; }

  .auth-submit { min-height: 44px; }

  /* iOS Safari zooms the page when a focused input has font-size < 16px.
     Bump every text-entry surface that currently inherits 14px. */
  .auth-card input,
  .entry-editor-body input[type="text"],
  .entry-editor-body input[type="date"],
  .entry-editor-body input[type="time"],
  .entry-editor-body input[type="number"],
  .entry-editor-body textarea,
  .entry-editor-body select,
  #noteComposeInput,
  .note-compose textarea,
  #chatInput,
  .chat-input-row textarea,
  #entryInput,
  .entry-modal #entryInput,
  .app-view-card .field input,
  .app-view-card .field textarea,
  .app-view-card .field select,
  #msForm input[type="text"],
  #msForm input[type="date"],
  #msForm input[type="number"],
  #msForm textarea,
  #msForm select,
  #listCreateTitle,
  .lists-modal input[type="text"],
  .lists-modal select,
  .baby-log-form input,
  .baby-log-form textarea,
  .baby-log-form select,
  .baby-profile-form input,
  .baby-profile-form textarea,
  .baby-profile-form select { font-size: 16px; }

  /* Lightbox close/delete buttons need safe-area-aware top offset and
     larger hit area on small phones. */
  .lightbox-close, .lightbox-del {
    top: max(16px, env(safe-area-inset-top));
    padding: 10px 14px;
  }
}

/* ============================================================
   Wave-2 mobile UX pass: per-view P0/P1 fixes layered on top of
   wave-1. Lives at the bottom so it overrides earlier rules.
   ============================================================ */
@media (max-width: 880px) {
  /* Footer (sync dot + shortcuts link) is desktop-only chrome. */
  .footer { display: none; }

  /* Hide the keyboard-hint "↵" pill on the add-entry trigger. */
  .aet-hint { display: none; }

  /* Memory/photo strips: visual scroll cue. The mask is a no-op when
     content fits, and trails off at the right when it overflows. */
  .day-photos-strip,
  .day-memories-strip {
    -webkit-mask-image: linear-gradient(to right, #000 90%, transparent);
            mask-image: linear-gradient(to right, #000 90%, transparent);
  }

  /* Inline weather-chip: always show the conditions label on touch. */
  .weather-label { display: inline; }

  /* Entry editor: stacked time fields render the arrow as orphaned glyph. */
  .ee-time-arrow { display: none; }
  /* Cap the tag grid; let touch users swipe inside the overflow region. */
  .ee-tag-grid { max-height: 140px; overflow-y: auto; }

  /* Find-a-time popover: force full-width inside the fullscreen entry
     modal — the JS positioning math clamps it flush-left otherwise. */
  .find-time-pop {
    left: 8px !important;
    right: 8px !important;
    width: auto !important;
    max-width: none !important;
  }
  .find-time-pop .ft-results { max-height: 40vh; }

  /* Year-in-review header: title + close stay on row 1; year picker +
     Save image button wrap to row 2 so they aren't squeezed. The h3 takes
     enough room to push the year/save buttons (order:2) to wrap. */
  .year-review-modal .modal-head { flex-wrap: wrap; row-gap: 8px; }
  .year-review-modal .modal-head h3 {
    flex: 1 1 100%;
    order: 0;
    min-width: 0;
  }
  .year-review-modal .modal-head [data-close] {
    order: 1;
    position: absolute;
    top: 8px;
    right: 8px;
  }
  .year-review-modal .modal-head { position: relative; padding-right: 56px; }
  .year-review-modal .modal-head .year-review-year {
    order: 2;
    flex: 1 1 auto;
    min-width: 0;
  }
  .year-review-modal .modal-head .yr-share-btn {
    order: 3;
    flex: 0 0 auto;
  }

  /* Chat modal becomes fullscreen, suggestions become a one-line scroller,
     input row gets safe-area padding. */
  .chat-modal {
    width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
  }
  .chat-suggestions {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-mask-image: linear-gradient(to right, #000 90%, transparent);
            mask-image: linear-gradient(to right, #000 90%, transparent);
  }
  .chat-suggestions .chat-chip { flex-shrink: 0; }
  .chat-input-row {
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  }

  /* Developer view: dev-table scrolls horizontally; long host chips
     truncate; color-picker field sits side-by-side on dev-row. */
  .dev-table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }
  .dev-host-filter > * {
    max-width: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Color picker stays narrow inline with the preceding text field, instead
     of being stretched full-width by the dev-row stacking rule above it. */
  .dev-row > .field.dev-color-field { flex: 0 0 96px; max-width: 96px; }
  .dev-color-field input[type="color"] { height: 40px; }
}

@media (max-width: 480px) {
  /* Sub-phone topbar: drop the notes icon (brand-mark is already hidden
     at the 880 breakpoint), collapse Today to icon-only. The cmd-palette
     still reaches notes via "Family notes". */
  #notesBtn { display: none; }
  .today-btn {
    font-size: 0;
    padding: 0;
    width: 36px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
  }
  .today-btn::before {
    content: "";
    width: 18px;
    height: 18px;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2'/><line x1='16' y1='2' x2='16' y2='6'/><line x1='8' y1='2' x2='8' y2='6'/><line x1='3' y1='10' x2='21' y2='10'/><circle cx='12' cy='16' r='1.5' fill='currentColor'/></svg>") center/contain no-repeat;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2'/><line x1='16' y1='2' x2='16' y2='6'/><line x1='8' y1='2' x2='8' y2='6'/><line x1='3' y1='10' x2='21' y2='10'/><circle cx='12' cy='16' r='1.5' fill='currentColor'/></svg>") center/contain no-repeat;
  }
}

/* ============================================================
   Wave-3 mobile UX polish: P1/P2 cleanups on top of waves 1 + 2.
   Lives at the bottom so it overrides earlier rules.
   ============================================================ */
@media (max-width: 880px) {
  /* F2: Notes modal head — baseline alignment leaves the close button
     mis-aligned with the title. Center it. */
  .notes-modal .modal-head { align-items: center; }

  /* F3: Notes per-item action buttons — bump hit area on touch. */
  .note-edit-btn,
  .note-del-btn,
  .note-pin-btn { min-height: 36px; padding: 8px 10px; }

  /* E7: Scope-seg ("All / Just me") was sharing the row with prev/next
     day arrows and crowding the title. Wrap to its own line. */
  .day-card .day-actions { flex-wrap: wrap; }
  .scope-seg { order: 99; flex-basis: 100%; margin-top: 4px; margin-left: 0; }

  /* G4: Chat bubble width — extra breathing room on phones. */
  .chat-msg { max-width: 92%; }

  /* I2: Quick-add hint is desktop chrome — popover is unreachable on phones. */
  .qa-hint { display: none; }

  /* O2: Settings rows wrap so the switch drops below long titles. */
  .settings-row { flex-wrap: wrap; }
}

@media (max-width: 480px) {
  /* Q1: Lightbox close/del — larger hit target (wave-1 added safe-area top). */
  .lightbox-close, .lightbox-del {
    padding: 12px 16px;
    min-height: 44px;
    min-width: 44px;
  }

  /* F2 (cont.): Notes subtitle gets ellipsis-clipped to nothing on small
     phones — just hide it. */
  .notes-modal-sub { display: none; }

  /* M4: Dev entry-detail row — stack as a card instead of the 5-col grid. */
  .dev-entry-detail-item {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    grid-template-columns: none;
  }
  .dev-entry-detail-mins,
  .dev-entry-detail-tokens,
  .dev-entry-detail-usd { text-align: left; }
  .dev-entry-detail-usd { display: block; }

  /* M6: Dev KPI strip — tighter, smaller font on small phones. */
  .dev-tokens-kpi,
  .dev-dash-totals { gap: 10px; font-size: 11px; }

  /* H3: Find-a-time member chip — larger hit area for active toggles. */
  .find-time-pop .ft-member-chip { padding: 8px 12px; }

  /* N3: Year-review month-grid label fits better at 9px. */
  .yr-month-label { font-size: 9px; }

  /* J6: "Save event" → "Save" on phones (button is squeezed against
     Cancel in the entry editor toolbar). CSS-only swap. */
  #eeSaveBtn { font-size: 0; }
  #eeSaveBtn::before {
    content: "Save";
    font-size: 14px;
  }
}

/* Touch devices: keep hover-only affordances at least partially visible,
   disable hover-only transforms that flicker on tap-and-hold, and mirror
   the journal-prompt rotate onto :active so touch users get the delight. */
@media (hover: none) {
  .entry-del { opacity: .55 !important; }
  .entry-comment-del { opacity: 1 !important; }
  .note-pin-btn,
  .note-del-btn,
  .note-edit-btn { opacity: 1; }
  .day-photo-thumb:hover { transform: none; }
  .day-memory-thumb:hover { transform: none; }
  .journal-prompt-skip:active { transform: rotate(-60deg); }
  :focus-visible { outline: none; }
  /* E6: weather-chip conditions label should not require hover. */
  .weather-label { display: inline; opacity: 1; }

  /* Touch targets: the planner's check / skip controls are 22px visual
     boxes — fine with a mouse, too small to reliably tap. An outward hit
     area can't be used here (the parent .planner-block has overflow:hidden
     to clip the stripe to its radius, which would crop a ::after; expanding
     outward would also let taps land on the title). Instead grow the
     buttons themselves to 28px on touch — still inside the block, no
     clipping, no neighbour overlap. */
  .planner-block-check,
  .planner-block-skip {
    width: 28px; height: 28px; flex-basis: 28px;
    margin-top: 5px;
  }
}

/* =============================================================
   User-customizable background image
   ============================================================= */

/* Two layers behind everything: the photo itself, then a translucent
   overlay tinted to the current theme so cool-slate type stays legible.
   --user-bg-image is set on :root from JS at boot when an image is
   chosen; --user-bg-opacity backs the overlay alpha. Both layers are
   pointer-events: none and aria-hidden so they don't intercept clicks
   or get announced to screen readers. */
.app-bg,
.app-bg-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;
  display: none;
}
body.has-user-bg .app-bg,
body.has-user-bg .app-bg-overlay { display: block; }
.app-bg {
  z-index: -2;
  background-image: var(--user-bg-image, none);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  /* Soft blur knocks down high-frequency detail so pill text doesn't
     fight the photo. Cheap on modern GPUs. */
  filter: saturate(.95);
}
.app-bg-overlay {
  z-index: -1;
  background: rgba(245, 246, 248, var(--user-bg-opacity, 0.7));
}
[data-theme="dark"] .app-bg-overlay {
  background: rgba(15, 19, 32, var(--user-bg-opacity, 0.7));
}

/* The body's own radial-gradient scrim adds noise on top of the photo.
   When a custom bg is active, drop body to a transparent background so
   the photo + overlay are what the user sees. */
body.has-user-bg {
  background: transparent !important;
}

/* The .app container's background-elev fills (cards, etc.) keep their
   solid surfaces — only the calendar grid cells need to become
   semi-transparent so the user's photo actually shows through. */
body.has-user-bg .cell {
  background: color-mix(in srgb, var(--bg-elev) 78%, transparent);
}
body.has-user-bg .cell.out {
  background: color-mix(in srgb, var(--bg-soft) 70%, transparent);
}
body.has-user-bg .cell.weekend:not(.out) {
  background: color-mix(in srgb,
                        color-mix(in srgb, var(--bg-elev) 70%, var(--bg-soft) 30%) 78%,
                        transparent);
}

/* =============================================================
   Per-day "finished day" background images on past cells
   ============================================================= */

/* Painted by JS: each .cell.has-day-bg gets a `--day-bg-image` inline
   style. A ::before paints the photo full-bleed inside the cell at low
   opacity so existing pill chips, the day number, and the weather chip
   keep contrast. ::after lays a flat overlay tinted to the theme so
   the photo never overpowers the chrome. */
.cell.has-day-bg {
  isolation: isolate;
}
.cell.has-day-bg::before,
.cell.has-day-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  z-index: 0;
}
.cell.has-day-bg::before {
  background-image: var(--day-bg-image, none);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  /* User-adjustable via Settings → Appearance → Day images. Falls back to
     .55 (the original hard-coded value) when the var isn't set. */
  opacity: var(--day-bg-opacity, .55);
}
.cell.has-day-bg::after {
  background: rgba(255, 255, 255, .35);
}
[data-theme="dark"] .cell.has-day-bg::after {
  background: rgba(15, 19, 32, .45);
}
/* Lift the cell's actual contents above the photo + overlay layers. */
.cell.has-day-bg > * { position: relative; z-index: 1; }

/* =============================================================
   Settings → Appearance: custom background + day-image controls
   ============================================================= */

.custom-bg-row {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 16px;
  align-items: start;
}
.custom-bg-preview {
  width: 160px;
  height: 100px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--bg-soft) center/cover no-repeat;
  display: grid; place-items: center;
  overflow: hidden;
}
.custom-bg-preview.has-image .custom-bg-empty { display: none; }
.custom-bg-empty {
  color: var(--text-mute);
  font-size: 12px;
}
.custom-bg-controls {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.custom-bg-buttons {
  display: flex; gap: 8px; flex-wrap: wrap;
}
.custom-bg-opacity {
  display: grid;
  grid-template-columns: 1fr;
  gap: 6px;
  font-size: 13px;
  color: var(--text-soft);
}
.custom-bg-opacity > span {
  display: flex; justify-content: space-between; align-items: baseline;
}
.custom-bg-opacity-val {
  color: var(--text);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.custom-bg-opacity input[type="range"] {
  width: 100%;
  accent-color: var(--primary);
}
/* When the opacity control sits in a settings-row (the Day-images card), the
   text column grows and the slider takes a comfortable fixed width. */
.settings-row > .day-bg-opacity { flex: 0 0 200px; }
.custom-bg-status,
.day-bg-status {
  margin: 0;
  font-size: 12px;
  color: var(--text-mute);
  min-height: 1em;
}
.custom-bg-status[data-state="error"],
.day-bg-status[data-state="error"] { color: var(--danger); }
.custom-bg-status[data-state="ok"],
.day-bg-status[data-state="ok"] { color: var(--success); }

.day-bg-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: 8px;
  margin-top: 14px;
}
.day-bg-empty {
  margin: 14px 0 0;
  font-size: 13px;
  color: var(--text-mute);
}
.day-bg-slot {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--bg-soft);
  cursor: pointer;
  overflow: hidden;
  display: grid;
  place-items: center;
  font-size: 13px;
  color: var(--text-soft);
  font-variant-numeric: tabular-nums;
  transition: border-color .12s ease, background .12s ease;
}
.day-bg-slot:hover { border-color: var(--line-strong); background: var(--bg-hover); }
.day-bg-slot:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}
.day-bg-slot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.day-bg-slot.has-image .day-bg-slot-num {
  position: absolute;
  top: 4px; left: 6px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  border-radius: 999px;
  padding: 1px 6px;
  font-size: 11px;
  font-weight: 600;
}
.day-bg-slot-add {
  display: grid; place-items: center; gap: 2px;
  color: var(--text-mute);
  text-align: center;
  line-height: 1.1;
}
.day-bg-slot-add-num { font-weight: 600; color: var(--text-soft); }
.day-bg-slot-add-hint { font-size: 10px; }
.day-bg-slot-remove {
  position: absolute;
  top: 4px; right: 4px;
  width: 18px; height: 18px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .6);
  color: #fff;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  display: none;
  place-items: center;
  padding: 0;
}
.day-bg-slot.has-image .day-bg-slot-remove { display: grid; }
.day-bg-slot.has-image .day-bg-slot-remove:hover { background: var(--danger); }
.day-bg-slot.is-uploading {
  opacity: .55;
  pointer-events: none;
}
.day-bg-slot.is-uploading::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(255,255,255,.18) 50%,
    transparent 100%);
  background-size: 200% 100%;
  animation: dayBgShimmer 1.1s linear infinite;
}
.day-bg-slot.is-errored {
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 8%, var(--bg-soft));
}
.day-bg-slot.is-errored .day-bg-slot-add-hint { color: var(--danger); }
@keyframes dayBgShimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.day-bg-bulk-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 14px;
}
.day-bg-bulk-hint {
  font-size: 12px;
  color: var(--text-mute);
}
.day-bg-bulk-row .btn.primary[disabled] {
  opacity: .55;
  cursor: progress;
}

.day-bg-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
  font-size: 12px;
  color: var(--text-soft);
}
.day-bg-progress-label {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.day-bg-progress-bar {
  position: relative;
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: var(--bg-soft);
  overflow: hidden;
  border: 1px solid var(--line);
}
.day-bg-progress-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--primary-fill, var(--primary));
  transition: width .2s ease;
}

.day-bg-dropzone {
  position: relative;
}
.day-bg-drop-overlay {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-sm);
  border: 2px dashed var(--primary);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  display: none;
  place-items: center;
  pointer-events: none;
  color: var(--primary);
  font-weight: 600;
  font-size: 14px;
  z-index: 2;
}
.day-bg-dropzone.is-dragover .day-bg-drop-overlay { display: grid; }

@media (max-width: 880px) {
  .custom-bg-row {
    grid-template-columns: 1fr;
  }
  .custom-bg-preview { width: 100%; height: 140px; }
  .day-bg-bulk-row .btn.primary { flex: 1; }
}

/* ── Enhancement bundle: reminders, directions, conflict markers ── */
.ee-directions {
  display: inline-flex; align-items: center; gap: 4px;
  margin-top: 6px; font-size: 0.82rem; font-weight: 600;
  color: var(--primary); text-decoration: none;
}
.ee-directions:hover { text-decoration: underline; }
.ee-hint { margin: 6px 0 0; font-size: 0.78rem; color: var(--muted, #888); }
.ee-conflict {
  margin: 8px 0 0; font-size: 0.82rem; font-weight: 600;
  color: var(--warn); line-height: 1.3;
}
.dv-event.is-conflict { box-shadow: inset 0 0 0 1.5px var(--warn); }
.dv-event-warn {
  margin-left: 4px; color: var(--warn); font-weight: 700;
  font-size: 0.85em; line-height: 1;
}

/* ============================ Nyan Cat theme ================================
   A full theme (peer of light/dark) set via [data-theme="nyan"] on .app.
   Deep-space surfaces, rainbow primary, and a pop-tart cat flying across a
   starry sky. Purely cosmetic; the .nyan-cat overlay is pointer-events:none. */
[data-theme="nyan"] {
  color-scheme: dark;
  --bg: #0a0a2e;
  --bg-elev: #161642;
  --bg-soft: #12123a;
  --bg-hover: #232358;
  --line: #2a2a63;
  --line-strong: #4242a6;
  --text: #fdf2ff;
  --text-soft: #cdbcff;
  --text-mute: #9088d6;
  --primary: #ff7fe0;
  --primary-hover: #ff9ae8;
  --primary-soft: #341a52;
  --primary-tint: rgba(255, 127, 224, .16);
  --primary-fill: #d92fb6;
  --on-primary: #ffffff;
  --accent: #36e2ff;
  --accent-soft: #15324a;
  --success: #57f287;
  --warn: #ffd93b;
  --danger: #ff5c7c;
  --danger-soft: #4a1530;
  --coral: #ff6ad5;
  --indigo-soft: #aa00ff;
  --today-ring: #ffd93b;
  --selected-ring: #36e2ff;
  --focus-ring: rgba(54, 226, 255, .45);
  --primary-gradient: linear-gradient(90deg, #ff004d, #ff8c00, #ffe600, #00e676, #00b0ff, #aa00ff);
  --primary-glow: 0 0 18px rgba(255, 127, 224, .45), 0 0 40px rgba(54, 226, 255, .22);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .45);
  --shadow-md: 0 10px 30px rgba(0, 0, 0, .50), 0 2px 6px rgba(0, 0, 0, .35);
  --shadow-lg: 0 28px 80px rgba(0, 0, 0, .65), 0 8px 20px rgba(0, 0, 0, .45);
  --holiday: #ff5c7c;
}

/* Starry deep-space backdrop — same layered-gradient approach as dark mode. */
[data-theme="nyan"] body {
  background:
    radial-gradient(2px 2px at 20% 30%, rgba(255,255,255,.9), transparent 60%),
    radial-gradient(2px 2px at 70% 20%, rgba(255,255,255,.7), transparent 60%),
    radial-gradient(1.5px 1.5px at 40% 70%, rgba(255,255,255,.8), transparent 60%),
    radial-gradient(2px 2px at 85% 65%, rgba(255,255,255,.7), transparent 60%),
    radial-gradient(1.5px 1.5px at 55% 45%, rgba(255,255,255,.6), transparent 60%),
    radial-gradient(2px 2px at 10% 80%, rgba(255,255,255,.7), transparent 60%),
    radial-gradient(1200px 700px at 110% -10%, rgba(170, 0, 255, .18), transparent 60%),
    radial-gradient(900px 600px at -10% 110%, rgba(54, 226, 255, .12), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}

/* Flying nyan cat overlay */
.nyan-cat { display: none; }
[data-theme="nyan"] .nyan-cat {
  display: block;
  position: fixed;
  top: 18%;
  left: 0;
  z-index: 60;
  pointer-events: none;
  will-change: transform;
  /* One pass only — fly across once, then hold off-screen (no loop). */
  animation: nyan-fly 9s linear 1 forwards;
}
[data-theme="nyan"] .nyan-body {
  position: relative;
  z-index: 1;
  animation: nyan-bob .35s steps(2, end) infinite;
  filter: drop-shadow(0 0 10px rgba(255, 127, 224, .6));
}
/* Rainbow trail streaming out behind the cat. */
[data-theme="nyan"] .nyan-trail {
  position: absolute;
  top: 22px;
  right: 78px;            /* tucks under the pop-tart body */
  width: 60vw;
  height: 34px;
  background: repeating-linear-gradient(
    to bottom,
    #ff004d 0, #ff004d 5px,
    #ff8c00 5px, #ff8c00 10px,
    #ffe600 10px, #ffe600 16px,
    #00e676 16px, #00e676 22px,
    #00b0ff 22px, #00b0ff 28px,
    #aa00ff 28px, #aa00ff 34px
  );
  border-radius: 3px;
  animation: nyan-trail-wave .3s steps(2, end) infinite;
}
@keyframes nyan-fly {
  from { transform: translateX(-60vw); }
  to   { transform: translateX(160vw); }
}
@keyframes nyan-bob {
  from { transform: translateY(0); }
  to   { transform: translateY(4px); }
}
@keyframes nyan-trail-wave {
  from { clip-path: polygon(0 6%, 100% 0, 100% 100%, 0 94%); }
  to   { clip-path: polygon(0 0, 100% 6%, 100% 94%, 0 100%); }
}
@media (prefers-reduced-motion: reduce) {
  [data-theme="nyan"] .nyan-cat { animation: none; left: 8px; top: 12%; }
  [data-theme="nyan"] .nyan-body,
  [data-theme="nyan"] .nyan-trail { animation: none; }
  [data-theme="nyan"] .nyan-trail { width: 180px; }
}

/* data-theme lives on .app, so paint the starfield on the .app element itself
   (the body-scoped rule above can't match a body nested under .app). */
.app[data-theme="nyan"] {
  background:
    radial-gradient(2px 2px at 20% 30%, rgba(255,255,255,.9), transparent 60%),
    radial-gradient(2px 2px at 70% 18%, rgba(255,255,255,.7), transparent 60%),
    radial-gradient(1.5px 1.5px at 40% 72%, rgba(255,255,255,.8), transparent 60%),
    radial-gradient(2px 2px at 85% 60%, rgba(255,255,255,.7), transparent 60%),
    radial-gradient(1.5px 1.5px at 55% 45%, rgba(255,255,255,.6), transparent 60%),
    radial-gradient(2px 2px at 12% 82%, rgba(255,255,255,.7), transparent 60%),
    radial-gradient(1.5px 1.5px at 90% 35%, rgba(255,255,255,.6), transparent 60%),
    radial-gradient(1300px 760px at 110% -10%, rgba(170, 0, 255, .20), transparent 60%),
    radial-gradient(1000px 640px at -10% 110%, rgba(54, 226, 255, .14), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}

/* ============================ Insights dashboard (moonshot B2) ============== */
.insights-view .app-view-head {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 20px; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--bg); z-index: 5;
}
.insights-view .app-view-title { font-size: 20px; font-weight: 750; margin: 0; }
.insights-body { padding: 20px; }
.ins-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 980px; margin: 0 auto;
}
.ins-span2 { grid-column: 1 / -1; }
.ins-card { padding: 18px; }

/* Heatmap */
.ins-heat-wds, .ins-heat-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.ins-heat-wd { text-align: center; font-size: 11px; color: var(--text-mute); font-weight: 700; padding-bottom: 4px; }
.ins-heat-grid { margin-top: 2px; }
.ins-heat-cell {
  aspect-ratio: 1; border-radius: 8px; background: var(--bg-soft);
  display: flex; align-items: flex-start; justify-content: flex-end;
  padding: 4px 5px; font-size: 11px; color: var(--text-mute);
  border: 1px solid transparent;
}
.ins-heat-cell.empty { background: transparent; }
.ins-heat-cell.load-0 { background: var(--bg-soft); }
.ins-heat-cell.load-1 { background: color-mix(in srgb, var(--primary) 22%, var(--bg-elev)); color: var(--text-soft); }
.ins-heat-cell.load-2 { background: color-mix(in srgb, var(--primary) 50%, var(--bg-elev)); color: var(--on-primary); }
.ins-heat-cell.load-3 { background: var(--primary); color: var(--on-primary); }
.ins-heat-cell.load-c { background: color-mix(in srgb, var(--danger) 65%, var(--bg-elev)); color: #fff; border-color: var(--danger); }
.ins-heat-cell.today { outline: 2px solid var(--today-ring); outline-offset: 1px; }
.ins-legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px; font-size: 12px; color: var(--text-mute); }
.ins-legend-item { display: inline-flex; align-items: center; gap: 5px; }
.ins-sw { width: 14px; height: 14px; border-radius: 4px; display: inline-block; }

/* Stat tiles */
.ins-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.ins-stat { background: var(--bg-soft); border-radius: var(--radius-sm); padding: 12px; text-align: center; }
.ins-stat b { display: block; font-size: 26px; font-weight: 800; line-height: 1; }
.ins-stat span { font-size: 12px; color: var(--text-mute); }
.ins-stat.warn b { color: var(--danger); }
.ins-foot { margin: 12px 0 0; font-size: 13px; color: var(--text-soft); }

/* Bars (mood + people) */
.ins-bars { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.ins-bar-row { display: flex; align-items: center; gap: 10px; }
.ins-bar-lbl { width: 22px; text-align: center; flex: none; }
.ins-bar-name { width: auto; min-width: 70px; text-align: left; font-size: 13px; font-weight: 650; }
.ins-bar-track { flex: 1; height: 10px; background: var(--bg-soft); border-radius: 999px; overflow: hidden; }
.ins-bar-fill { display: block; height: 100%; background: var(--primary); border-radius: 999px; min-width: 2px; }
.ins-bar-val { width: 28px; text-align: right; font-size: 13px; color: var(--text-soft); font-variant-numeric: tabular-nums; }

/* Mood sparkline */
.ins-spark { display: block; margin: 4px 0 6px; }
.ins-spark-empty { font-size: 12px; color: var(--text-mute); padding: 8px 0; }

/* Rings */
.ins-rings { display: flex; flex-direction: column; gap: 14px; }
.ins-ring-row { display: flex; align-items: center; gap: 14px; }
.ins-ring { position: relative; display: grid; place-items: center; flex: none; }
.ins-ring-label { position: absolute; font-size: 13px; font-weight: 750; }
.ins-ring-cap { font-size: 14px; font-weight: 650; display: flex; flex-direction: column; }
.ins-ring-cap small { color: var(--text-mute); font-weight: 500; font-size: 12px; }

/* Upcoming list */
.ins-up { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ins-up li { display: flex; gap: 10px; align-items: baseline; font-size: 14px; }
.ins-up-date { color: var(--text-mute); font-size: 12px; flex: none; min-width: 64px; }
.ins-up-title { font-weight: 600; }
.ins-empty { color: var(--text-mute); }

@media (max-width: 720px) {
  .ins-grid { grid-template-columns: 1fr; }
  .ins-span2 { grid-column: auto; }
}
/* Legend swatches reuse the heat tier colors */
.ins-sw.load-0 { background: var(--bg-soft); border: 1px solid var(--line); }
.ins-sw.load-1 { background: color-mix(in srgb, var(--primary) 22%, var(--bg-elev)); }
.ins-sw.load-2 { background: color-mix(in srgb, var(--primary) 50%, var(--bg-elev)); }
.ins-sw.load-3 { background: var(--primary); }
.ins-sw.load-c { background: color-mix(in srgb, var(--danger) 65%, var(--bg-elev)); }
/* Insights month nav + interactive heatmap cells */
.ins-monthnav { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.ins-monthnav #insightsMonthLabel { font-weight: 650; min-width: 128px; text-align: center; font-variant-numeric: tabular-nums; }
.ins-heat-cell[role="button"] { cursor: pointer; transition: transform .08s ease, box-shadow .08s ease; }
.ins-heat-cell[role="button"]:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.ins-heat-cell[role="button"]:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* ============================ Ambient dashboard (moonshot B3) =============== */
.ambient { position: fixed; inset: 0; z-index: 1000; overflow: hidden; background: #05060c; color: #f4f6ff; }
body.amb-open { overflow: hidden; }
.amb-bg { position: absolute; inset: 0; opacity: 0; transition: opacity 1.6s ease; }
.amb-bg.is-active { opacity: 1; }
/* Full-screen background visualizer canvas (behind the text). */
.amb-viz { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; display: block; }
.amb-viz[hidden] { display: none; }
.ambient.amb-viz-on .amb-bg { display: none; }   /* viz replaces the photo bg */
/* Background-style picker */
.amb-bgbtn {
  position: absolute; top: 18px; right: 74px; z-index: 4;
  width: 44px; height: 44px; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.10); color: #fff; cursor: pointer;
  display: grid; place-items: center; opacity: .85;
}
.amb-bgbtn:hover { opacity: 1; background: rgba(255,255,255,.2); }
.amb-bg-menu {
  position: absolute; top: 70px; right: 20px; z-index: 5;
  display: flex; flex-direction: column; gap: 2px; padding: 6px;
  background: rgba(10,12,20,.92); border: 1px solid rgba(255,255,255,.12);
  border-radius: 12px; backdrop-filter: blur(8px); min-width: 150px;
}
.amb-bg-menu[hidden] { display: none; }
.amb-bg-opt {
  text-align: left; border: 0; background: transparent; color: #f4f6ff;
  font-size: 14px; padding: 8px 12px; border-radius: 8px; cursor: pointer;
}
.amb-bg-opt:hover { background: rgba(255,255,255,.12); }
.amb-bg-opt.active { background: color-mix(in srgb, var(--accent, #e0457b) 30%, transparent); font-weight: 650; }
/* Frame-TV fill: a blurred cover layer fills the page edge-to-edge while the
   whole photo shows sharp + uncropped (contain) on top. */
.amb-bg-blur, .amb-bg-photo {
  position: absolute; inset: 0; background-position: center; background-repeat: no-repeat;
}
.amb-bg-blur { background-size: cover; filter: blur(34px) brightness(0.5); transform: scale(1.12); }
.amb-bg-photo { background-size: contain; }
.amb-scrim {
  position: absolute; inset: 0;
  background: radial-gradient(1200px 800px at 20% 10%, rgba(5,6,12,.45), transparent 60%),
              linear-gradient(180deg, rgba(5,6,12,.55) 0%, rgba(5,6,12,.78) 100%);
}
.amb-close {
  position: absolute; top: 18px; right: 20px; z-index: 3;
  width: 44px; height: 44px; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.10); color: #fff; font-size: 26px; line-height: 1; cursor: pointer;
  opacity: .35; transition: opacity .2s ease;
}
.amb-close:hover { opacity: 1; background: rgba(255,255,255,.2); }
/* Voice button + spoken-reply caption on the ambient overlay */
.amb-voice {
  position: absolute; right: calc(20px + env(safe-area-inset-right, 0px));
  bottom: calc(22px + env(safe-area-inset-bottom, 0px)); z-index: 3;
  width: 60px; height: 60px; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.12); color: #fff; cursor: pointer;
  display: grid; place-items: center; transition: transform .12s ease, background .15s ease;
  touch-action: none; -webkit-user-select: none; user-select: none;
}
.amb-voice:hover { background: rgba(255,255,255,.2); }
.amb-voice.held { transform: scale(1.1); background: #e0457b; box-shadow: 0 0 0 0 rgba(224,69,123,.6); animation: ambVoicePulse 1.2s ease-out infinite; }
@keyframes ambVoicePulse { to { box-shadow: 0 0 0 22px rgba(224,69,123,0); } }
.amb-voice-reply {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(96px + env(safe-area-inset-bottom, 0px)); z-index: 3;
  max-width: min(640px, 86vw); padding: 12px 18px; border-radius: 16px;
  background: rgba(0,0,0,.55); color: #fff; font-size: clamp(15px, 2.2vw, 20px);
  line-height: 1.4; text-align: center; backdrop-filter: blur(8px);
}
.amb-voice-reply[hidden] { display: none; }
.ss-voice.held { background: #e0457b; color: #fff; }
.ss-voice-reply {
  position: absolute; left: 50%; transform: translateX(-50%); bottom: 92px; z-index: 3;
  max-width: min(640px, 86vw); padding: 12px 18px; border-radius: 16px;
  background: rgba(0,0,0,.6); color: #fff; font-size: clamp(15px, 2.2vw, 20px);
  line-height: 1.4; text-align: center; backdrop-filter: blur(8px);
}
.ss-voice-reply[hidden] { display: none; }
.amb-content {
  position: relative; z-index: 2; height: 100%; box-sizing: border-box;
  padding: clamp(24px, 5vw, 72px); display: flex; flex-direction: column; gap: clamp(20px, 3vh, 40px);
  max-width: 1400px; margin: 0 auto;
}
.amb-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.amb-time { font-size: clamp(72px, 16vw, 220px); font-weight: 800; line-height: .9; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.amb-headside { text-align: right; }
.amb-date { font-size: clamp(20px, 3.5vw, 40px); font-weight: 600; color: #cdd5f5; }
.amb-weather { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 8px; }
.amb-wx-icon { font-size: clamp(28px, 5vw, 56px); }
.amb-wx-temp { font-size: clamp(24px, 4vw, 48px); font-weight: 700; }
.amb-wx-temp small { font-size: .55em; color: #aab2da; margin-left: 6px; font-weight: 600; }

.amb-now {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.12);
  border-radius: 20px; padding: 18px 24px; backdrop-filter: blur(8px);
}
.amb-now-k { font-size: clamp(12px, 1.4vw, 15px); text-transform: uppercase; letter-spacing: .12em; color: #9fb0ff; font-weight: 800; }
.amb-now-t { font-size: clamp(22px, 3.4vw, 40px); font-weight: 800; font-variant-numeric: tabular-nums; }
.amb-now-title { font-size: clamp(20px, 3vw, 34px); font-weight: 600; }

.amb-cols { display: grid; grid-template-columns: 1.6fr 1fr; gap: clamp(16px, 2.5vw, 32px); flex: 1; min-height: 0; }
.amb-card {
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.1);
  border-radius: 22px; padding: clamp(18px, 2.5vw, 30px); overflow: auto; backdrop-filter: blur(8px);
}
.amb-card-title { margin: 0 0 14px; font-size: clamp(14px, 1.8vw, 19px); text-transform: uppercase; letter-spacing: .12em; color: #9fb0ff; font-weight: 800; }
.amb-ev {
  display: flex; align-items: center; gap: 14px; padding: 12px 4px;
  border-bottom: 1px solid rgba(255,255,255,.08); font-size: clamp(18px, 2.4vw, 28px);
}
.amb-ev:last-child { border-bottom: 0; }
.amb-ev-time { color: #aab2da; font-weight: 700; min-width: 4.5em; font-variant-numeric: tabular-nums; font-size: .9em; }
.amb-ev.allday .amb-ev-time { font-size: .7em; }
.amb-ev-title { font-weight: 600; }
.amb-ev.done { opacity: .45; }
.amb-ev.done .amb-ev-title { text-decoration: line-through; }
.amb-ev.is-now { background: rgba(120,140,255,.18); border-radius: 12px; padding-inline: 12px; border-bottom-color: transparent; }
.amb-dot { width: 12px; height: 12px; border-radius: 50%; flex: none; }
.amb-meal { display: flex; gap: 12px; padding: 10px 0; font-size: clamp(17px, 2.2vw, 26px); align-items: baseline; }
.amb-meal-k { color: #9fb0ff; font-weight: 800; min-width: 5em; font-size: .8em; text-transform: uppercase; letter-spacing: .06em; }
.amb-meal-note { color: #cdd5f5; font-style: italic; }
.amb-empty { color: #8b93bd; font-size: clamp(16px, 2vw, 22px); padding: 8px 0; }

@media (max-width: 760px) {
  .amb-cols { grid-template-columns: 1fr; }
  .amb-head { align-items: center; }
  .amb-headside { text-align: center; }
  .amb-weather { justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  .amb-bg { transition: none; transform: none; }
}

/* ============================ Theme platform (moonshot B5) ================== */
/* New full themes (peers of light/dark/nyan). Each sets the same variable
   surface as the dark block so every component re-skins cleanly. */
[data-theme="midnight"] {
  color-scheme: dark;
  --bg: #000206; --bg-elev: #0a0e16; --bg-soft: #070b12; --bg-hover: #141a26;
  --line: #1a2230; --line-strong: #2a3547;
  --text: #e9eefc; --text-soft: #aeb9d4; --text-mute: #6b7793;
  --primary: #4dd0ff; --primary-hover: #74dbff; --primary-soft: #0a2733; --primary-tint: rgba(77,208,255,.14);
  --primary-fill: #0ea5d4; --on-primary: #001016;
  --accent: #7c9cff; --accent-soft: #16203f;
  --success: #34d399; --warn: #fbbf24; --danger: #fb7185; --danger-soft: #3a1a24; --coral: #fda4af;
  --indigo-soft: #4f46e5;
  --today-ring: #4dd0ff; --selected-ring: #4dd0ff; --focus-ring: rgba(77,208,255,.4);
  --primary-gradient: linear-gradient(135deg, #4dd0ff 0%, #7c9cff 100%);
  --primary-glow: 0 0 20px rgba(77,208,255,.25);
  --shadow-sm: 0 1px 2px rgba(0,0,0,.6);
  --shadow-md: 0 10px 30px rgba(0,0,0,.6), 0 2px 6px rgba(0,0,0,.4);
  --shadow-lg: 0 28px 80px rgba(0,0,0,.75), 0 8px 20px rgba(0,0,0,.5);
  --holiday: #fb7185;
}
[data-theme="midnight"] body {
  background: radial-gradient(1000px 600px at 110% -10%, rgba(77,208,255,.08), transparent 60%), var(--bg);
  background-attachment: fixed;
}
[data-theme="sunset"] {
  color-scheme: light;
  --bg: #fff6f0; --bg-elev: #fffdfb; --bg-soft: #ffeee3; --bg-hover: #ffe3d3;
  --line: #f3d9c8; --line-strong: #e7bfa6;
  --text: #3a2417; --text-soft: #6b4a37; --text-mute: #9c7a64;
  --primary: #e8603c; --primary-hover: #d44e2b; --primary-soft: #ffe0d3; --primary-tint: rgba(232,96,60,.10);
  --primary-fill: #d44e2b; --on-primary: #ffffff;
  --accent: #f0a73c; --accent-soft: #ffeccf;
  --success: #15a36b; --warn: #d97706; --danger: #dc2626; --danger-soft: #fde8e8; --coral: #e85a72;
  --today-ring: #e8603c; --selected-ring: #e8603c; --focus-ring: rgba(232,96,60,.35);
  --primary-gradient: linear-gradient(135deg, #e8603c 0%, #f0a73c 100%);
  --primary-glow: 0 8px 24px rgba(232,96,60,.22), 0 2px 6px rgba(232,96,60,.12);
  --holiday: #b91c1c;
}
[data-theme="sunset"] body {
  background: radial-gradient(1100px 600px at 110% -10%, rgba(240,167,60,.16), transparent 60%),
              radial-gradient(900px 500px at -10% 110%, rgba(232,96,60,.10), transparent 60%), var(--bg);
  background-attachment: fixed;
}
[data-theme="forest"] {
  color-scheme: light;
  --bg: #f1f6f1; --bg-elev: #ffffff; --bg-soft: #e6efe6; --bg-hover: #dbe8db;
  --line: #d2e0d2; --line-strong: #b3c9b3;
  --text: #1c2a1e; --text-soft: #3f5142; --text-mute: #6d806f;
  --primary: #2f8f5b; --primary-hover: #277a4d; --primary-soft: #d9efe1; --primary-tint: rgba(47,143,91,.10);
  --primary-fill: #277a4d; --on-primary: #ffffff;
  --accent: #5bbf8a; --accent-soft: #dcefe3;
  --success: #15a36b; --warn: #d97706; --danger: #dc2626; --danger-soft: #fde8e8; --coral: #e07a5f;
  --today-ring: #2f8f5b; --selected-ring: #2f8f5b; --focus-ring: rgba(47,143,91,.32);
  --primary-gradient: linear-gradient(135deg, #2f8f5b 0%, #5bbf8a 100%);
  --primary-glow: 0 8px 24px rgba(47,143,91,.2), 0 2px 6px rgba(47,143,91,.1);
  --holiday: #b91c1c;
}
[data-theme="forest"] body {
  background: radial-gradient(1000px 600px at 110% -10%, rgba(91,191,138,.14), transparent 60%), var(--bg);
  background-attachment: fixed;
}

/* Theme gallery — live-preview cards (each .tc-prev carries its own
   data-theme so its swatch renders in that theme's real variables). */
.theme-gallery {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 12px;
}
.theme-card {
  display: flex; flex-direction: column; gap: 8px; padding: 8px;
  border: 2px solid var(--line); border-radius: 16px; background: var(--bg-elev);
  cursor: pointer; text-align: center; transition: border-color .15s ease, transform .08s ease, box-shadow .15s ease;
}
.theme-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.theme-card.active { border-color: var(--primary); box-shadow: var(--primary-glow); }
.theme-card:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.tc-prev {
  display: block; border-radius: 10px; overflow: hidden;
  border: 1px solid var(--line); background: var(--bg); height: 62px;
}
.tc-bar { display: block; height: 20px; background: var(--primary-gradient); }
.tc-body { display: flex; align-items: center; gap: 7px; padding: 9px 10px; }
.tc-pill { width: 36px; height: 11px; border-radius: 999px; background: var(--primary); }
.tc-dot { width: 11px; height: 11px; border-radius: 50%; background: var(--accent); }
.tc-name { font-size: 13px; font-weight: 650; }

/* ============================ Touch time picker (moonshot B4) =============== */
.ee-time-input { display: flex; align-items: center; gap: 6px; }
.ee-time-input input[type="time"] { flex: 1; min-width: 0; }
.ee-time-btn {
  flex: none; width: 36px; height: 36px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--bg-soft); color: var(--text-soft);
  display: grid; place-items: center; cursor: pointer;
}
.ee-time-btn:hover { background: var(--bg-hover); color: var(--text); }
.ee-time-btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

.timepicker {
  position: fixed; z-index: 1200; width: 288px; max-width: calc(100vw - 16px);
  background: var(--bg-elev); border: 1px solid var(--line-strong);
  border-radius: 16px; box-shadow: var(--shadow-lg); padding: 14px;
}
.tp-head { text-align: center; margin-bottom: 10px; }
.tp-preview { font-size: 28px; font-weight: 800; font-variant-numeric: tabular-nums; }
.tp-section { margin-bottom: 10px; }
.tp-section-label { font-size: 11px; text-transform: uppercase; letter-spacing: .1em; color: var(--text-mute); font-weight: 700; margin-bottom: 6px; }
.tp-grid { display: grid; gap: 6px; grid-template-columns: repeat(6, 1fr); }
.tp-cell {
  padding: 10px 0; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-soft); color: var(--text); font-weight: 650; font-size: 14px;
  cursor: pointer; font-variant-numeric: tabular-nums;
}
.tp-cell:hover { background: var(--bg-hover); }
.tp-cell.sel { background: var(--primary-fill); color: var(--on-primary); border-color: transparent; }
.tp-foot { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.tp-ap { display: inline-flex; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.tp-ap-btn { padding: 8px 12px; border: 0; background: var(--bg-soft); color: var(--text-soft); font-weight: 700; cursor: pointer; }
.tp-ap-btn.sel { background: var(--primary-fill); color: var(--on-primary); }
.tp-now, .tp-clear { padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-soft); color: var(--text-soft); font-weight: 650; cursor: pointer; font-size: 13px; }
.tp-done { margin-left: auto; padding: 8px 16px; }

/* ============================ Realtime presence (moonshot B6) =============== */
.presence { display: inline-flex; align-items: center; gap: -6px; }
.presence-dot {
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  color: #fff; font-size: 11px; font-weight: 800; border: 2px solid var(--bg);
  margin-left: -6px; box-shadow: var(--shadow-sm);
}
.presence-dot:first-child { margin-left: 0; }
.presence-more { margin-left: 4px; font-size: 12px; color: var(--text-mute); font-weight: 700; }

/* ============================ Automations UI (moonshot A2) ================== */
.auto-form { display: flex; flex-direction: column; gap: 12px; }
.auto-form .ee-field { display: flex; flex-direction: column; gap: 4px; }
.auto-form .ee-label { font-size: 12px; color: var(--text-mute); font-weight: 600; }
.auto-form input[type="text"], .auto-form input[type="number"], .auto-form input[type="time"], .auto-form select {
  padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-soft); color: var(--text); font: inherit;
}
.auto-cadence { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.auto-cadence .ee-field { flex: 1; min-width: 120px; }
.auto-weekdays { display: flex; gap: 6px; flex-wrap: wrap; }
.auto-wd { display: inline-flex; }
.auto-wd input { position: absolute; opacity: 0; pointer-events: none; }
.auto-wd span {
  display: inline-grid; place-items: center; min-width: 42px; padding: 7px 0;
  border: 1px solid var(--line); border-radius: 999px; background: var(--bg-soft);
  color: var(--text-soft); font-size: 13px; font-weight: 650; cursor: pointer;
}
.auto-wd input:checked + span { background: var(--primary-fill); color: var(--on-primary); border-color: transparent; }
.auto-preview { margin: 0; font-size: 13px; color: var(--text-soft); min-height: 1.2em; }
.auto-form-foot { display: flex; align-items: center; gap: 12px; }
.auto-status { font-size: 13px; color: var(--text-mute); }

.auto-list { display: flex; flex-direction: column; gap: 8px; }
.auto-item { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 12px; }
.auto-item-main { flex: 1; min-width: 0; }
.auto-item-title { font-weight: 700; }
.auto-item-sub { font-size: 13px; color: var(--text-mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.auto-item-del { flex: none; }
.auto-empty { color: var(--text-mute); font-size: 14px; padding: 6px 0; }

/* External (synced) calendars — Settings → Data */
.ext-cal { display: flex; flex-direction: column; gap: 12px; }
.ext-cal-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ext-cal-item { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 12px; }
.ext-cal-main { flex: 1; min-width: 0; }
.ext-cal-label { font-weight: 700; }
.ext-cal-meta { font-size: 13px; color: var(--text-mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ext-cal-meta.err { color: var(--danger, #d9534f); }
.ext-cal-actions { flex: none; display: flex; gap: 12px; align-items: center; }
.ext-cal-empty { color: var(--text-mute); font-size: 14px; padding: 2px 0; }
.ext-cal-add { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.ext-cal-add input { flex: 1; min-width: 180px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-soft); color: var(--text); font: inherit; }
.ext-cal-add input#extCalLabel { flex: 0 0 160px; min-width: 120px; }

/* Wellbeing card (moonshot A6) */
.ins-wb { display: flex; flex-direction: column; gap: 8px; }
.ins-wb-item {
  padding: 10px 12px; background: var(--bg-soft); border: 1px solid var(--line);
  border-left: 3px solid var(--primary); border-radius: 10px; font-size: 14px;
}

/* Proactive suggestions card (moonshot A1) */
.ins-sug { display: flex; flex-direction: column; gap: 8px; }
.ins-sug-item {
  padding: 10px 12px; border-radius: 10px; font-size: 14px; font-weight: 550;
  background: var(--bg-soft); border: 1px solid var(--line); border-left: 3px solid var(--accent);
}
.ins-sug-item.warn { border-left-color: var(--danger); }
.ins-sug-item.info { border-left-color: var(--primary); }

/* Inline text button (calendar subscribe regenerate) */
.link-btn { background: none; border: 0; padding: 0; color: var(--primary); font: inherit; cursor: pointer; text-decoration: underline; }

/* Household points leaderboard (moonshot A5) */
.ins-points { display: flex; flex-direction: column; gap: 8px; }
.ins-pts-row { display: flex; align-items: center; gap: 10px; }
.ins-pts-rank { width: 28px; text-align: center; font-size: 15px; }
.ins-pts-name { min-width: 70px; font-weight: 650; font-size: 14px; }
.ins-pts-val { width: 44px; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }

.ins-achievements { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.ins-mvp { font-size: 14px; }
.ins-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.ins-badge { font-size: 12px; padding: 3px 8px; border-radius: 999px; background: var(--bg-soft); color: var(--text); white-space: nowrap; }

.ins-rewards { display: flex; flex-direction: column; gap: 8px; }
.ins-reward-mine { font-size: 13px; color: var(--text-mute); margin-bottom: 2px; }
.ins-reward-row { display: flex; align-items: center; gap: 10px; }
.ins-reward-row.pending { opacity: .95; }
.ins-reward-title { flex: 1; font-weight: 600; font-size: 14px; }
.ins-reward-cost { font-variant-numeric: tabular-nums; color: var(--text-mute); font-size: 13px; white-space: nowrap; }
.ins-reward-add { display: flex; gap: 8px; margin-top: 6px; }
.ins-reward-add input[type="text"] { flex: 1; }
.ins-reward-add input[type="number"] { width: 72px; }
.ins-reward-queue { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.ins-reward-queue-head { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-mute); }

/* ============================================================
   Time capsules — sealed messages to the future. The composer
   (#capsuleModal) and list (#capsulesModal) are centered modals
   on desktop and full-screen pages on mobile (data-page-name).
   ============================================================ */

/* Composer */
.capsule-modal { width: min(560px, calc(100vw - 32px)); }
.capsule-form { display: flex; flex-direction: column; gap: 12px; }
.capsule-field { display: flex; flex-direction: column; gap: 6px; }
.capsule-label { font-size: 12px; font-weight: 600; color: var(--text-soft); text-transform: uppercase; letter-spacing: .04em; }
.capsule-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md, 10px);
  background: var(--bg);
  color: var(--text);
  font: inherit;
}
.capsule-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
.capsule-message { resize: vertical; min-height: 120px; line-height: 1.5; }
.capsule-quick { display: flex; flex-wrap: wrap; gap: 8px; }
.capsule-chip {
  padding: 7px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-elev);
  color: var(--text-soft);
  font-size: 13px; font-weight: 600;
  cursor: pointer;
}
.capsule-chip:hover { border-color: var(--accent); color: var(--text); }
.capsule-actions { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 4px; }
.capsule-status { flex: 1; font-size: 13px; color: var(--text-soft); }

/* List */
.capsules-new-btn { margin-left: auto; }
.capsules-section { margin-bottom: 18px; }
.capsules-section-title { margin: 0 0 10px; font-size: 13px; font-weight: 700; color: var(--text); }
.capsules-section-hint { font-weight: 500; color: var(--text-soft); }
.capsules-list { display: flex; flex-direction: column; gap: 10px; }
.capsules-empty { text-align: center; padding: 32px 16px; color: var(--text-soft); }
.capsules-empty p { margin: 0 0 6px; }
.capsules-empty-sub { font-size: 14px; line-height: 1.5; margin-bottom: 16px !important; }

.capsule-card {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg, 14px);
  background: var(--bg-elev);
}
.capsule-card.is-locked { border-style: dashed; opacity: .92; }
.capsule-card.is-open { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); background: color-mix(in srgb, var(--accent) 7%, var(--bg-elev)); }
.capsule-card-icon { font-size: 22px; line-height: 1; flex-shrink: 0; }
.capsule-card-body { flex: 1; min-width: 0; }
.capsule-card-title { font-weight: 700; font-size: 15px; color: var(--text); }
.capsule-card-meta { font-size: 12.5px; color: var(--text-soft); margin-top: 2px; }
.capsule-card-msg { margin-top: 8px; font-size: 14px; line-height: 1.5; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.capsule-del { flex-shrink: 0; width: 32px; height: 32px; color: var(--text-soft); }
.capsule-del:hover { color: var(--danger, #e5484d); }

/* Day-view "a capsule opened today" moment */
.day-capsules { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; }
.day-capsule {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--line));
  border-radius: var(--radius-lg, 14px);
  background: linear-gradient(120deg, color-mix(in srgb, var(--accent) 12%, var(--bg-elev)), var(--bg-elev));
  color: var(--text);
  text-align: left;
  cursor: pointer;
  animation: capsulePop .3s ease;
}
.day-capsule:hover { border-color: var(--accent); }
@keyframes capsulePop { from { transform: translateY(6px); opacity: 0; } to { transform: none; opacity: 1; } }
.day-capsule-icon { font-size: 22px; line-height: 1; flex-shrink: 0; }
.day-capsule-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.day-capsule-title { font-weight: 700; font-size: 14px; }
.day-capsule-sub { font-size: 12.5px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.day-capsule-cta {
  flex-shrink: 0; font-size: 12px; font-weight: 700; color: var(--accent);
  padding: 5px 12px; border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line)); border-radius: 999px;
}

/* ============================================================
   Chronicle — the family's auto-written monthly memoir. A shelf
   of month-chapters (#chronicleShelf) and a reader (#chronicleReader),
   both inside #chronicleModal (full page on mobile).
   ============================================================ */
.chronicle-modal { width: min(680px, calc(100vw - 32px)); }
.chronicle-write-btn { margin-left: auto; }
.chronicle-lead { color: var(--text-soft); margin: 0 0 12px; line-height: 1.5; }
.chronicle-status { font-size: 13px; color: var(--accent); min-height: 0; margin-bottom: 8px; }
.chronicle-status:empty { display: none; }
.chronicle-empty { text-align: center; padding: 28px 16px; color: var(--text-soft); }

.chronicle-list { display: flex; flex-direction: column; gap: 12px; }
.chronicle-card {
  display: flex; align-items: stretch; gap: 12px;
  padding: 12px; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius-lg, 14px);
  background: var(--bg-elev); color: var(--text);
}
.chronicle-card:hover { border-color: var(--accent); }
.chronicle-card-cover {
  flex-shrink: 0; width: 64px; height: 64px; border-radius: 10px;
  object-fit: cover; background: var(--bg);
}
.chronicle-card-cover-blank { display: grid; place-items: center; font-size: 26px; }
.chronicle-card-text { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.chronicle-card-month { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--accent); }
.chronicle-card-title { font-weight: 700; font-size: 15px; color: var(--text); }
.chronicle-card-excerpt {
  font-size: 13px; color: var(--text-soft); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Reader */
.chronicle-reader { max-width: 640px; margin: 0 auto; }
.chronicle-back { display: inline-flex; margin-bottom: 10px; }
.chronicle-cover {
  width: 100%; max-height: 280px; object-fit: cover;
  border-radius: var(--radius-lg, 14px); margin-bottom: 16px;
}
.chronicle-reader-title { margin: 0 0 4px; font-size: 24px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.2; }
.chronicle-reader-meta { font-size: 13px; color: var(--text-soft); margin-bottom: 18px; }
.chronicle-reader-body { font-size: 16.5px; line-height: 1.7; color: var(--text); }
.chronicle-reader-body p { margin: 0 0 16px; }
.chronicle-reader-body h3 { font-size: 18px; margin: 22px 0 8px; }
.chronicle-reader-body h4 { font-size: 15px; margin: 18px 0 6px; color: var(--text-soft); }
.chronicle-reader-body :first-child::first-letter {
  font-size: 3.1em; font-weight: 800; float: left;
  line-height: .82; padding: 4px 10px 0 0; color: var(--accent);
}
.chronicle-reader-actions { margin-top: 24px; padding-top: 14px; border-top: 1px solid var(--line); }

/* ============================================================
   23. Baby — infant care tracker scene
   A full-page scene (body[data-scene="baby"]) like Settings/Dev.
   Reuses .app-view chrome; adds a centered content column, a
   glanceable today-dashboard, a quick-log row, and a timeline.
   ============================================================ */
.baby-shell {
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 0 4px 40px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* ---- profile header + switcher ---- */
.baby-header { display: flex; flex-direction: column; gap: 12px; }
.baby-head-title { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; color: var(--text); }
.baby-profile {
  display: flex; align-items: center; gap: 14px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 14px 16px;
  box-shadow: var(--shadow-sm);
}
.baby-avatar {
  flex: none;
  width: 52px; height: 52px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 22px; font-weight: 700;
  color: #fff;
  background: var(--bk, var(--primary-fill));
  box-shadow: 0 2px 8px color-mix(in srgb, var(--bk, var(--primary)) 40%, transparent);
}
.baby-profile-main { flex: 1; min-width: 0; }
.baby-profile-name { font-size: 19px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.baby-profile-sub { font-size: 13px; color: var(--text-soft); margin-top: 2px; }
.baby-edit-btn, .baby-settings-btn { flex: none; width: 38px; height: 38px; color: var(--text-soft); }
.baby-edit-btn:hover, .baby-settings-btn:hover { background: var(--bg-hover); color: var(--text); }

.baby-switch { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.baby-switch-chip {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--line);
  background: var(--bg-elev);
  color: var(--text-soft);
  border-radius: 999px;
  padding: 6px 13px;
  font-size: 13px; font-weight: 600;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.baby-switch-chip:hover { background: var(--bg-hover); color: var(--text); }
.baby-switch-chip.active { background: var(--primary-tint); color: var(--primary); border-color: transparent; }
.baby-switch-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.baby-switch-add { font-size: 16px; line-height: 1; padding: 6px 12px; color: var(--text-soft); }
.baby-add-inline { align-self: flex-start; }

/* ---- empty state ---- */
.baby-empty {
  text-align: center;
  max-width: 420px;
  margin: 40px auto;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.baby-empty-glyph {
  width: 76px; height: 76px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary-tint); color: var(--primary);
  margin-bottom: 4px;
}
.baby-empty h2 { margin: 0; font-size: 20px; font-weight: 700; color: var(--text); }
.baby-empty p { margin: 0; font-size: 14px; color: var(--text-soft); line-height: 1.5; }
.baby-empty .btn { margin-top: 8px; }

/* ---- sections ---- */
.baby-section { display: flex; flex-direction: column; gap: 12px; }
.baby-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.baby-section-title { margin: 0; font-size: 14px; font-weight: 700; color: var(--text-soft); text-transform: uppercase; letter-spacing: 0.04em; }
/* Collapsible tracker sections (Baby / Water / Meds) — tap the title/chevron to
   minimize a section. Scene-agnostic: any <section data-collapse-key> with a
   .section-toggle header button collapses. Heads are named *-section-head. */
.section-toggle { display: inline-flex; align-items: center; gap: 8px; padding: 2px 0; margin: 0; background: none; border: 0; cursor: pointer; color: inherit; text-align: left; -webkit-tap-highlight-color: transparent; }
.section-chevron { flex: none; color: var(--text-soft); transition: transform 0.18s ease; }
.section-toggle:hover [class$="section-title"] { color: var(--text); }
.section-toggle:focus-visible { outline: 2px solid var(--accent, #6366f1); outline-offset: 3px; border-radius: 6px; }
[data-collapse-key].is-collapsed .section-chevron { transform: rotate(-90deg); }
/* Collapsed: hide the body and any right-side head controls, keep the toggle. */
[data-collapse-key].is-collapsed > :not([class*="section-head"]) { display: none; }
[data-collapse-key].is-collapsed [class*="section-head"] > :not(.section-toggle) { display: none; }

/* ---- unit toggles ---- */
.baby-units { display: flex; gap: 8px; flex-wrap: wrap; }
.baby-unit {
  display: inline-flex;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px;
}
.baby-unit-btn {
  border: 0; background: transparent;
  color: var(--text-soft);
  font-size: 12px; font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.baby-unit-btn.active { background: var(--primary-fill); color: var(--on-primary); }

/* ---- today dashboard ---- */
.baby-dash { display: flex; flex-direction: column; gap: 14px; }
.baby-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.baby-card {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px;
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: 3px;
  min-width: 0;
}
.baby-card-label { font-size: 12px; font-weight: 600; color: var(--text-soft); }
.baby-card-value { font-size: 22px; font-weight: 700; color: var(--text); letter-spacing: -0.02em; line-height: 1.15; }
.baby-card-sub { font-size: 12px; color: var(--text-mute); }
.baby-card-feed .baby-card-value { color: #0284c7; }
.baby-card-diaper .baby-card-value { color: #d97706; }
.baby-card-sleep .baby-card-value { color: #7c3aed; }
.baby-card-temp .baby-card-value { color: #e11d48; }
.baby-card-weight .baby-card-value { color: #16a34a; }
:root[data-theme="dark"] .baby-card-feed .baby-card-value { color: #38bdf8; }
:root[data-theme="dark"] .baby-card-diaper .baby-card-value { color: #fbbf24; }
:root[data-theme="dark"] .baby-card-sleep .baby-card-value { color: #a78bfa; }
:root[data-theme="dark"] .baby-card-temp .baby-card-value { color: #fb7185; }
:root[data-theme="dark"] .baby-card-weight .baby-card-value { color: #4ade80; }

/* ---- "since last" hero (the glanceable 3am answer) ---- */
.baby-since-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.baby-since {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 13px 14px;
  box-shadow: var(--shadow-sm);
  min-width: 0;
}
.baby-since-emoji {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 20px; background: var(--bg-soft);
}
.baby-since-main { min-width: 0; }
.baby-since-label { font-size: 12px; font-weight: 600; color: var(--text-soft); }
.baby-since-value {
  font-size: 20px; font-weight: 700; color: var(--text);
  letter-spacing: -0.02em; line-height: 1.2; white-space: nowrap;
}
.baby-since-sub {
  font-size: 11px; color: var(--text-mute);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.baby-since-feed .baby-since-emoji { background: color-mix(in srgb, #0284c7 16%, transparent); }
.baby-since-diaper .baby-since-emoji { background: color-mix(in srgb, #d97706 16%, transparent); }
.baby-since-sleep .baby-since-emoji { background: color-mix(in srgb, #7c3aed 16%, transparent); }
.baby-since-live {
  background: color-mix(in srgb, #7c3aed 12%, var(--bg-elev));
  border-color: color-mix(in srgb, #7c3aed 32%, var(--line));
}
.baby-since-live .baby-since-value { color: #7c3aed; }
:root[data-theme="dark"] .baby-since-live .baby-since-value { color: #a78bfa; }
/* live-feed variant of the hero tile (the generic live tint is sleep purple) */
.baby-since-feed.baby-since-live {
  background: color-mix(in srgb, #0284c7 12%, var(--bg-elev));
  border-color: color-mix(in srgb, #0284c7 32%, var(--line));
}
.baby-since-feed.baby-since-live .baby-since-value { color: #0284c7; }
:root[data-theme="dark"] .baby-since-feed.baby-since-live .baby-since-value { color: #38bdf8; }
.baby-since-end {
  border: 0; background: transparent; padding: 0; cursor: pointer;
  font: inherit; font-size: 11px; font-weight: 700; color: var(--primary);
}
.baby-since-end:hover { text-decoration: underline; }

/* ---- rolling daily averages ---- */
.baby-averages {
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 14px; padding: 12px 14px; box-shadow: var(--shadow-sm);
}
.baby-averages-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: 12px; font-weight: 700; color: var(--text-soft);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 10px;
}
.baby-averages-head span {
  font-size: 11px; font-weight: 600; color: var(--text-mute);
  text-transform: none; letter-spacing: 0;
}
.baby-averages-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(64px, 1fr)); gap: 10px; }
.baby-avg { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.baby-avg-val { font-size: 17px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; white-space: nowrap; }
.baby-avg-label { font-size: 11px; color: var(--text-mute); text-transform: uppercase; letter-spacing: 0.03em; }

/* ---- trends / sparklines ---- */
.baby-trends { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.baby-trend {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 12px 14px;
  box-shadow: var(--shadow-sm);
}
.baby-trend-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: 12px; font-weight: 600; color: var(--text-soft); margin-bottom: 6px;
}
.baby-trend-head span { font-size: 14px; font-weight: 700; color: var(--text); }
.baby-spark { display: block; width: 100%; height: 42px; }

/* ---- Health trends (shared strip: Baby / Water / Meds scenes) ---- */
.trends-win {
  display: inline-flex; gap: 2px;
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px;
}
.trends-win-btn {
  border: 0; background: transparent; border-radius: 999px;
  padding: 4px 10px; font: inherit; font-size: 12px; font-weight: 600;
  color: var(--text-soft); cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.trends-win-btn:hover { background: var(--bg-hover); }
.trends-win-btn.active { background: var(--primary); color: #fff; }
/* Trend window toggle + refresh grouped on the right of the section head. */
.trends-tools { display: inline-flex; align-items: center; gap: 8px; }
.trends-refresh-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0;
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: 999px;
  color: var(--text-soft); cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.trends-refresh-btn:hover { background: var(--bg-hover); color: var(--text); }
.trends-refresh-btn:disabled { cursor: default; opacity: .7; }
.trends-refresh-btn.is-spinning svg { animation: trends-spin .7s linear infinite; }
@keyframes trends-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .trends-refresh-btn.is-spinning svg { animation: none; }
}
.trends-body {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
}
.trends-card {
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 14px; padding: 12px 14px; box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
}
.trends-card-head { display: flex; align-items: flex-start; gap: 8px; }
.trends-arrow { font-size: 15px; font-weight: 800; line-height: 1.3; flex: none; }
.trends-card.is-increasing .trends-arrow { color: #16a34a; }
.trends-card.is-decreasing .trends-arrow { color: #dc2626; }
:root[data-theme="dark"] .trends-card.is-increasing .trends-arrow { color: #4ade80; }
:root[data-theme="dark"] .trends-card.is-decreasing .trends-arrow { color: #f87171; }
.trends-card.is-steady .trends-arrow,
.trends-card.is-insufficient .trends-arrow { color: var(--text-mute); }
.trends-summary {
  font-size: 13px; font-weight: 600; color: var(--text);
  line-height: 1.35; min-width: 0; overflow-wrap: anywhere;
}
.trends-card.is-insufficient .trends-summary { color: var(--text-mute); font-weight: 500; }
.trends-spark { display: block; width: 100%; height: 44px; }
.trends-spark-goal { stroke: var(--text-mute); opacity: .55; }
.trends-spark-empty { font-size: 11px; color: var(--text-mute); }
.trends-empty { font-size: 13px; color: var(--text-mute); padding: 6px 2px; }
@media (max-width: 640px) {
  .trends-body { grid-template-columns: 1fr; }
}

/* ---- quick log ---- */
.baby-quick { display: flex; flex-direction: column; gap: 12px; }
.baby-quick-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; }
.baby-quick-btn {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 6px;
  cursor: pointer;
  transition: transform .1s ease, border-color .12s ease, background .12s ease;
  min-width: 0;
}
.baby-quick-btn:hover { background: var(--bg-hover); border-color: color-mix(in srgb, var(--bk) 45%, var(--line)); }
.baby-quick-btn:active { transform: scale(.96); }
.baby-quick-emoji {
  width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 20px;
  background: color-mix(in srgb, var(--bk) 16%, transparent);
}
.baby-quick-label { font-size: 12px; font-weight: 600; color: var(--text); text-align: center; }

/* ---- one-tap diaper (skip the sheet for the most frequent log) ---- */
.baby-fast { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.baby-fast-label { font-size: 12px; font-weight: 600; color: var(--text-mute); margin-right: 2px; }
.baby-fast-btn {
  display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid var(--line); background: var(--bg-elev);
  color: var(--text); border-radius: 999px;
  padding: 6px 14px; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background .12s ease, border-color .12s ease, transform .1s ease;
}
.baby-fast-btn:hover { background: var(--bg-hover); border-color: color-mix(in srgb, #d97706 40%, var(--line)); }
.baby-fast-btn:active { transform: scale(.96); }

/* ---- quick meds (one-tap medicine presets) ---- */
.baby-quickmeds { --qm: #0d9488; display: flex; flex-wrap: wrap; gap: 8px; }
:root[data-theme="dark"] .baby-quickmeds { --qm: #2dd4bf; }
.baby-med-chip {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid color-mix(in srgb, var(--qm) 32%, var(--line));
  background: color-mix(in srgb, var(--qm) 7%, var(--bg-elev));
  color: var(--text); border-radius: 999px;
  padding: 7px 14px; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background .12s ease, border-color .12s ease, transform .1s ease;
}
.baby-med-chip:hover { background: color-mix(in srgb, var(--qm) 16%, var(--bg-elev)); border-color: color-mix(in srgb, var(--qm) 55%, var(--line)); }
.baby-med-chip:active { transform: scale(.96); }
.baby-med-chip-emoji { font-size: 15px; line-height: 1; }
.baby-med-chip-dose {
  font-size: 11px; font-weight: 700; color: var(--qm);
  background: color-mix(in srgb, var(--qm) 14%, transparent);
  border-radius: 999px; padding: 1px 7px;
}
.baby-med-chip--add {
  color: var(--text-soft);
  background: var(--bg-elev);
  border-style: dashed;
}
.baby-med-chip--add:hover { color: var(--text); }
.baby-med-chip-plus { font-size: 16px; font-weight: 700; line-height: 1; }

/* Saved-medicine shortcut chips at the top of the medicine log form — a
   visible, tappable row set apart from the manual fields below it. */
.baby-med-saved { --qm: #0d9488; padding-bottom: 12px; margin-bottom: 2px; border-bottom: 1px dashed var(--line); }
:root[data-theme="dark"] .baby-med-saved { --qm: #2dd4bf; }
.baby-med-saved-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.baby-med-saved-chip {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 44px;   /* comfortable touch target */
  max-width: 100%;    /* never force horizontal overflow on mobile */
  border: 1px solid color-mix(in srgb, var(--qm) 32%, var(--line));
  background: color-mix(in srgb, var(--qm) 7%, var(--bg-elev));
  color: var(--text); border-radius: 999px;
  padding: 6px 14px; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background .12s ease, border-color .12s ease, transform .1s ease;
}
.baby-med-saved-chip:hover { background: color-mix(in srgb, var(--qm) 16%, var(--bg-elev)); border-color: color-mix(in srgb, var(--qm) 55%, var(--line)); }
.baby-med-saved-chip:active { transform: scale(.96); }
.baby-med-saved-chip.active { border-color: var(--qm); background: color-mix(in srgb, var(--qm) 18%, var(--bg-elev)); }
.baby-med-saved-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.baby-med-saved-dose {
  flex-shrink: 0; font-size: 11px; font-weight: 700; color: var(--qm);
  background: color-mix(in srgb, var(--qm) 14%, transparent);
  border-radius: 999px; padding: 1px 7px;
}

/* ---- quick-meds manager modal ---- */
.baby-med-presets-body { display: flex; flex-direction: column; gap: 14px; }
.baby-med-presets-lead { font-size: 13px; color: var(--text-mute); margin: 0; }
.baby-med-presets-list { display: flex; flex-direction: column; gap: 8px; }
.baby-med-presets-empty { font-size: 13px; color: var(--text-mute); margin: 0; padding: 4px 0; }
.baby-med-preset-row {
  display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--line); background: var(--bg-elev);
  border-radius: 12px; padding: 8px 10px 8px 14px;
}
.baby-med-preset-row.editing { border-color: color-mix(in srgb, #0d9488 45%, var(--line)); }
.baby-med-preset-info { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; min-width: 0; flex: 1; }
.baby-med-preset-name { font-size: 14px; font-weight: 600; color: var(--text); }
.baby-med-preset-dose { font-size: 12px; font-weight: 700; color: #0d9488; }
:root[data-theme="dark"] .baby-med-preset-dose { color: #2dd4bf; }
.baby-med-preset-notes { font-size: 12px; color: var(--text-mute); width: 100%; }
.baby-med-preset-actions { display: inline-flex; gap: 2px; flex-shrink: 0; }
.baby-med-preset-form {
  display: flex; flex-direction: column; gap: 12px;
  border-top: 1px solid var(--line); padding-top: 14px;
}
.baby-med-preset-form-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--text-mute); }
.baby-med-preset-form-foot { display: flex; align-items: center; gap: 8px; }
.baby-med-preset-status { font-size: 12px; color: var(--text-mute); }
.baby-med-presets-foot { display: flex; justify-content: flex-end; border-top: 1px solid var(--line); padding-top: 12px; }

/* ---- one-tap feed / sleep timers (start buttons ↔ running banner) ---- */
.baby-timers { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 18px; }
.baby-timers:empty { display: none; margin: 0; }
.baby-timer--feeding { --tk: #0284c7; }
.baby-timer--sleep { --tk: #7c3aed; }
:root[data-theme="dark"] .baby-timer--feeding { --tk: #38bdf8; }
:root[data-theme="dark"] .baby-timer--sleep { --tk: #a78bfa; }
.baby-timer-startbtn {
  display: flex; align-items: center; gap: 10px; min-width: 0;
  background: var(--bg-elev);
  border: 1px solid color-mix(in srgb, var(--tk) 30%, var(--line));
  border-radius: 14px;
  padding: 12px 14px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  text-align: left;
  transition: transform .1s ease, border-color .12s ease, background .12s ease;
}
.baby-timer-startbtn:hover { background: var(--bg-hover); border-color: color-mix(in srgb, var(--tk) 55%, var(--line)); }
.baby-timer-startbtn:active { transform: scale(.97); }
.baby-timer-emoji {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 20px;
  background: color-mix(in srgb, var(--tk) 16%, transparent);
}
.baby-timer-start-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.baby-timer-start-label { font-size: 14px; font-weight: 700; color: var(--text); white-space: nowrap; }
.baby-timer-start-sub { font-size: 11px; color: var(--text-mute); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.baby-timer-play { flex: none; font-size: 12px; color: var(--tk); }

/* What-kind chooser: swaps in place of the Start-feed button. Every chip is
   the tap that starts the timer; "Just start" leads for 3am usability. */
.baby-timer-pick {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-elev);
  border: 1px solid color-mix(in srgb, var(--tk) 42%, var(--line));
  border-radius: 14px;
  padding: 10px 12px;
  box-shadow: var(--shadow-sm);
}
.baby-timer-pick-chips { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; min-width: 0; }
.baby-timer-chip {
  border: 1px solid color-mix(in srgb, var(--tk) 35%, var(--line));
  background: color-mix(in srgb, var(--tk) 8%, var(--bg-elev));
  color: var(--text); border-radius: 999px;
  padding: 9px 14px; min-height: 38px;   /* one-thumb targets */
  font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  transition: background .12s ease, border-color .12s ease, transform .1s ease;
}
.baby-timer-chip:hover { background: color-mix(in srgb, var(--tk) 16%, var(--bg-elev)); }
.baby-timer-chip:active { transform: scale(.95); }
.baby-timer-chip.is-plain { background: var(--tk); border-color: transparent; color: #fff; }
.baby-timer-chip.is-plain:hover { filter: brightness(1.08); }
.baby-timer-pick-cancel { flex: none; width: 32px; height: 32px; color: var(--text-soft); }
@media (max-width: 480px) {
  .baby-timer-pick { flex-wrap: wrap; }
  .baby-timer-pick .baby-timer-emoji { display: none; }   /* chips get the full width */
}

/* Finish-feed sheet: type chips + common-amount presets + free entry. */
.baby-ff-sub { margin: 0 0 14px; }
.baby-ff-group { margin-bottom: 16px; }
.baby-ff-label { display: block; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-soft); margin-bottom: 8px; }
.baby-ff-types, .baby-ff-presets { display: flex; flex-wrap: wrap; gap: 8px; }
.baby-ff-type, .baby-ff-preset {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); background: var(--bg-elev); color: var(--text);
  border-radius: 999px; padding: 9px 14px; min-height: 40px;   /* one-thumb targets */
  font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  transition: background .12s ease, border-color .12s ease, transform .1s ease;
}
.baby-ff-type:hover, .baby-ff-preset:hover { background: var(--bg-hover); }
.baby-ff-type:active, .baby-ff-preset:active { transform: scale(.95); }
.baby-ff-type.active, .baby-ff-preset.active { background: var(--accent, #6366f1); border-color: transparent; color: #fff; }
.baby-ff-amount { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.baby-ff-amount .form-input { flex: 1; min-width: 0; max-width: 160px; }
.baby-ff-unit { font-size: 14px; font-weight: 700; color: var(--text-soft); }
.baby-ff-actions { margin-top: 6px; }
@media (max-width: 480px) {
  .baby-ff-skip { order: 3; }
}

/* Running banner: spans the full row, live tint, one big Finish. */
.baby-timer-live {
  grid-column: 1 / -1;
  display: flex; align-items: stretch; gap: 10px;
  background: color-mix(in srgb, var(--tk) 10%, var(--bg-elev));
  border: 1px solid color-mix(in srgb, var(--tk) 36%, var(--line));
  border-radius: 14px;
  padding: 10px 12px;
  box-shadow: var(--shadow-sm);
}
.baby-timer-body {
  display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0;
  border: 0; background: transparent; padding: 2px; margin: 0;
  font: inherit; text-align: left; cursor: pointer; border-radius: 10px;
}
.baby-timer-body:hover .baby-timer-sub { color: var(--text-soft); }
.baby-timer-emoji.is-live { animation: babyTimerPulse 2.4s ease-in-out infinite; }
@keyframes babyTimerPulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tk) 38%, transparent); }
  50% { box-shadow: 0 0 0 7px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .baby-timer-emoji.is-live { animation: none; }
}
.baby-timer-main { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.baby-timer-label { font-size: 15px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.baby-timer-elapsed { color: var(--tk); font-variant-numeric: tabular-nums; }
.baby-timer-sub { font-size: 11px; color: var(--text-mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.baby-timer-finish {
  flex: none; align-self: center;
  border: 0; border-radius: 12px; cursor: pointer;
  background: var(--tk); color: #fff;
  font: inherit; font-size: 14px; font-weight: 700;
  padding: 12px 20px; min-height: 44px;   /* one-thumb 3am target */
  transition: transform .1s ease, filter .12s ease;
}
.baby-timer-finish:hover { filter: brightness(1.08); }
.baby-timer-finish:active { transform: scale(.96); }

/* Forgot to finish: amber and explicit — surfaced, never auto-closed. */
.baby-timer-live.is-stale {
  background: color-mix(in srgb, #d97706 12%, var(--bg-elev));
  border-color: color-mix(in srgb, #d97706 46%, var(--line));
}
.baby-timer-live.is-stale .baby-timer-emoji.is-live { animation: none; }
.baby-timer-stale-flag {
  display: inline-block; vertical-align: 2px; margin-left: 4px;
  font-size: 10px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase;
  color: #b45309; background: color-mix(in srgb, #d97706 18%, transparent);
  border-radius: 999px; padding: 2px 7px;
}
:root[data-theme="dark"] .baby-timer-stale-flag { color: #fbbf24; }
@media (max-width: 480px) {
  .baby-timers { gap: 8px; }
  .baby-timer-startbtn { flex-direction: column; text-align: center; gap: 6px; padding: 12px 8px; }
  .baby-timer-start-main { align-items: center; }
  .baby-timer-play { display: none; }
}

/* ---- day at a glance (24h visual band) ---- */
/* ---- baby calendar mode (month grid shows baby activity) ---- */
.baby-cal-btn.active {
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
}
.baby-cal-banner {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 8px; padding: 7px 12px;
  border: 1px solid color-mix(in srgb, var(--primary) 30%, var(--line));
  border-radius: 12px;
  background: color-mix(in srgb, var(--primary) 8%, var(--bg-elev));
  font-size: 13px; color: var(--text-soft);
}
.baby-cal-banner-text { flex: 1; min-width: 0; }
.baby-cal-cell { cursor: pointer; }
.baby-cal-list {
  display: flex; flex-direction: column; gap: 3px;
  min-height: 0; overflow: hidden;
}
.baby-cal-stat {
  font-size: 11.5px; font-weight: 600; color: var(--text-soft);
  line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.baby-cal-stat em {
  font-style: normal; font-weight: 500; color: var(--text-mute); font-size: 10.5px;
}
.baby-cal-sep { color: var(--text-mute); }
.baby-cal-stat.is-extra { opacity: .85; }
@media (max-width: 880px) {
  .baby-cal-banner { font-size: 12px; padding: 6px 10px; }
  .baby-cal-list { gap: 1px; }
  .baby-cal-stat { font-size: 9px; letter-spacing: -0.01em; }
  .baby-cal-stat em { display: none; }
}

/* ---- voice logging ---- */
.baby-quick-actions { display: flex; align-items: center; gap: 6px; }
.baby-voice-btn.listening {
  color: var(--danger, #ef4444);
  border-color: color-mix(in srgb, var(--danger, #ef4444) 55%, var(--line));
  animation: baby-voice-pulse 1.4s ease-in-out infinite;
}
@keyframes baby-voice-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--danger, #ef4444) 30%, transparent); }
  50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--danger, #ef4444) 12%, transparent); }
}
.baby-voice-hint {
  margin: 0 0 8px; font-size: 13px; color: var(--text-soft); font-style: italic;
}

.baby-daytl-nav { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.baby-section-head--tl { flex-wrap: wrap; row-gap: 6px; }

/* Range switcher (24h / Day / Week / Month) — mirrors the unit segments. */
.baby-tlmode {
  display: inline-flex; border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg-elev); padding: 2px; margin-right: 6px;
}
.baby-tlmode-btn {
  border: 0; background: transparent; color: var(--text-soft);
  font: inherit; font-size: 12px; font-weight: 600;
  padding: 4px 10px; border-radius: 999px; cursor: pointer;
  transition: background .12s, color .12s;
}
.baby-tlmode-btn:hover { color: var(--text); }
.baby-tlmode-btn.active { background: var(--primary-fill); color: var(--on-primary); }
.baby-daytl-navbtn { width: 30px; height: 30px; }
.baby-daytl-navbtn:disabled { opacity: 0.35; pointer-events: none; }
.baby-daytl-daybtn {
  min-width: 92px; padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg-elev);
  color: var(--text); font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; transition: background .12s, border-color .12s;
}
.baby-daytl-daybtn:hover { background: var(--bg-hover); }
.baby-daytl-daybtn.is-today { border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); color: var(--primary); }

.baby-daytl { display: flex; flex-direction: column; gap: 10px; }
.baby-daytl-track {
  position: relative; width: 100%;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-elev); overflow: hidden;
}
/* Hourly gridlines: 24 hairlines, heavier every 6h, drawn behind everything. */
.baby-daytl-grid {
  position: absolute; left: 0; right: 0; top: 0;
  background-image:
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--line) 60%, transparent) 0 1px, transparent 1px calc(100% / 24)),
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--line) 100%, transparent) 0 1px, transparent 1px calc(100% / 4));
  pointer-events: none;
}
.baby-daytl-sleep {
  position: absolute; top: 10px; padding: 0; cursor: pointer;
  border: 1px solid color-mix(in srgb, #7c3aed 45%, transparent);
  background: color-mix(in srgb, #7c3aed 22%, transparent);
  border-radius: 7px; min-width: 3px; z-index: 1;
  transition: background .12s;
}
.baby-daytl-sleep:hover { background: color-mix(in srgb, #7c3aed 34%, transparent); }
.baby-daytl-sleep.is-live {
  border-style: dashed;
  border-color: color-mix(in srgb, #7c3aed 70%, transparent);
  background: color-mix(in srgb, #7c3aed 30%, transparent);
}
.baby-daytl-sleep:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.baby-daytl-now {
  position: absolute; top: 6px; bottom: 30px; width: 2px;
  background: var(--danger, #ef4444); border-radius: 2px; z-index: 3;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger, #ef4444) 18%, transparent);
}
.baby-daytl-now::before {
  content: ""; position: absolute; top: -4px; left: 50%; transform: translateX(-50%);
  width: 7px; height: 7px; border-radius: 50%; background: var(--danger, #ef4444);
}
.baby-daytl-mark {
  position: absolute; transform: translateX(-50%); padding: 0;
  width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid color-mix(in srgb, var(--bk) 65%, transparent);
  background: color-mix(in srgb, var(--bk) 16%, var(--bg-elev));
  cursor: pointer; z-index: 4; line-height: 1;
  transition: transform .1s, box-shadow .1s;
}
.baby-daytl-mark:hover { transform: translateX(-50%) scale(1.18); box-shadow: 0 2px 8px rgba(0,0,0,.18); z-index: 5; }
.baby-daytl-mark:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.baby-daytl-emoji { font-size: 11px; }
/* Mixed pee+poop mark carries two emojis — pill instead of circle. */
.baby-daytl-mark.is-double { width: auto; min-width: 20px; padding: 0 4px; border-radius: 999px; }
.baby-daytl-mark.is-double .baby-daytl-emoji { font-size: 9px; letter-spacing: 0.5px; }
.baby-daytl-axis { position: absolute; left: 0; right: 0; bottom: 6px; height: 16px; }
.baby-daytl-hour {
  position: absolute; font-size: 10px; font-weight: 600;
  color: var(--text-mute); letter-spacing: 0.02em; white-space: nowrap;
}
.baby-daytl-empty {
  position: absolute; inset: 0 0 30px 0; display: flex;
  align-items: center; justify-content: center;
  font-size: 13px; color: var(--text-mute); pointer-events: none;
}
.baby-daytl-loading {
  padding: 40px 0; text-align: center; font-size: 13px; color: var(--text-mute);
  border: 1px solid var(--line); border-radius: 14px; background: var(--bg-elev);
}
.baby-daytl-legend { display: flex; flex-wrap: wrap; gap: 6px; }
.baby-daytl-chip {
  font-size: 12px; font-weight: 600; color: var(--text-soft);
  padding: 3px 10px; border-radius: 999px;
  background: var(--bg-hover); border: 1px solid var(--line);
}

/* ---- week/month: stacked mini day-bands ---- */
.baby-mdtl {
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-elev); overflow: hidden;
}
.baby-mdtl-row {
  display: flex; align-items: center; gap: 8px;
  padding: 3px 10px; cursor: pointer;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  transition: background .12s;
}
.baby-mdtl-row:last-child { border-bottom: 0; }
.baby-mdtl-row:hover { background: var(--bg-hover); }
.baby-mdtl-row:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.baby-mdtl-row.is-open { background: var(--bg-hover); border-bottom-color: transparent; }

/* Tap-to-reveal totals for one day (kept off the rows to avoid crowding). */
.baby-mdtl-detail {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 2px 10px 10px;
  background: var(--bg-hover);
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
.baby-mdtl-detail:last-child { border-bottom: 0; }
.baby-mdtl-openday { margin-left: auto; white-space: nowrap; }
.baby-mdtl-label {
  flex: none; width: 58px; font-size: 11px; font-weight: 600;
  color: var(--text-mute); white-space: nowrap;
}
.baby-mdtl-band { position: relative; flex: 1; height: 30px; min-width: 0; }
.baby-mdtl-row.is-compact .baby-mdtl-band { height: 14px; }
.baby-mdtl-row.is-compact { padding: 1px 10px; }
.baby-mdtl-sleep {
  position: absolute; top: 20%; height: 60%; min-width: 2px;
  border-radius: 4px; background: color-mix(in srgb, #7c3aed 24%, transparent);
  border: 1px solid color-mix(in srgb, #7c3aed 40%, transparent);
  pointer-events: none;
}
.baby-mdtl-sleep.is-live { border-style: dashed; background: color-mix(in srgb, #7c3aed 32%, transparent); }
.baby-mdtl-mark {
  position: absolute; top: 50%; transform: translate(-50%, -50%);
  width: 18px; height: 18px; padding: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; line-height: 1; cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--bk) 60%, transparent);
  background: color-mix(in srgb, var(--bk) 16%, var(--bg-elev));
  transition: transform .1s;
}
.baby-mdtl-mark:hover { transform: translate(-50%, -50%) scale(1.2); z-index: 3; }
.baby-mdtl-mark.is-double { width: auto; min-width: 18px; padding: 0 3px; border-radius: 999px; font-size: 8px; }
.baby-mdtl-tick {
  position: absolute; top: 15%; height: 70%; width: 3px;
  transform: translateX(-50%); border-radius: 2px; opacity: .85;
  pointer-events: none;
}
.baby-mdtl-now {
  position: absolute; top: 0; bottom: 0; width: 2px;
  background: var(--danger, #ef4444); border-radius: 2px;
  pointer-events: none;
}

/* ---- timeline ---- */
.baby-timeline { display: flex; flex-direction: column; gap: 16px; }
.baby-day-group { display: flex; flex-direction: column; gap: 6px; }
.baby-day-head {
  font-size: 12px; font-weight: 700; color: var(--text-mute);
  text-transform: uppercase; letter-spacing: 0.05em;
  padding: 2px 2px 4px;
  position: sticky; top: 0;
}
.baby-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 12px;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.baby-row:hover { background: var(--bg-hover); }
.baby-row:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.baby-row-icon {
  flex: none;
  width: 36px; height: 36px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 17px;
  background: color-mix(in srgb, var(--bk) 16%, transparent);
}
/* A mixed pee+poop change shows both emojis — widen the circle into a pill. */
.baby-row-icon.is-double { width: auto; min-width: 36px; padding: 0 7px; border-radius: 999px; font-size: 14px; letter-spacing: 1px; }
.baby-row-main { flex: 1; min-width: 0; }
.baby-row-detail { font-size: 14px; font-weight: 600; color: var(--text); }
.baby-row-meta { font-size: 12px; color: var(--text-mute); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; }
.baby-row-note { color: var(--text-soft); font-style: italic; }
.baby-row-del { flex: none; width: 30px; height: 30px; color: var(--text-mute); opacity: .7; }
.baby-row-del:hover { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); opacity: 1; }

/* ---- log photos ---- */
/* Thumbnails inside a timeline row (photos attached to the log). */
.baby-row-photos {
  display: flex; flex-wrap: nowrap; overflow-x: auto;
  gap: 5px; margin-top: 6px;
  scrollbar-width: thin;
}
.baby-row-photo {
  flex: 0 0 auto;
  width: 52px; height: 52px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  border-radius: 8px;
  padding: 0; cursor: pointer; overflow: hidden;
  transition: transform .12s, border-color .12s;
}
.baby-row-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.baby-row-photo:hover { transform: scale(1.05); border-color: var(--primary); }

/* Composer photo strip (existing + staged-for-upload). */
.baby-log-photos-head { display: flex; align-items: center; gap: 8px; }
.baby-log-photo-strip {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 6px;
}
.baby-log-photo-strip[hidden] { display: none; }
.baby-log-photo { position: relative; }
.baby-log-photo-thumb {
  display: block;
  width: 72px; height: 72px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  border-radius: 8px;
  padding: 0; cursor: pointer; overflow: hidden;
  transition: transform .12s, border-color .12s;
}
.baby-log-photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
button.baby-log-photo-thumb:hover { transform: scale(1.03); border-color: var(--primary); }
.baby-log-photo.is-staged .baby-log-photo-thumb { border-style: dashed; cursor: default; }
.baby-log-photo-del {
  position: absolute; top: -6px; right: -6px;
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--bg-elev);
  color: var(--text-mute);
  font-size: 13px; line-height: 1;
  cursor: pointer;
}
.baby-log-photo-del:hover { color: var(--danger); border-color: var(--danger); }
.baby-empty-inline { font-size: 13px; color: var(--text-soft); text-align: center; padding: 24px 12px; }
.baby-timeline-more { display: flex; justify-content: center; margin-top: 4px; }

/* ---- CSV export / import ---- */
.baby-timeline-actions { display: flex; gap: 6px; flex-shrink: 0; }
.baby-timeline-actions .btn { display: inline-flex; align-items: center; gap: 5px; }
.baby-timeline-actions .btn svg { flex-shrink: 0; }
@media (max-width: 560px) {
  /* Keep the icons; drop the labels so the two buttons fit next to the title. */
  .baby-timeline-actions .btn { padding: 6px; }
  .baby-timeline-actions-label { display: none; }
}

.baby-import-body { display: flex; flex-direction: column; gap: 14px; }
.baby-import-lead { margin: 0; color: var(--text-soft); font-size: 14px; line-height: 1.5; }
.baby-import-lead code { font-size: 12px; }

.baby-import-format {
  border: 1px solid var(--line); border-radius: 12px;
  padding: 4px 12px 12px;
  background: var(--bg);
}
.baby-import-format > summary {
  cursor: pointer; padding: 10px 2px; margin: 0 -2px;
  font-weight: 600; font-size: 14px; color: var(--text);
  list-style-position: inside;
}
.baby-import-format > summary:hover { color: var(--primary); }
.baby-import-format p { margin: 6px 0; font-size: 13px; color: var(--text-soft); line-height: 1.5; }
.baby-import-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 6px 0; }
.baby-import-table {
  width: 100%; border-collapse: collapse; font-size: 12.5px;
  min-width: 460px;
}
.baby-import-table th, .baby-import-table td {
  text-align: left; padding: 6px 8px; vertical-align: top;
  border-bottom: 1px solid var(--line);
}
.baby-import-table th { color: var(--text-mute); font-weight: 600; white-space: nowrap; }
.baby-import-table td { color: var(--text-soft); }
.baby-import-table code {
  font-size: 11.5px; background: var(--bg-hover);
  padding: 1px 5px; border-radius: 5px; white-space: nowrap;
}
.baby-import-table .req {
  display: inline-block; margin-left: 4px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--danger);
}
.baby-import-eg {
  font-size: 12px; color: var(--text-mute);
  overflow-x: auto; white-space: nowrap;
}
.baby-import-eg code { background: var(--bg-hover); padding: 2px 6px; border-radius: 6px; }

.baby-import-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.baby-import-file { cursor: pointer; }
.baby-import-filename { font-size: 13px; color: var(--text-mute); overflow: hidden; text-overflow: ellipsis; }
.baby-import-modal textarea {
  width: 100%; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; line-height: 1.5;
}

.baby-import-result {
  border-radius: 10px; padding: 10px 12px; font-size: 13px; line-height: 1.5;
  background: var(--bg-hover); color: var(--text);
}
.baby-import-result.ok { background: color-mix(in srgb, var(--ok, #16a34a) 14%, transparent); }
.baby-import-result.warn { background: color-mix(in srgb, #f59e0b 16%, transparent); }
.baby-import-result.err { background: color-mix(in srgb, var(--danger) 14%, transparent); }
.baby-import-errs { margin: 6px 0 0; padding-left: 18px; color: var(--text-soft); font-size: 12.5px; }
.baby-import-errs li { margin: 2px 0; }

.baby-import-defaults {
  margin: 12px 0 0; padding: 10px 12px 12px;
  border: 1px solid var(--line); border-radius: 10px;
  background: color-mix(in srgb, var(--surface-2, var(--surface)) 60%, transparent);
}
.baby-import-defaults legend { padding: 0 6px; font-size: 12.5px; font-weight: 600; color: var(--text-soft); }
.baby-import-defaults-hint { margin: 0 0 10px; font-size: 12.5px; color: var(--text-mute); line-height: 1.45; }
.baby-import-defaults-row { display: flex; flex-wrap: wrap; gap: 10px; }
.baby-import-defaults-row .field { flex: 1 1 140px; min-width: 0; margin: 0; }
.baby-import-defaults-row .field[hidden] { display: none; }

.baby-import-actions { display: flex; align-items: center; gap: 10px; }
.baby-import-actions .spacer { flex: 1; }
.baby-import-status { font-size: 13px; color: var(--text-mute); }

/* ---- care reminders ---- */
.baby-reminders-body { display: flex; flex-direction: column; gap: 14px; }
.baby-reminders-lead { margin: 0; color: var(--text-soft); font-size: 14px; line-height: 1.5; }
.baby-reminders-list { display: flex; flex-direction: column; gap: 10px; }
.baby-reminder-row {
  border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px;
  background: var(--bg-soft, transparent); transition: border-color .15s;
}
.baby-reminder-row.on { border-color: color-mix(in srgb, var(--bk) 45%, var(--line)); }
.baby-reminder-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.baby-reminder-label { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14.5px; color: var(--text); }
.baby-reminder-emoji { font-size: 16px; }
.baby-reminder-tune { margin-top: 12px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.baby-reminder-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.baby-reminder-chip {
  border: 1px solid var(--line); background: transparent; color: var(--text-soft);
  border-radius: 999px; padding: 3px 11px; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.baby-reminder-chip:hover { border-color: color-mix(in srgb, var(--bk) 45%, var(--line)); }
.baby-reminder-chip.active { background: var(--bk); border-color: var(--bk); color: #fff; }
.baby-reminder-interval { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-soft); }
.baby-reminder-interval input { width: 74px; padding: 5px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--text); font: inherit; }
.baby-reminders-foot { display: flex; align-items: center; gap: 10px; }
.baby-reminders-foot .spacer { flex: 1; }
.baby-reminders-status { font-size: 13px; color: var(--text-mute); }

/* ---- compose sheet + profile form ---- */
.baby-log-fields { display: flex; flex-direction: column; gap: 12px; }
.baby-form-row { display: flex; gap: 12px; }
.baby-form-row .field { flex: 1; min-width: 0; }
.baby-field-unit { flex: 0 0 96px; }
/* Inputs/selects must never spill past their field — datetime-local pickers
   have a wide intrinsic size that otherwise overflows the flex row. */
.baby-log-fields .field input,
.baby-log-fields .field select { width: 100%; min-width: 0; max-width: 100%; }
@media (max-width: 560px) {
  /* Two datetime-local pickers can't share a row on a phone without clipping
     or overlapping — give each the full width by stacking them. */
  .baby-form-row--time { flex-direction: column; gap: 12px; }
}
.baby-log-actions, .baby-profile-actions {
  display: flex; align-items: center; gap: 10px; margin-top: 16px;
}
.baby-log-actions .spacer, .baby-profile-actions .spacer { flex: 1; }
.baby-log-status { font-size: 12px; color: var(--text-soft); }
.baby-color-swatches { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.baby-swatch {
  width: 30px; height: 30px; border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform .1s ease;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.08);
}
.baby-swatch:hover { transform: scale(1.1); }
.baby-swatch.active { border-color: var(--text); transform: scale(1.1); }

/* ---- profile "important details" disclosure ---- */
.baby-details { margin-top: 16px; border-top: 1px solid var(--border); padding-top: 12px; }
.baby-details-summary {
  cursor: pointer; font-weight: 600; font-size: 14px; list-style: none;
  display: flex; align-items: center; gap: 8px; user-select: none;
}
.baby-details-summary::-webkit-details-marker { display: none; }
.baby-details-summary::before {
  content: "›"; font-size: 18px; line-height: 1; color: var(--text-soft);
  transition: transform .15s ease;
}
.baby-details[open] > .baby-details-summary::before { transform: rotate(90deg); }
.baby-details-body { display: flex; flex-direction: column; gap: 12px; margin-top: 12px; }
.baby-measure { display: flex; gap: 8px; align-items: center; }
.baby-measure input { flex: 1; min-width: 0; }
.baby-measure select { flex: 0 0 72px; }
.baby-measure-suffix { flex: none; font-size: 13px; color: var(--text-mute); font-weight: 600; }
.field-note { display: block; margin-top: 4px; font-size: 11px; color: var(--text-mute); line-height: 1.35; }

/* ---- Settings → Baby management list ---- */
.settings-baby-list { display: flex; flex-direction: column; gap: 10px; }
.settings-baby-empty { margin: 4px 0; font-size: 14px; }
.settings-baby-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--bg-soft);
}
.settings-baby-row.is-archived { opacity: .6; }
.settings-baby-dot {
  flex: 0 0 auto; width: 12px; height: 12px; border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.12);
}
.settings-baby-main { flex: 1; min-width: 0; }
.settings-baby-name { font-weight: 600; font-size: 15px; }
.settings-baby-meta { font-size: 12px; margin-top: 2px; }
.settings-baby-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.settings-baby-chip {
  font-size: 11px; padding: 2px 8px; border-radius: 999px;
  background: var(--bg-hover); color: var(--text-soft);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.settings-baby-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }

/* ---- load skeleton (avoid flashing the empty state before data lands) ---- */
.baby-skeleton { display: flex; flex-direction: column; gap: 18px; }
.baby-sk-profile, .baby-sk-tile, .baby-sk-card {
  background: linear-gradient(90deg, var(--bg-soft) 0%, var(--bg-hover) 50%, var(--bg-soft) 100%);
  background-size: 200% 100%;
  animation: skelShimmer 1.4s ease-in-out infinite;
  border-radius: 14px;
}
.baby-sk-profile { height: 82px; }
.baby-sk-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.baby-sk-tile { height: 68px; }
.baby-sk-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.baby-sk-card { height: 84px; }

/* ---- responsive ---- */
@media (max-width: 620px) {
  .baby-cards { grid-template-columns: repeat(2, 1fr); }
  .baby-quick-grid { grid-template-columns: repeat(3, 1fr); }
  .baby-trends { grid-template-columns: 1fr; }
  .baby-sk-cards { grid-template-columns: repeat(2, 1fr); }
  /* Stack each since-tile vertically so "2h 14m" never gets clipped on phones. */
  .baby-since-row { gap: 8px; }
  .baby-since { flex-direction: column; align-items: flex-start; gap: 7px; padding: 11px; }
  .baby-since-emoji { width: 34px; height: 34px; font-size: 18px; }
  .baby-since-value { font-size: 18px; }
}

/* ---- mobile scene chrome (mirror Settings): full-screen page ---- */
@media (max-width: 880px) {
  body[data-scene="baby"] .topbar,
  body[data-scene="baby"] .mobile-tabs { display: none !important; }
  /* The calendar shell is hidden for every non-calendar scene by the general
     `body[data-scene]:not([data-scene="calendar"]) main.layout` rule in the
     mobile-page block above. */
  body[data-scene="baby"] .app-view-close { display: none; }
  body[data-scene="baby"] .app-view-mobile-head {
    display: flex; align-items: center; gap: 6px;
    position: sticky; top: 0; z-index: 40;
    padding: 6px 8px;
    padding-top: max(6px, env(safe-area-inset-top));
    background: color-mix(in srgb, var(--bg-elev) 96%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--line);
    margin: 0 -8px 8px;
  }
  body[data-scene="baby"] .app-view-back { width: 40px; height: 40px; color: var(--text); }
  body[data-scene="baby"] .app-view-back:hover { background: var(--bg-hover); }
  body[data-scene="baby"] .app-view-mobile-title {
    margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; color: var(--text);
  }
  body[data-scene="baby"] .app-view { padding-top: 0; gap: 0; }
}

/* ============================================================
   Water tracker — a PERSONAL daily hydration scene. Mirrors the
   Baby scene's shell + section rhythm (reuses .app-view chrome),
   with a progress ring, quick-add chips, today's log list, and a
   7-day mini bar chart. Light/dark parity via design tokens.
   ============================================================ */
.water-shell {
  width: 100%;
  max-width: 620px;
  margin: 0 auto;
  padding: 0 4px 40px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.water-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.water-head-title { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; color: var(--text); }
.water-goal-btn { flex: none; }

.water-section { display: flex; flex-direction: column; gap: 12px; }
.water-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.water-section-title {
  margin: 0; font-size: 14px; font-weight: 700; color: var(--text-soft);
  text-transform: uppercase; letter-spacing: 0.04em;
}

/* ---- progress ring ---- */
.water-progress {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 22px 16px;
  box-shadow: var(--shadow-sm);
}
.water-ring { position: relative; width: 150px; height: 150px; }
.water-ring-track { stroke: var(--bg-soft); }
.water-ring-fill {
  stroke: var(--primary);
  transition: stroke-dasharray .5s ease;
}
.water-ring.is-met .water-ring-fill { stroke: var(--success); }
.water-ring-center {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
}
.water-ring-total { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; color: var(--text); }
.water-ring-goal { font-size: 13px; color: var(--text-soft); }
.water-progress-meta {
  display: flex; align-items: center; gap: 12px;
  font-size: 14px; color: var(--text-soft);
}
.water-remaining strong { color: var(--text); font-weight: 700; }
.water-goal-met { color: var(--success); font-weight: 600; }
.water-progress-pct {
  margin-left: auto; font-size: 13px; font-weight: 700;
  color: var(--primary);
  background: var(--primary-tint);
  border-radius: 999px; padding: 3px 10px;
}

/* ---- quick-add chips ---- */
.water-quick { display: flex; flex-wrap: wrap; gap: 10px; }
.water-quick-btn {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-width: 78px; padding: 12px 14px;
  border: 1px solid var(--line);
  background: var(--bg-elev);
  color: var(--text);
  border-radius: 14px;
  cursor: pointer;
  font: inherit;
  box-shadow: var(--shadow-sm);
  transition: background .12s ease, border-color .12s ease, transform .12s ease;
}
.water-quick-btn:hover { background: var(--bg-hover); border-color: var(--primary); }
.water-quick-btn:active { transform: translateY(1px); }
.water-quick-amt { font-size: 18px; font-weight: 800; letter-spacing: -0.01em; color: var(--primary); }
.water-quick-unit { font-size: 11px; color: var(--text-soft); text-transform: uppercase; letter-spacing: 0.05em; }
.water-quick-custom { color: var(--text-soft); }
.water-quick-custom span { font-size: 13px; font-weight: 600; }

/* ---- today's log list ---- */
.water-log-list { display: flex; flex-direction: column; gap: 8px; }
.water-log-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 12px;
}
.water-log-row.is-pending { opacity: 0.55; }
.water-log-drop { flex: none; color: var(--primary); display: inline-flex; }
.water-log-amt { font-size: 15px; font-weight: 700; color: var(--text); }
.water-log-time { margin-left: auto; font-size: 13px; color: var(--text-soft); }
.water-log-del { flex: none; width: 30px; height: 30px; color: var(--text-muted); }
.water-log-del:hover { background: var(--bg-hover); color: var(--danger); }

/* ---- 7-day history bar chart ---- */
.water-history {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 16px 12px 10px;
}
.water-bars { display: flex; align-items: flex-end; justify-content: space-between; gap: 8px; height: 120px; }
.water-bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; }
.water-bar-track {
  position: relative; width: 100%; max-width: 34px; flex: 1;
  background: var(--bg-soft);
  border-radius: 8px 8px 4px 4px;
  overflow: hidden;
}
.water-bar-fill {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: var(--primary);
  border-radius: 8px 8px 0 0;
  transition: height .4s ease;
}
.water-bar-fill.met { background: var(--success); }
/* Dashed goal line across each bar's track. */
.water-bar-goal {
  position: absolute; left: 0; right: 0; height: 0;
  border-top: 2px dashed color-mix(in srgb, var(--text-soft) 55%, transparent);
  z-index: 1;
}
.water-bar-col.is-today .water-bar-label { color: var(--primary); font-weight: 800; }
.water-bar-label { font-size: 11px; color: var(--text-soft); font-weight: 600; }

/* ---- goal / unit editor ---- */
.water-goal-editor {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 16px;
}
.water-goal-form { display: flex; flex-direction: column; gap: 14px; }
.water-field { display: flex; flex-direction: column; gap: 6px; }
.water-field-label { font-size: 13px; font-weight: 600; color: var(--text-soft); }
.water-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--text);
  border-radius: 10px;
  font: inherit;
}
.water-input:focus { outline: none; border-color: var(--primary); }
.water-units { display: inline-flex; gap: 8px; }
.water-unit {
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--text-soft);
  border-radius: 999px;
  padding: 7px 18px;
  font: inherit; font-weight: 600; font-size: 13px;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.water-unit:hover { background: var(--bg-hover); color: var(--text); }
.water-unit.active { background: var(--primary-fill); color: var(--on-primary); border-color: transparent; }
.water-goal-actions { display: flex; justify-content: flex-end; gap: 8px; }
/* Settings › Health — the goal input + its trailing unit label. */
.settings-water-goal { display: inline-flex; align-items: center; gap: 10px; }
.settings-water-goal .water-input { width: 120px; }
.settings-water-goal-unit { color: var(--text-soft); font-weight: 600; font-size: 13px; }

.water-empty-inline { font-size: 13px; color: var(--text-soft); text-align: center; padding: 20px 12px; }

/* ---- mobile scene chrome (mirror Baby): full-screen page ---- */
@media (max-width: 880px) {
  body[data-scene="water"] .topbar,
  body[data-scene="water"] .mobile-tabs { display: none !important; }
  body[data-scene="water"] .app-view-close { display: none; }
  body[data-scene="water"] .app-view-mobile-head {
    display: flex; align-items: center; gap: 6px;
    position: sticky; top: 0; z-index: 40;
    padding: 6px 8px;
    padding-top: max(6px, env(safe-area-inset-top));
    background: color-mix(in srgb, var(--bg-elev) 96%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--line);
    margin: 0 -8px 8px;
  }
  body[data-scene="water"] .app-view-back { width: 40px; height: 40px; color: var(--text); }
  body[data-scene="water"] .app-view-back:hover { background: var(--bg-hover); }
  body[data-scene="water"] .app-view-mobile-title {
    margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; color: var(--text);
  }
  body[data-scene="water"] .app-view { padding-top: 0; gap: 0; }
  .water-quick-btn { min-width: 70px; flex: 1; }
}

/* ============================================================
   Medications & supplements — a PERSONAL meds tracker scene.
   Mirrors the Water scene's shell + section rhythm (reuses the
   .app-view chrome) with a richer definition+logs model like Baby:
   an adherence summary, a card per active medication with its
   scheduled-dose pills, and a day-grouped history timeline.
   Light/dark parity via design tokens.
   ============================================================ */
.meds-shell {
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding: 0 4px 40px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.meds-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.meds-head-title { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; color: var(--text); }
.meds-add-btn { flex: none; }

.meds-section { display: flex; flex-direction: column; gap: 12px; }
.meds-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.meds-section-title {
  margin: 0; font-size: 14px; font-weight: 700; color: var(--text-soft);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.meds-empty-inline { font-size: 13px; color: var(--text-soft); text-align: center; padding: 20px 12px; }

/* ---- adherence summary ---- */
.meds-summary {
  display: flex; align-items: center; gap: 18px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 18px 20px;
  box-shadow: var(--shadow-sm);
}
.meds-summary:empty { display: none; }
.med-summary-ring { position: relative; width: 84px; height: 84px; flex: none; }
.med-summary-track { stroke: var(--bg-soft); }
.med-summary-fill { stroke: var(--primary); transition: stroke-dasharray .5s ease; }
.med-summary-ring.is-met .med-summary-fill { stroke: var(--success); }
.med-summary-pct {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 17px; font-weight: 800; letter-spacing: -0.02em; color: var(--text);
}
.med-summary-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.med-summary-headline { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; color: var(--text); }
.med-summary-of { font-size: 15px; font-weight: 600; color: var(--text-soft); }
.med-summary-sub { font-size: 13px; color: var(--text-soft); }
.med-summary-due {
  align-self: flex-start; margin-top: 4px;
  font-size: 12px; font-weight: 700; color: var(--primary);
  background: var(--primary-tint); border-radius: 999px; padding: 3px 10px;
}
.med-summary-done { align-self: flex-start; margin-top: 4px; font-size: 13px; font-weight: 600; color: var(--success); }

/* ---- medication cards ---- */
.meds-cards { display: flex; flex-direction: column; gap: 12px; }
.med-card {
  --mc: var(--primary);
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 12px;
  box-shadow: var(--shadow-sm);
}
.med-card-top { display: flex; align-items: flex-start; gap: 12px; }
.med-card-dot { flex: none; width: 10px; height: 10px; margin-top: 5px; border-radius: 50%; background: var(--mc); box-shadow: inset 0 0 0 1px rgba(0,0,0,.12); }
.med-card-id { flex: 1; min-width: 0; }
.med-card-name { font-size: 16px; font-weight: 700; color: var(--text); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.med-kind-badge {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  padding: 2px 7px; border-radius: 999px;
  background: var(--bg-hover); color: var(--text-soft);
}
.med-kind-badge-supplement { background: color-mix(in srgb, var(--success) 16%, transparent); color: var(--success); }
.med-card-dose { font-size: 13px; color: var(--text-soft); margin-top: 2px; }
.med-card-edit { flex: none; width: 32px; height: 32px; color: var(--text-muted); }
.med-card-edit:hover { background: var(--bg-hover); color: var(--text); }

/* scheduled-dose pills: taken=filled+check, pending=outline, skipped=strikethrough */
.med-card-pills { display: flex; flex-wrap: wrap; gap: 8px; }
.med-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 12px 6px 10px;
  border-radius: 999px;
  border: 1.5px solid var(--line);
  background: var(--bg-soft);
  color: var(--text-soft);
  font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease, transform .12s ease;
}
.med-pill:hover { border-color: var(--mc); color: var(--text); }
.med-pill:active { transform: translateY(1px); }
.med-pill-check { display: none; align-items: center; }
.med-pill-taken {
  background: var(--mc); border-color: transparent; color: #fff;
}
.med-pill-taken:hover { color: #fff; filter: brightness(1.03); }
.med-pill-taken .med-pill-check { display: inline-flex; }
.med-pill-skipped { text-decoration: line-through; opacity: .6; }
.med-pill-skipped .med-pill-time { text-decoration: line-through; }

.med-card-asneeded { font-size: 13px; color: var(--text-soft); }
.med-card-tally { font-size: 12px; font-weight: 600; color: var(--text-soft); }
.med-card-foot { display: flex; align-items: center; gap: 12px; }
.med-take-now { display: inline-flex; align-items: center; gap: 6px; }
.med-take-now svg { color: var(--mc); }
.med-card-foot .med-card-tally { margin-left: auto; }

/* ---- history timeline ---- */
.meds-history { display: flex; flex-direction: column; gap: 16px; }
.meds-day-group { display: flex; flex-direction: column; gap: 8px; }
.meds-day-head {
  font-size: 12px; font-weight: 700; color: var(--text-soft);
  text-transform: uppercase; letter-spacing: 0.04em; padding: 0 2px;
}
.med-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 12px;
  cursor: pointer;
  transition: background .12s ease;
}
.med-row:hover { background: var(--bg-hover); }
.med-row:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.med-row.is-skipped { opacity: .72; }
.med-row-icon {
  flex: none; width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--mc); color: #fff; font-size: 13px; font-weight: 700;
}
.med-row.is-skipped .med-row-icon { background: var(--bg-hover); color: var(--text-muted); }
.med-row-main { flex: 1; min-width: 0; }
.med-row-name { font-size: 14px; font-weight: 600; color: var(--text); }
.med-row-meta { font-size: 12px; color: var(--text-soft); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; }
.med-row-status { color: var(--danger); font-weight: 600; }
.med-row-note { color: var(--text-soft); }
.med-row-del { flex: none; width: 30px; height: 30px; color: var(--text-muted); }
.med-row-del:hover { background: var(--bg-hover); color: var(--danger); }

/* ---- compose / edit + log sheets ---- */
.med-kind-toggle, .med-status-toggle { display: inline-flex; gap: 8px; }
.med-kind, .med-status {
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--text-soft);
  border-radius: 999px;
  padding: 7px 18px;
  font: inherit; font-weight: 600; font-size: 13px;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.med-kind:hover, .med-status:hover { background: var(--bg-hover); color: var(--text); }
.med-kind.active, .med-status.active { background: var(--primary-fill); color: var(--on-primary); border-color: transparent; }

.med-edit-form .field select,
.med-log-form .field input,
.med-log-form .field select { width: 100%; min-width: 0; max-width: 100%; }

.med-sched-editor { display: flex; flex-direction: column; gap: 10px; }
.med-asneeded-row { display: flex; }
.med-asneeded-toggle {
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--text-soft);
  border-radius: 999px;
  padding: 6px 14px;
  font: inherit; font-weight: 600; font-size: 12px;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.med-asneeded-toggle:hover { background: var(--bg-hover); color: var(--text); }
.med-asneeded-toggle.active { background: var(--primary-fill); color: var(--on-primary); border-color: transparent; }
.med-sched-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.med-sched-empty { font-size: 12px; color: var(--text-soft); }
.med-sched-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 6px 5px 12px;
  border-radius: 999px;
  background: var(--primary-tint);
  color: var(--text);
  font-size: 13px; font-weight: 600;
}
.med-sched-del {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%;
  border: 0; background: transparent; color: var(--text-soft);
  font-size: 15px; line-height: 1; cursor: pointer;
}
.med-sched-del:hover { background: var(--bg-hover); color: var(--danger); }
.med-sched-add { display: flex; gap: 8px; align-items: center; }
.med-sched-input {
  flex: 0 0 auto;
  padding: 8px 10px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--text);
  border-radius: 10px;
  font: inherit;
}
.med-sched-input:focus { outline: none; border-color: var(--primary); }

.med-color-swatches { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.med-swatch {
  width: 30px; height: 30px; border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform .1s ease;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.08);
}
.med-swatch:hover { transform: scale(1.1); }
.med-swatch.active { border-color: var(--text); transform: scale(1.1); }

.med-edit-actions, .med-log-actions { display: flex; align-items: center; gap: 10px; margin-top: 16px; }
.med-edit-actions .spacer, .med-log-actions .spacer { flex: 1; }
.med-log-name { font-size: 16px; font-weight: 700; color: var(--text); }

/* ---- mobile scene chrome (mirror Water/Baby): full-screen page ---- */
@media (max-width: 880px) {
  body[data-scene="meds"] .topbar,
  body[data-scene="meds"] .mobile-tabs { display: none !important; }
  body[data-scene="meds"] .app-view-close { display: none; }
  body[data-scene="meds"] .app-view-mobile-head {
    display: flex; align-items: center; gap: 6px;
    position: sticky; top: 0; z-index: 40;
    padding: 6px 8px;
    padding-top: max(6px, env(safe-area-inset-top));
    background: color-mix(in srgb, var(--bg-elev) 96%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--line);
    margin: 0 -8px 8px;
  }
  body[data-scene="meds"] .app-view-back { width: 40px; height: 40px; color: var(--text); }
  body[data-scene="meds"] .app-view-back:hover { background: var(--bg-hover); }
  body[data-scene="meds"] .app-view-mobile-title {
    margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; color: var(--text);
  }
  body[data-scene="meds"] .app-view { padding-top: 0; gap: 0; }
}
@media (max-width: 560px) {
  .meds-summary { padding: 16px; gap: 14px; }
  .med-summary-headline { font-size: 22px; }
}

/* ================= Feedback modal ================= */
.feedback-form .field textarea { width: 100%; resize: vertical; }
.feedback-form .field input[type="file"] { font-size: 13px; }
.feedback-check { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text); margin: 4px 0; cursor: pointer; }
.feedback-note { font-size: 12px; color: var(--text-mute); margin: 6px 0 0; line-height: 1.45; }
.feedback-actions { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.feedback-actions .spacer { flex: 1; }
/* Page mode (mobile): the mobile head already carries the title. */
body[data-page="feedback"] #feedbackModal > .modal-head { display: none; }
body[data-page="feedback"] #feedbackModal .modal-body { flex: 1; min-height: 0; }
