:root {
  /* DailyGrid brand: Warm Sage + Peach */
  --bg: #F6F2EA;            /* linen page */
  --surface: #FCFAF5;       /* card */
  --band: #F1F6F2;          /* alt section background (pale sage) */
  --ink: #2F4035;           /* forest text */
  --muted: #5E6B5E;
  --line: #E5DECF;          /* warm border */
  --line-strong: #C7BB9A;   /* heavier divider, e.g. between two days */

  --brand: #4F745B;         /* sage 600 (AA on white) */
  --brand-d: #3D5A47;       /* sage 700 hover */
  --brand-soft: #DEEAE1;    /* sage 100 */

  --peach: #FFB39E;         /* accent base */
  --peach-soft: #FFE6DE;
  --peach-ink: #B5573F;
  --appt: #7C83B4;          /* calm slate-lavender for appointments (was harsh brick red) */
  --appt-soft: #ECEEF7;

  --ok: #3E9D6B;
  --high: #C9533F;          /* warm brick (to-do / urgent / danger) */
  --low: #4C8FA6;           /* soft teal */
  --gold: #E3B23C;          /* highlight (flagged / priority) */
  --gold-ink: #4A3608;

  /* Mobile app shell aliases: the phone design (bottom-tab layout) refers to the
     palette by these names. Most map onto the existing brand colours above so there
     is a single source of truth; only the two soft tints and --faint are new. */
  --sage: var(--brand);
  --sage-d: var(--brand-d);
  --sage-soft: var(--brand-soft);
  --brick: var(--high);
  --brick-soft: #F7DED7;    /* pale brick, for the "needs you" count chip */
  --linen: var(--bg);
  --line-2: var(--line-strong);
  --faint: #8B8A7E;         /* lightest ink, for inactive tab icons / free time */
  --slate: var(--appt);
  --slate-soft: var(--appt-soft);

  --radius: 14px;
  --shadow: 0 1px 2px rgba(47,64,53,.06), 0 8px 24px rgba(47,64,53,.07);
  --maxw: 1120px;
}

* { box-sizing: border-box; }
/* The hidden attribute must always win, even over flex/grid display rules. */
[hidden] { display: none !important; }
html { scroll-behavior: smooth; overflow-x: clip; }  /* clip (not hidden): stops sideways page creep without breaking position:sticky */
/* No form control may ever be wider than its container (long values, 16px mobile fonts). */
input, select, textarea { max-width: 100%; }
body {
  margin: 0;
  font-family: "Nunito Sans", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--ink);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* Sticky footer: fill the viewport so the footer never floats up and reveals
     the linen background below it when a page (e.g. a filtered view) is short. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
h1, h2, h3 { line-height: 1.15; margin: 0; }
.display { font-family: "Fraunces", Georgia, serif; font-weight: 600; letter-spacing: -.01em; }
p { margin: 0; }
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-d); }

.container { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
main { display: block; flex: 1 0 auto; }

/* ---------- Top bar ---------- */
/* Floating pill nav */
/* Stick to the very top with a solid page-colour bar so scrolled content can never
   show in the strip above or behind the floating pill (mobile bleed fix). The pill
   still sits 14px down via padding, so it keeps its floating look. */
.topbar { position: sticky; top: 0; margin-top: 0; padding: 14px 0 12px; z-index: 30; background: var(--bg); border: 0; }
.topbar-inner { display: flex; align-items: center; justify-content: space-between; height: 60px; position: relative;
  background: rgba(252,250,245,.72); backdrop-filter: blur(14px) saturate(1.4); -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border: 1px solid rgba(255,255,255,.6); border-radius: 999px; padding: 0 14px 0 18px;
  box-shadow: 0 14px 36px rgba(31,45,33,.16), inset 0 1px 0 rgba(255,255,255,.6); }
/* On the landing the pill floats over the full-bleed hero video */
.landing .topbar { position: absolute; top: 14px; left: 0; right: 0; margin-top: 0; padding: 0; background: transparent; }
/* Without backdrop-filter (e.g. Windows browsers with it disabled) the translucent
   pill lets content show through, so make it opaque so it never looks like the nav
   is overlapping the page behind it. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .topbar-inner { background: rgba(252,250,245,.97); }
  .hero-pills { background: rgba(255,255,255,.95); }
  .btn.glass { background: rgba(255,255,255,.96); }
}
.brand { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); font-weight: 700; }
/* The wordmark: one lowercase word, two tones. "daily" carries the colour and "grid" carries
   the weight of the surface it sits on, so the pair reads as one word rather than two.
   The two halves are TOKENS, not fixed colours, because white only exists on a dark ground:
   on the linen header "grid" is forest ink, and on the dark footer it is white. Set the
   colour anywhere by redefining the two variables, never by restating a hex. */
.brand-name {
  font-family: "Nunito Sans", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-weight: 700;
  font-size: 1.24rem;
  letter-spacing: -.022em;   /* the reference is set tight; the default tracking reads loose */
  /* The MARKUP says DailyGrid and this makes it look lowercase. That order matters: a crawler,
     a screen reader and an OAuth reviewer all read the text, not the rendering, so the machine
     readable name is DailyGrid while the mark on screen stays the lowercase one. Writing
     "dailygrid" into the HTML instead would have left the header with no capitalised instance
     of the product's name anywhere on the page. */
  text-transform: lowercase;
}
.brand-name .wm-a { color: var(--wm-a, var(--ink)); }     /* daily */
.brand-name .wm-b { color: var(--wm-b, var(--brand)); }   /* grid  */
.logo { width: 32px; height: 32px; border-radius: 9px; display: block; }
.topnav { display: flex; align-items: center; gap: 18px; }
/* Tabs sit dead-centre of the bar, independent of the brand/account widths. */
.nav-links { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; gap: 4px; }
.nav-links a { color: var(--muted); font-weight: 600; font-size: .95rem;
  padding: 7px 14px; border-radius: 9px; transition: background .15s, color .15s; }
.nav-links a:hover { color: var(--ink); background: var(--band); }
/* Active tab: clear sage container + bolder, darker label. */
.nav-links a.active { color: var(--brand-d); background: var(--brand-soft); font-weight: 700; }
.nav-account { display: flex; align-items: center; gap: 14px; }
.nav-account > a { color: var(--muted); }
.topbar .btn.light { border: 1px solid var(--line); }
.nav-toggle { display: none; background: transparent; border: 0; cursor: pointer; padding: 8px; flex-direction: column; gap: 4px; }
.nav-toggle span { display: block; width: 22px; height: 2px; background: var(--ink); border-radius: 2px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--brand); color: #fff; border: none; cursor: pointer;
  padding: 11px 20px; border-radius: 12px; font: inherit; font-weight: 600; font-size: .98rem;
  transition: transform .12s ease, filter .15s ease, box-shadow .15s ease; text-decoration: none;
}
.btn:hover { filter: brightness(1.05); color: #fff; transform: translateY(-1px); }
.btn:active { transform: translateY(1px); }
.btn.sm { padding: 8px 14px; font-size: .9rem; border-radius: 10px; }
.btn.lg { padding: 14px 26px; font-size: 1.05rem; }
.btn.block { width: 100%; }
.btn.ghost { background: transparent; color: var(--brand); border: 1.5px solid var(--brand-soft); }
.btn.ghost:hover { background: var(--brand-soft); color: var(--brand-d); }
.btn.ghost.danger { color: var(--high); border-color: rgba(201,83,63,.4); }
.btn.ghost.danger:hover { background: rgba(201,83,63,.08); color: var(--high); }
.danger-zone { border-color: rgba(201,83,63,.35); }
.danger-zone .card-title { color: var(--high); }
.btn.light { background: #fff; color: var(--brand-d); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn.loading { position: relative; color: transparent !important; pointer-events: none; }
.btn.loading::after { content: ""; position: absolute; inset: 0; margin: auto; width: 16px; height: 16px; border-radius: 50%; border: 2px solid rgba(255,255,255,.5); border-top-color: #fff; animation: spin .7s linear infinite; }
.btn.ghost.loading::after, .btn.light.loading::after { border-color: rgba(79,116,91,.3); border-top-color: var(--brand); }

/* ---------- Pills ---------- */
.pill { font-size: .8rem; padding: 4px 11px; border-radius: 20px; font-weight: 600; }
.pill.ok { background: var(--brand-soft); color: var(--brand-d); }
.pill.warn { background: var(--peach-soft); color: var(--peach-ink); }

/* ---------- Shared text ---------- */
.kicker { display: inline-block; text-transform: uppercase; letter-spacing: .08em; font-size: .74rem; font-weight: 700; color: var(--brand); margin-bottom: 14px; }
.lead { font-size: 1.12rem; color: #4c594d; }
.lead.center { text-align: center; margin-left: auto; margin-right: auto; max-width: 580px; }
.micro { color: var(--muted); font-size: .85rem; }
.micro.center { text-align: center; }
.muted { color: var(--muted); }
em { font-style: italic; color: var(--brand); }

/* ---------- Icons ---------- */
.ico { width: 26px; height: 26px; color: var(--brand); }
.ico-sm { width: 18px; height: 18px; color: var(--ok); flex: none; }
.ico-xs { width: 14px; height: 14px; flex: none; }

/* Date and time badges: make dates obviously dates, not loose text */
.date-badge { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 999px;
  background: var(--brand-soft); color: var(--brand-d); font-size: .72rem; font-weight: 700;
  letter-spacing: .02em; white-space: nowrap; line-height: 1.4; }
.date-badge.time { background: #f6ecdd; color: #8a5a23; }
.date-badge .ico-xs { opacity: .85; }

/* Accessibility and motion (UI/UX checklist) */
html { scroll-behavior: smooth; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 6px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- Flash ---------- */
.flash { background: var(--brand-soft); border-bottom: 1px solid var(--line);
  transition: opacity .4s ease, transform .4s ease; }
.flash.flash-out { opacity: 0; transform: translateY(-8px); }
.flash .container { padding: 12px 24px; color: var(--brand-d); font-weight: 500;
  display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.flash-x { background: none; border: 0; font-size: 1.4rem; line-height: 1; color: var(--brand-d);
  opacity: .55; cursor: pointer; padding: 0 2px; flex: none; }
.flash-x:hover { opacity: 1; }

/* ---------- Visual placeholders ---------- */
.ph {
  position: relative; width: 100%; border-radius: var(--radius);
  background:
    repeating-linear-gradient(45deg, rgba(91,91,214,.05) 0 12px, rgba(91,91,214,.09) 12px 24px);
  border: 2px dashed #c9c9ea; display: grid; place-items: center; padding: 24px;
}
.ph::after { content: attr(data-label); color: #6f6f9a; font-size: .82rem; font-weight: 600; text-align: center; max-width: 80%; }
.ph-hero { aspect-ratio: 4/3; }
.ph-shot { aspect-ratio: 16/10; }

/* ================= LANDING ================= */

/* Hero: full-bleed soft-focus video under a light linen wash, dark type on top */
/* padding-top reserves space for the floating (position:absolute) nav so the
   vertically-centred content always clears it. Without it, on short viewports
   (e.g. Windows at 125–150% display scaling) the centred content rises to the
   top of the hero and slides under the nav, overlapping the title + mock. */
.hero { position: relative; overflow: hidden; background: linear-gradient(180deg, #EFF4ED, var(--bg)); border: 0; padding: 90px 0 0;
  min-height: 100vh; display: flex; align-items: center; }
/* Heavy blur + slight lift so the printed text in the footage melts into a soft texture */
.hero-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; pointer-events: none; background: var(--bg); filter: blur(7px) brightness(1.06) saturate(.9); transform: scale(1.1); }
/* Soft linen wash, lightest through the centre so the dark type stays crisp */
.hero-scrim { position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(120% 92% at 50% 44%, rgba(246,242,234,.84) 0%, rgba(246,242,234,.52) 68%, rgba(246,242,234,.42) 100%),
    linear-gradient(180deg, rgba(246,242,234,.42) 0%, rgba(246,242,234,.2) 42%, rgba(246,242,234,.74) 100%); }
/* Nav clearance now lives on .hero (padding-top); keep only breathing room here. */
/* Longhands on purpose. This element is `class="container hero-grid"`, and a `padding`
   SHORTHAND here would also set padding-left/right to 0, beating .container's `0 24px` on
   specificity. That left the hero (and only the hero) with no side padding, so on a phone
   the headline and copy ran edge to edge, and on desktop the hero sat 24px wider than
   every section below it. */
.hero .hero-grid { position: relative; z-index: 2; padding-top: 24px; padding-bottom: 48px; align-items: center; }
.hero-copy { text-align: left; }
.hero .hero-visual { position: relative; z-index: 2; display: flex; justify-content: center; }
.hero .hero-visual .mock-board { max-width: 400px; box-shadow: 0 30px 70px rgba(31,45,33,.18); }

.hero-pills { display: inline-flex; align-items: center; gap: 13px; margin-bottom: 28px;
  padding: 8px 18px; border: 1px solid var(--brand-soft); border-radius: 999px;
  background: rgba(255,255,255,.62); backdrop-filter: blur(6px); box-shadow: 0 2px 12px rgba(31,45,33,.05);
  text-transform: uppercase; letter-spacing: .14em; font-size: .68rem; font-weight: 700; color: var(--brand-d); }
.hero-pills .dot, .hero-trust .dot { width: 4px; height: 4px; border-radius: 50%; background: currentColor; opacity: .45; flex: none; }

.hero-title { color: var(--ink); font-size: clamp(2.4rem, 5.6vw, 4.05rem); line-height: 1.04;
  letter-spacing: -.02em; margin: 0 0 18px; max-width: 13ch; text-shadow: 0 1px 14px rgba(246,242,234,.92); }
.hero-title em { font-style: italic; color: var(--brand-d);
  background: none; -webkit-background-clip: border-box; background-clip: border-box; -webkit-text-fill-color: currentColor; filter: none; }

.hero-lead { font-size: clamp(1.02rem, 1.5vw, 1.2rem); line-height: 1.6; color: #46534a;
  max-width: 500px; margin: 0 0 28px; text-shadow: 0 1px 10px rgba(246,242,234,.8); }

.hero .cta-row { justify-content: flex-start; gap: 14px; margin: 0 0 26px; }
.hero .btn.lg:not(.glass) { box-shadow: 0 10px 26px rgba(79,116,91,.28); }
.btn.glass { background: rgba(255,255,255,.74); color: var(--brand-d); border: 1px solid var(--brand-soft); backdrop-filter: blur(8px); box-shadow: 0 4px 14px rgba(31,45,33,.06); }
.btn.glass:hover { background: #fff; color: var(--brand-d); filter: none; }

.hero-trust { display: flex; align-items: center; flex-wrap: wrap; row-gap: 5px;
  color: var(--muted); font-size: .85rem; }
.hero-trust svg { width: 15px; height: 15px; color: var(--brand); margin-right: 6px; }
.hero-trust .ht-item { display: inline-flex; align-items: center; }
/* Separator travels WITH its item, so a wrapped item leads with the dot (like a list
   marker) instead of leaving a dangling bullet at the end of the previous line. */
.hero-trust .ht-item + .ht-item { margin-left: 14px; }
.hero-trust .ht-item + .ht-item::before { content: "•"; margin-right: 14px; opacity: .45; }
.hero-audience { color: var(--muted); font-size: .8rem; margin: 10px 0 0; opacity: .85; }

/* Belt and braces with the script in landing.html: if JS never runs, the clip still must
   not paint on a phone. The .hero gradient stands in for it. */
@media (prefers-reduced-motion: reduce), (max-width: 820px) { .hero-video { display: none; } }
@media (max-width: 720px) { .hero-inner { padding: 124px 20px 80px; } }
.hero-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: 48px; align-items: center; }
.hero-copy h1 { font-size: 3.1rem; margin-bottom: 16px; }
.hero-copy .lead { margin-bottom: 26px; max-width: 520px; }
.cta-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }

/* Value strip */
.strip { border-bottom: 1px solid var(--line); background: var(--surface); }
.strip-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; padding: 26px 24px; }
.strip-item { display: flex; gap: 12px; align-items: flex-start; }
.strip-item p { display: flex; flex-direction: column; }
.strip-item strong { font-size: .98rem; }
.strip-item span { color: var(--muted); font-size: .9rem; }

/* Sections */
.section { padding: 60px 0; }
.section.alt { background: var(--band); }
.section-head { text-align: center; max-width: 640px; margin: 0 auto 32px; }
.section-head h2 { font-size: 2.2rem; margin-bottom: 10px; }

/* Steps */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.step-card { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 28px 24px; box-shadow: var(--shadow); }
.step-card .ico { margin-bottom: 14px; }
.step-card h3 { font-size: 1.15rem; margin-bottom: 6px; }
.step-card p { color: var(--muted); font-size: .96rem; }
.step-num { position: absolute; top: 14px; right: 22px; font-family: "Fraunces", serif; font-weight: 700; font-size: 2.6rem; line-height: 1; letter-spacing: -.02em; color: #E08A66; }
/* Card hover lift + scroll reveal */
.feature, .step-card { transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease; }
.feature:hover, .step-card:hover { transform: translateY(-4px); box-shadow: 0 18px 40px rgba(31,45,33,.13); border-color: var(--brand-soft); }
.reveal { opacity: 0; transform: translateY(16px); transition: opacity .6s ease, transform .6s ease; }
.reveal-in { opacity: 1; transform: none; }

/* Showcase */
.showcase-grid { display: grid; grid-template-columns: 1fr 1.3fr; gap: 48px; align-items: center; }
.showcase-copy h2 { font-size: 2.1rem; margin-bottom: 12px; }
.ticks { list-style: none; padding: 0; margin: 22px 0 0; display: grid; gap: 12px; }
.ticks li { display: flex; gap: 10px; align-items: flex-start; }
.ticks span { font-weight: 500; }

/* /start: what the app does, in four lines, above the form. Kept to one short paragraph each so
   a shared link explains itself in about ten seconds and the form is still near the top. */
.start-points { max-width: 640px; margin: 4px auto 0; gap: 14px; }
.start-points svg { width: 20px; height: 20px; flex: 0 0 auto; color: var(--brand); margin-top: 2px; }
.start-points span { font-weight: 400; font-size: .95rem; line-height: 1.55; color: var(--muted); }
.start-points b { color: var(--ink); font-weight: 700; }
.start-points { margin-bottom: 26px; }

/* Trust strip: the privacy promise above the form, where the decision is actually made. Quiet
   rather than alarming, so it reads as a fact about the product and not a warning. */
.trust-strip { display: flex; align-items: flex-start; gap: 10px; margin: 0 auto 18px; max-width: 640px;
  padding: 12px 15px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
  font-size: .9rem; line-height: 1.5; color: var(--muted); }
.trust-strip svg { width: 18px; height: 18px; flex: 0 0 auto; color: var(--brand); margin-top: 2px; }
.trust-strip b { color: var(--ink); font-weight: 700; }

/* Heads-up about the provider's consent screen, sat directly above the button it precedes. */
.consent-heads-up { margin: 14px 0 10px; font-size: .88rem; line-height: 1.5; color: var(--muted); }
.btn-sub { margin-top: 9px; }

/* Sign-in reassurance (privacy promises restated at the connect moment) */
.signin-assure { margin-top: 16px; gap: 9px; }
.signin-assure svg { width: 18px; height: 18px; flex: 0 0 auto; color: var(--brand); margin-top: 1px; }
.signin-assure span { font-weight: 500; font-size: .9rem; color: var(--muted); }
.feature h3 .rec { vertical-align: middle; margin-left: 6px; }

/* Sample preview */
.preview { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; max-width: 880px; margin: 0 auto; }
.preview-col { display: flex; flex-direction: column; gap: 14px; }
.col-label { font-weight: 700; font-size: .95rem; color: var(--ink); }

/* Features */
.features { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.feature { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 26px 22px; box-shadow: var(--shadow); }
/* Colourful icon chips give the feature grids life */
.feature .ico { width: 46px; height: 46px; padding: 11px; border-radius: 13px; box-sizing: border-box; margin-bottom: 16px; background: var(--brand-soft); color: var(--brand-d); }
.valueprops .feature:nth-child(6n+1) .ico { background: var(--brand-soft); color: var(--brand-d); }
.valueprops .feature:nth-child(6n+2) .ico { background: #E2EEF4; color: #2f6f9e; }
.valueprops .feature:nth-child(6n+3) .ico { background: var(--peach-soft); color: var(--peach-ink); }
.valueprops .feature:nth-child(6n+4) .ico { background: #DEF0E8; color: #2f8f76; }
.valueprops .feature:nth-child(6n+5) .ico { background: #ECE8FB; color: #6b5bd6; }
.valueprops .feature:nth-child(6n+6) .ico { background: #FBEBCF; color: #9a6b1e; }
.feature h3 { font-size: 1.05rem; margin-bottom: 6px; }
.feature p { color: var(--muted); font-size: .92rem; }

/* Connect card */
.narrow-mid { max-width: 620px; }
.connect-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow); }
.option { display: flex; gap: 14px; align-items: flex-start; border: 2px solid var(--line); border-radius: 14px; padding: 16px; margin-bottom: 12px; cursor: pointer; transition: border-color .15s, background .15s; }
.option:has(input:checked) { border-color: var(--brand); background: #f5f5fe; }
.option input[type=radio] { width: auto; margin-top: 3px; flex: none; accent-color: var(--brand); }
.option-body { display: flex; flex-direction: column; gap: 4px; }
.option-title { font-weight: 700; display: flex; align-items: center; gap: 8px; }
.option-desc { color: var(--muted); font-size: .92rem; }
.rec { font-size: .68rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; background: var(--peach-soft); color: var(--peach-ink); padding: 2px 8px; border-radius: 6px; white-space: nowrap; }
/* Roadmap badge pinned to a feature card's top-right corner (kept off the heading so it never wraps). */
.rec-corner { position: absolute; top: 14px; right: 14px; }
.senders { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.sub-label { font-size: .85rem; font-weight: 600; }
.senders textarea, .form textarea, .form input, .form select { width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; font: inherit; background: #fff; }
.hint { font-size: .82rem; color: var(--muted); }
.connect-card .btn { margin-top: 6px; }
.field-label { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; font-weight: 700; color: var(--muted); margin: 4px 0 10px; }
.field-label + .option, .provider-pick + .field-label { margin-top: 2px; }
.provider-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 20px; }
.provider { display: flex; align-items: center; gap: 12px; border: 2px solid var(--line); border-radius: 14px; padding: 14px 16px; cursor: pointer; transition: border-color .15s, background .15s; }
.provider:has(input:checked) { border-color: var(--brand); background: #f5f5fe; }
.provider input[type=radio] { width: auto; flex: none; accent-color: var(--brand); }
.provider-body { display: flex; flex-direction: column; gap: 2px; }
.provider-name { font-weight: 700; }
.provider-sub { font-size: .8rem; color: var(--muted); }
@media (max-width: 520px) { .provider-pick { grid-template-columns: 1fr; } }

/* Emphasis phrase in headings (DailyNest-style italic accent) */
.display em { font-style: italic; font-weight: 600; color: var(--brand-d); }

/* Rendered mock UI used as landing visuals (not real screenshots) */
.hero-visual { display: flex; justify-content: center; }
.mock { background: var(--surface); border: 1px solid var(--line); border-radius: 18px; box-shadow: 0 18px 50px rgba(31,31,58,.12); overflow: hidden; width: 100%; }
.mock-board { max-width: 380px; }
.mock-bar { display: flex; align-items: center; gap: 7px; padding: 12px 16px; border-bottom: 1px solid var(--line); background: #faf7f0; }
.mock-bar .md { width: 10px; height: 10px; border-radius: 50%; background: #e3ddcf; }
.mock-bar .md:nth-child(1) { background: #f3b6a3; }
.mock-bar .md:nth-child(2) { background: #f0d49a; }
.mock-bar .md:nth-child(3) { background: #aed9b9; }
.mock-name { margin-left: 8px; font-size: .8rem; font-weight: 700; color: var(--muted); }
.mock-body { padding: 0; display: block; background: var(--surface); }

/* Hero board = a compact weekly agenda preview (date rail + entries) */
.mock-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 15px 16px 11px; }
.mock-h { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.05rem; color: var(--ink); }
.mock-range { font-size: .7rem; font-weight: 700; color: var(--brand-d); background: var(--brand-soft); padding: 3px 10px; border-radius: 999px; white-space: nowrap; }

.mock-agenda { display: flex; flex-direction: column; }
.mock-row { display: flex; gap: 13px; align-items: center; padding: 11px 16px; border-top: 1px solid var(--line); }
.mock-row.is-today { background: #fff5ef; box-shadow: inset 3px 0 0 var(--peach); }

.mock-date { flex: none; width: 38px; display: flex; flex-direction: column; align-items: center; gap: 1px; }
.mock-dow { font-size: .62rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.mock-dnum { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.4rem; line-height: 1; color: var(--ink); }
.mock-row.is-today .mock-dow, .mock-row.is-today .mock-dnum { color: var(--peach-ink); }

.mock-entry { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.mock-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
.mock-cat { display: inline-flex; align-items: center; gap: 6px; font-size: .7rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .02em; }
.mock-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.mock-dot.c-school { background: var(--brand); }
.mock-dot.c-appt { background: var(--peach-ink); }
.mock-dot.c-travel { background: #2f8f76; }
.mock-dot.c-sports { background: #2f6f9e; }
.mock-title { flex: 1; min-width: 0; font-size: .9rem; font-weight: 700; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mock-when { flex: none; font-size: .72rem; font-weight: 700; color: #8a5a23; background: #f6ecdd; padding: 2px 8px; border-radius: 6px; white-space: nowrap; }
.mock-due { flex: none; font-size: .72rem; font-weight: 700; color: var(--high); white-space: nowrap; }
.mock-row.is-today .mock-due { color: var(--peach-ink); }

.mock-kid { margin-left: auto; flex: none; display: inline-flex; align-items: center; gap: 5px; font-size: .72rem; font-weight: 700; color: var(--ink); }
.mock-kid::before { content: attr(data-i); display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; font-size: .6rem; font-weight: 800; color: #fff; background: var(--kc, var(--brand)); }
.mock-kid.k-maya { --kc: #db7f57; }
.mock-kid.k-leo { --kc: #3e86a0; }
.mock-kid.k-sam { --kc: #5b7e66; }

/* Mail mock = a faithful preview of the real briefing email (see emailer.render_html):
   warm-sage shell, pale-sage header panel, peach "needs you first" panel, date-tile agenda. */
.mock-mail { max-width: 560px; background: #fff; }
.mail-accent { height: 6px; background: #4F745B; }
.mail-pad { padding: 16px 20px; background: #fff; }

.mail-head { background: #ECF2EC; border: 1px solid #DCE7DC; border-radius: 14px; padding: 14px 18px; }
.mail-brand { display: flex; align-items: center; gap: 8px; font-size: .82rem; font-weight: 800; color: #4F745B; letter-spacing: .01em; }
.mail-logo { width: 19px; height: 19px; border-radius: 5px; display: block; flex: none; }
.mail-date { font-size: .62rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase; color: #8E938A; margin: 11px 0 5px; }
.mail-title { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.45rem; color: #2F4035; line-height: 1.12; }
.mail-summary { font-size: .82rem; color: #5E6B5E; line-height: 1.5; margin: 7px 0 0; }

.mail-todos { background: #FFE6DE; border-radius: 13px; padding: 11px 16px; margin-top: 12px; }
.mail-todos-h { font-size: .64rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: #B5573F; margin-bottom: 4px; }
.mail-todo { padding: 6px 0; }
.mail-todo + .mail-todo { border-top: 1px solid #F6CDBF; }
.mail-todo-t { font-size: .82rem; font-weight: 800; color: #2F4035; }
.mail-todo-m { font-size: .74rem; font-weight: 700; color: #B5573F; margin-left: 6px; white-space: nowrap; }

/* Stretch the date tile to the card's height with its date centred, so the two line up as one row. */
.mail-day { display: flex; gap: 12px; margin-top: 13px; align-items: stretch; }
.mail-tile { flex: none; width: 52px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  background: #F5F1E8; border: 1px solid #E7E0D2; border-radius: 12px; padding: 8px 4px; }
.mail-tile.is-today { background: #FFE6DE; }
.mail-tile-mon { font-size: .56rem; font-weight: 800; letter-spacing: .06em; color: #3D5A47; }
.mail-tile-num { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.4rem; line-height: 1.05; color: #2F4035; }
.mail-tile-dow { font-size: .56rem; font-weight: 800; letter-spacing: .02em; color: #5E6B5E; }
.mail-tile.is-today .mail-tile-num, .mail-tile.is-today .mail-tile-dow { color: #B5573F; }

.mail-cards { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.mail-card { background: #fff; border: 1px solid #E7E0D2; border-radius: 12px; padding: 10px 14px; }
.mail-card-top { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.mail-time { font-size: .72rem; font-weight: 800; color: #3D5A47; white-space: nowrap; }
.mail-kid { font-size: .64rem; font-weight: 800; color: #fff; padding: 2px 9px; border-radius: 999px; white-space: nowrap; }
.mail-cat { margin-left: auto; font-size: .62rem; font-weight: 800; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.mail-card-title { font-size: .9rem; font-weight: 800; color: #2F4035; line-height: 1.3; margin-top: 8px; }
.mail-card-desc { font-size: .78rem; color: #5E6B5E; margin: 3px 0 0; }

/* Value props (three cards reusing the .feature card look) */
.valueprops { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
/* The first value section runs four across on desktop; it collapses with the base rule below 900px. */
@media (min-width: 901px) { .valueprops.vp-4 { grid-template-columns: repeat(4, 1fr); } }

/* Three-lane sample preview */
.preview.three { grid-template-columns: repeat(3, 1fr); max-width: 1040px; }

/* FAQ */
.faq { display: flex; flex-direction: column; gap: 10px; }
.faq-item { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 4px 18px; box-shadow: var(--shadow); }
.faq-item summary { cursor: pointer; font-weight: 600; padding: 14px 0; list-style: none; position: relative; padding-right: 28px; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; position: absolute; right: 4px; top: 12px; font-size: 1.3rem; color: var(--brand); font-weight: 400; }
.faq-item[open] summary::after { content: "\2212"; }
.faq-item p { color: var(--muted); line-height: 1.6; margin: 0 0 14px; }

/* Pricing / what you'll get */
.pricing-card { max-width: 460px; margin: 0 auto; background: var(--surface); border: 1px solid var(--line); border-radius: 18px; padding: 30px; box-shadow: var(--shadow); text-align: center; }
.price { display: flex; align-items: baseline; justify-content: center; gap: 8px; margin-bottom: 18px; }
.price-amt { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 2.4rem; color: var(--ink); }
.price-per { color: var(--muted); font-size: .95rem; }
.plan-features { list-style: none; padding: 0; margin: 0 0 22px; text-align: left; }
.plan-features li { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; color: #3a3a4a; }

/* Final CTA band */
.cta-band { background: linear-gradient(120deg, var(--brand), var(--brand-d)); color: #fff; padding: 72px 0; text-align: center; }
.cta-band h2 { font-size: 2.3rem; margin-bottom: 10px; }
.cta-band .lead { color: rgba(255,255,255,.9); margin-bottom: 24px; }

/* ---------- Page wrapper (app screens) ---------- */
.page { max-width: 960px; margin: 0 auto; padding: 40px 24px 64px; }
.page.narrow { max-width: 720px; }
.page.center-page { text-align: center; padding-top: 80px; }
.page .display { font-size: 2rem; margin-bottom: 8px; }

/* Setup steps list */
.steps-list { line-height: 1.8; padding-left: 20px; }
.steps-list li { margin-bottom: 10px; }
code, .copy { background: #ececf6; padding: 2px 7px; border-radius: 6px; font-size: .85rem; word-break: break-all; }
.status-row { display: flex; gap: 12px; margin-top: 16px; flex-wrap: wrap; }

/* Connected dashboard */
.hero-row { display: flex; align-items: stretch; justify-content: space-between; gap: 24px; margin-bottom: 18px; }
.hero-text { flex: 1 1 auto; min-width: 0; align-self: center; }
.summary { font-size: 1.08rem; margin: 6px 0; }
.meta { color: var(--muted); font-size: .9rem; }
/* Last-updated line sits just above the Refresh + co-parent actions, grouped together */
.updated-meta { display: inline-flex; align-items: center; gap: 6px; margin: 12px 0 0; font-size: .86rem; color: var(--muted); font-weight: 600; }
.board-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 10px; }
/* Desktop: the secondary actions sit inline exactly as before; no "More" button. */
.board-secondary { display: contents; }
.board-more-toggle { display: none; }
@media (max-width: 640px) {
  /* Mobile: Refresh + "More" only. The rest collapse into a menu so the schedule
     isn't buried under three rows of buttons. */
  .board-secondary { display: none; width: 100%; flex-direction: column; gap: 8px; }
  .board-secondary.open { display: flex; }
  .board-secondary .btn { width: 100%; justify-content: center; }
  .board-more-toggle { display: inline-flex; }
}
.updated-meta .ico-xs { opacity: .75; }
.section-title { display: flex; align-items: center; gap: 10px; margin: 32px 0 14px; font-size: 1.3rem; font-family: "Fraunces", serif; font-weight: 600; }
.count { background: var(--brand-soft); color: var(--brand-d); border-radius: 20px; padding: 1px 10px; font-size: .8rem; font-weight: 700; font-family: "Nunito Sans", sans-serif; }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.empty { text-align: center; padding: 40px; }
.empty .btn { margin-top: 12px; }

/* Kanban board */
.hero-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.micro-link { font-size: .85rem; color: var(--muted); text-decoration: underline; }
button.micro-link { background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }
/* Recipient list inside the Manage / Send popups. */
.rec-people { list-style: none; margin: 12px 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.rec-person { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.rec-person-main { display: flex; flex-direction: column; min-width: 0; }
.rec-person-main strong { font-size: .92rem; color: var(--ink); }
.rec-person-sub { font-size: .78rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.rec-person .inline-form { margin-left: auto; }
.board-hint { display: none; }

/* Mobile-first: lanes stack vertically (no sideways swiping). Columns on desktop. */
.board { display: flex; flex-direction: column; gap: 14px; padding: 2px 0 10px; }
.lane { width: 100%; background: #f3f3fb; border: 1px solid var(--line); border-radius: 16px; padding: 14px; min-width: 0; }
.lane-head { display: flex; align-items: center; gap: 8px; padding: 4px 4px 12px; }
.lane-head h2 { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.05rem; margin: 0; flex: 1; }
.lane-head .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--brand); flex: none; }
.lane-body { display: flex; flex-direction: column; gap: 10px; }
.lane-body .card { box-shadow: 0 1px 2px rgba(20, 20, 50, .06); }
.lane-body .card + .card { margin-top: 0; }
/* per-lane accent dots */
.lane-action .dot { background: var(--high); }
.lane-school_admin .dot { background: #3D5A47; }
.lane-activities .dot { background: var(--low); }
.lane-health .dot { background: #2f8f76; }
.lane-money .dot { background: var(--peach-ink); }
.lane-travel .dot { background: #2f8f76; }
.lane-academics .dot { background: #3D5A47; }
.lane-appointments .dot { background: var(--peach-ink); }
/* legacy lanes (pre-rebuild digests) */
.lane-personal .dot { background: #9aa0ad; }
.lane-todo .dot { background: var(--high); }
.lane-logistics .dot { background: var(--peach-ink); }
/* Personal lane is de-emphasized */
.lane-personal { background: #f1f1f4; opacity: .85; }
.lane-personal .card { box-shadow: none; }

/* category chip + action verb + amount on cards */
.cat { font-size: .68rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: #efe9dd; color: #5e6b5e; }
/* Scoped to the chip (.cat.cat-x): the bare .cat-x classes also mark whole agenda cards
   for their border colour, and unscoped rules painted entire cards pale blue. */
.cat.cat-academics { background: var(--brand-soft); color: var(--brand-d); }
.cat.cat-appointments { background: var(--appt-soft); color: var(--appt); }
.cat.cat-school_admin { background: var(--brand-soft); color: var(--brand-d); }
.cat.cat-activities { background: #e4eef5; color: #2f6f9e; }
.cat.cat-health { background: #e1f0ea; color: #2f8f76; }
.cat.cat-money { background: var(--peach-soft); color: var(--peach-ink); }
.cat.cat-personal { background: #eceef2; color: #6b7280; }
.actverb { font-size: .68rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: var(--high); color: #fff; }
.amount { font-weight: 700; color: var(--peach-ink); }
.ti-link { font-size: .82rem; color: var(--brand-d); font-weight: 600; }

@media (min-width: 900px) {
  .board { flex-direction: row; gap: 16px; }
  .lane { flex: 1 1 0; width: auto; }
}

/* This week (calendar events + dated plan items) */
.week-activities { margin: 8px 0 24px; }
.wa-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.wa-head h2 { font-size: 1.15rem; margin: 0; }
.wa-head .micro-link { font-size: .85rem; }
.wa-empty.card { color: #5d5a52; }
.wa-empty .btn { margin-top: 10px; }
.wa-time.is-plan { min-width: auto; background: var(--brand-soft); color: var(--brand-d); padding: 1px 7px; border-radius: 6px; font-size: .62rem; text-transform: uppercase; letter-spacing: .03em; align-self: flex-start; }
.wa-days { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 6px; }
.wa-day { flex: 0 0 220px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 12px; box-shadow: var(--shadow); }
.wa-day-label { font-weight: 700; font-size: .8rem; text-transform: uppercase; letter-spacing: .03em; color: #6b6757; margin-bottom: 8px; }
.wa-event { display: flex; gap: 8px; padding: 6px 0; border-top: 1px solid #f0eee8; }
.wa-event:first-of-type { border-top: 0; }
.wa-time { font-size: .72rem; font-weight: 700; color: var(--brand-d); white-space: nowrap; min-width: 42px; }
.wa-main strong { font-size: .9rem; }
.wa-loc { font-size: .76rem; color: #7a766c; }
@media (min-width: 900px) { .wa-day { flex: 1 1 0; } }

/* Cards */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 16px; box-shadow: var(--shadow); }
.card.high { border-left: 4px solid var(--brand); }
.card.prio-high { border-left: 4px solid var(--high); }
.card.needs-reply { border-left: 4px solid #e07b3e; background: #fff8f3; }
.noreply { font-size: .68rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: #fce6d8; color: #a23a12; }
.card.flagged { border-left: 4px solid var(--gold); }
.flag-badge { font-size: .68rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: var(--gold); color: var(--gold-ink); }

/* Card actions: one-tap calendar + who's got it */
.card-actions { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.inline-form { margin: 0; }
.mini-btn { font-size: .78rem; font-weight: 600; padding: 5px 10px; border-radius: 8px; border: 1px solid var(--brand-soft); background: var(--brand-soft); color: var(--brand-d); cursor: pointer; }
.mini-btn:hover { background: var(--brand); color: #fff; border-color: var(--brand); }
.mini-btn.ghost { background: transparent; border-color: var(--line); color: var(--muted); }
.mini-btn.ghost:hover { border-color: var(--brand); color: var(--brand-d); background: transparent; }
.assignee { font-size: .72rem; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: #ece9e0; color: #6b6757; }

/* Modal (who's got it) */
.modal { position: fixed; inset: 0; background: rgba(31,31,58,.45); display: flex; align-items: center; justify-content: center; z-index: 50; padding: 20px; }
.modal[hidden] { display: none; }
.modal-card { background: var(--surface); border-radius: 16px; padding: 24px; width: 100%; max-width: 380px; box-shadow: 0 24px 60px rgba(31,31,58,.3); }
.modal-card h3 { margin: 0 0 4px; font-family: "Fraunces", serif; }
.modal-card input[name=person] { width: 100%; margin: 10px 0; }
.modal-card label.sm { display: block; margin: 12px 0 0; font-size: .82rem; font-weight: 600; color: var(--muted); }
.modal-field { width: 100%; margin-top: 5px; }
.rm-err { color: var(--high); font-size: .85rem; margin: 10px 0 0; }
.modal-actions { display: flex; gap: 10px; margin-top: 16px; align-items: center; justify-content: space-between; }
.modal-actions-right { display: flex; gap: 10px; }
/* When there's no Remove button (add mode), keep the right cluster flush right. */
.modal-actions #rec_remove[hidden] + .modal-actions-right { margin-left: auto; }

/* Recipient chips: a co-parent shows as a compact tappable card, not an inline form. */
.rec-chips { list-style: none; padding: 0; margin: 6px 0 10px; display: flex; flex-wrap: wrap; gap: 8px; }
.rec-chip { display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 8px 14px; background: var(--band); border: 1px solid var(--line); border-radius: 12px;
  cursor: pointer; text-align: left; transition: border-color .12s, background .12s; }
.rec-chip:hover { border-color: var(--brand); background: var(--surface); }
.rec-chip-name { font-weight: 700; color: var(--ink); font-size: .95rem; }
.rec-chip-sub { font-size: .78rem; color: var(--muted); }
.dismiss-quote { font-style: italic; color: var(--muted); margin: 8px 0 4px; }
.card h3 { font-size: 1.04rem; margin: 8px 0 6px; }
.card p { margin: 0 0 10px; color: #4c4c63; font-size: .94rem; }
.card-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.card-foot { display: flex; flex-wrap: wrap; gap: 10px; font-size: .82rem; color: var(--muted); }
.card-foot .due { color: var(--high); font-weight: 600; }

.tag { font-size: .72rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: var(--brand-soft); color: var(--brand-d); }
.tag.deadline { background: var(--peach-soft); color: var(--peach-ink); }
.tag.event { background: #e4eef5; color: var(--low); }
.tag.academic { background: #e1f0ea; color: #2f8f76; }
.tag.career { background: #ece8fb; color: #3D5A47; }
.tag.travel { background: #e1f0ea; color: #2f8f76; }
.card.travel { border-left: 4px solid #2f8f76; }
/* Trip grouping */
.trips { display: grid; gap: 16px; }
.card.trip { border-left: 4px solid #2f8f76; }
.trip-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.trip-head h3 { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.15rem; }
.countdown { flex: none; background: #e1f0ea; color: #2f8f76; font-weight: 700; font-size: .8rem; padding: 3px 10px; border-radius: 20px; white-space: nowrap; }
.trip-items { display: grid; gap: 10px; }
.trip-item { display: flex; gap: 10px; align-items: flex-start; padding-top: 10px; border-top: 1px solid var(--line); }
.trip-item:first-child { border-top: none; padding-top: 0; }
.trip-item .tag { margin-top: 2px; }
.ti-main { display: flex; flex-direction: column; gap: 2px; }
.ti-meta { color: var(--muted); font-size: .85rem; }
.ti-details { color: var(--muted); font-size: .82rem; }
.srctag { font-size: .72rem; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: #eef0f7; color: #5d6b86; }
.prio { font-size: .72rem; font-weight: 700; text-transform: uppercase; margin-left: auto; }
.prio.prio-high { color: var(--high); }
.prio.prio-medium { color: var(--peach-ink); }
.prio.prio-low { color: var(--low); }

/* Legal / prose pages */
.legal .legal-head { margin-bottom: 18px; }
.legal-lead { font-size: 1.06rem; line-height: 1.6; color: #4c4c63; margin-top: 10px; max-width: 60ch; }
.legal-toc { display: flex; flex-wrap: wrap; gap: 8px 14px; padding: 16px 18px; margin: 8px 0 28px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); }
.legal-toc a { font-size: .86rem; color: var(--brand-d); text-decoration: none; font-weight: 600; }
.legal-toc a:hover { text-decoration: underline; }
.prose h2 { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.2rem; margin: 30px 0 8px;
  padding-top: 22px; border-top: 1px solid var(--line); scroll-margin-top: 16px; }
.prose h2:first-of-type { border-top: 0; padding-top: 0; }
.prose p, .prose li { color: #3a3a4a; line-height: 1.65; }
.prose ul { padding-left: 20px; margin: 8px 0; }
.prose li { margin-bottom: 6px; }
.prose a { color: var(--brand-d); }
.prose code { background: var(--brand-soft); color: var(--brand-d); padding: 1px 6px; border-radius: 5px; font-size: .9em; }
.legal-foot { margin-top: 32px; padding-top: 16px; border-top: 1px solid var(--line); color: var(--muted); font-size: .92rem; }
.footer-links { margin-top: 10px; }
.footer-links a { color: inherit; text-decoration: underline; }

/* Forms (settings) */
.form { margin-top: 8px; }
.form label { display: block; margin-bottom: 12px; font-weight: 600; }
.form small { display: block; font-weight: 400; color: var(--muted); margin: 2px 0 6px; }
.form fieldset { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin-bottom: 12px; }
.form legend { font-weight: 700; padding: 0 6px; }
.form .row { display: flex; gap: 12px; }
.form .row label { flex: 1; }
.form .actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
label.inline { display: flex; gap: 10px; align-items: flex-start; font-weight: 400; margin-bottom: 10px; }
label.inline input { width: auto; flex: none; margin-top: 4px; accent-color: var(--brand); }
.card-title { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.2rem; margin: 0 0 4px; }
.card + .card { margin-top: 12px; }

/* Settings: priorities hint, repeatable child/recipient rows */
.fs-hint { display: block; color: var(--muted); font-size: .85rem; margin-bottom: 6px; }
/* Plain-language data-privacy note shown where a child's details are entered. */
.fs-privacy { display: flex; gap: 8px; align-items: flex-start; background: var(--brand-soft);
  color: var(--brand-d); font-size: .82rem; line-height: 1.4; padding: 8px 11px;
  border-radius: 10px; margin: 0 0 10px; }
.fs-privacy svg { width: 15px; height: 15px; flex: none; margin-top: 1px; }
.fs-privacy a { color: var(--brand-d); font-weight: 700; text-decoration: underline; }
/* Add-inbox price note: warmer accent than the privacy note so the cost stands out. */
.fs-price { display: flex; gap: 8px; align-items: flex-start; background: var(--peach-soft);
  color: var(--peach-ink); font-size: .82rem; line-height: 1.4; padding: 8px 11px;
  border-radius: 10px; margin: 0 0 10px; }
.fs-price svg { width: 15px; height: 15px; flex: none; margin-top: 1px; }
.repeat-row { display: flex; gap: 10px; align-items: flex-start; padding: 12px; margin-bottom: 10px; background: var(--band); border: 1px solid var(--line); border-radius: 12px; }
.rr-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; flex: 1; }
.rr-grid .sm { margin: 0; font-size: .78rem; color: var(--muted); }
.rr-grid .sm input { margin-top: 3px; }
.rr-grid label.full { grid-column: 1 / -1; }
/* Collapsible sub-sections inside settings ("Advanced delivery", "Flag/include/skip rules")
   so the page opens short. The summary reads as a quiet toggle, not a heading. */
.fs-accordion { border: 1px solid var(--line); border-radius: 10px; padding: 0 12px; margin: 0 0 10px; background: var(--band); }
.fs-accordion > summary { cursor: pointer; font-weight: 600; font-size: .9rem; padding: 11px 26px 11px 0;
  list-style: none; position: relative; color: var(--ink); }
.fs-accordion > summary::-webkit-details-marker { display: none; }
.fs-accordion > summary::after { content: "+"; position: absolute; right: 2px; top: 9px; font-size: 1.2rem;
  color: var(--brand); font-weight: 400; line-height: 1; }
.fs-accordion[open] > summary::after { content: "\2212"; }
.fs-accordion[open] > summary { border-bottom: 1px solid var(--line); margin-bottom: 12px; }
.fs-accordion > label:last-child, .fs-accordion > .sched-custom:last-child { margin-bottom: 14px; }
/* Sub-headings that group the two halves of the unified "People" section. */
.fs-subhead { font-size: .95rem; font-weight: 700; margin: 4px 0 5px; }
.fs-subhead + .fs-hint { margin-top: 0; }
fieldset > .fs-subhead:not(:first-of-type) { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
/* Delivery schedule: give the cadence + timezone full width so nothing is cramped.
   Use .rr-grid.sched-grid (two classes) so the single column survives the mobile
   `.rr-grid { 1fr 1fr }` rule below — otherwise the schedule collapses into two
   cramped columns on phones (cadence dropdown clipped to "E", text cut off). */
.rr-grid.sched-grid { grid-template-columns: 1fr; gap: 16px; margin-bottom: 6px; }
.sched-grid .sm { min-width: 0; }
.sched-grid .sm select, .sched-grid .sm input, .sched-grid .tz-row {
  margin-top: 5px; width: 100%; max-width: 100%; box-sizing: border-box; }
.sched-custom .sched-grid { grid-template-columns: 1fr 1fr; }
.tz-row { display: flex; gap: 8px; align-items: center; }
.tz-row select { flex: 1 1 auto; min-width: 0; width: auto; }
.tz-row .btn { flex: none; white-space: nowrap; }

/* Custom day/time controls, shown inline under the schedule picker when "Custom" is
   chosen (moved out of the old "Advanced delivery" section so they're findable). */
.sched-nest { margin: 2px 0 12px; padding: 12px 14px; background: var(--band);
  border: 1px solid var(--line); border-radius: 12px; }
.sched-nest > .fs-hint { margin-bottom: 8px; }
.sched-nest .rr-grid.sched-grid { grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 0; }
/* Per-child colour swatch picker */
.swatches { display: flex; gap: 7px; flex-wrap: wrap; padding-top: 5px; }
.swatch { width: 22px; height: 22px; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 0 0 1px var(--line);
  cursor: pointer; padding: 0; transition: transform .1s ease; }
.swatch:hover { transform: scale(1.12); }
.swatch.sel { box-shadow: 0 0 0 2px var(--ink); }
.rec-row { align-items: center; }
.rec-row input, .rec-row select { margin: 0; }
.rr-remove { flex: none; background: transparent; border: 1px solid var(--line); color: var(--muted); border-radius: 8px; padding: 6px 10px; font-size: .82rem; cursor: pointer; }
.rr-remove:hover { color: var(--high); border-color: var(--high); }
.btn.sm { padding: 8px 14px; font-size: .9rem; }
@media (max-width: 640px) {
  .rr-grid { grid-template-columns: 1fr 1fr; }
  .rec-row { flex-wrap: wrap; }
  /* Keep the delivery schedule single-column on phones (both the main grid and the
     custom-schedule fields) so nothing gets clipped. */
  .sched-custom .sched-grid { grid-template-columns: 1fr; }
}

/* Household / linked inboxes */
.inbox-list { list-style: none; padding: 0; margin: 6px 0 8px; }
/* wrap + break so a long account email can never widen the row past the phone screen
   (it pushed the whole settings page to ~413px on a 390px viewport, cutting the boxes
   off at the right edge); the tag just drops to the next line instead. Dividers sit
   BETWEEN rows only, so no stray line hangs under the last one. */
.inbox-row { display: flex; align-items: center; gap: 4px 10px; padding: 5px 0; flex-wrap: wrap; }
.inbox-row + .inbox-row { border-top: 1px solid var(--line); }
.inbox-email { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.inbox-tag { margin-left: auto; }  /* tag right-aligned on the email's line */
.inbox-tag { font-size: .72rem; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: var(--brand-soft); color: var(--brand-d); }
.inbox-row .inline-form { margin-left: auto; }

/* Connections: Email / Calendar / WhatsApp, one row each.
   Grid rather than flex so the icon column, the text and the action stay in three straight
   lines down the list however long a subtitle runs. On a phone the action drops under the text
   and lines up with it, because a button squeezed into a 60px gutter is a button nobody hits. */
.conn-list { list-style: none; padding: 0; margin: 8px 0 0; }
.conn-row { display: grid; grid-template-columns: 28px 1fr auto; align-items: start;
  column-gap: 12px; row-gap: 6px; padding: 12px 0; }
.conn-row + .conn-row { border-top: 1px solid var(--line); }
.conn-ic { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px;
  border-radius: 8px; background: var(--brand-soft); color: var(--brand-d); }
.conn-ic svg { width: 15px; height: 15px; }
.conn-row.off .conn-ic { background: var(--line); color: var(--muted); }
.conn-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.conn-name { font-size: .95rem; }
.conn-sub { font-size: .82rem; color: var(--muted); line-height: 1.45; overflow-wrap: anywhere; }
.conn-act { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.conn-on { display: inline-flex; align-items: center; gap: 4px; font-size: .72rem; font-weight: 700;
  padding: 2px 8px; border-radius: 6px; background: var(--brand-soft); color: var(--brand-d); }
.conn-on svg { width: 11px; height: 11px; }
@media (max-width: 520px) {
  .conn-row { grid-template-columns: 28px 1fr; }
  .conn-act { grid-column: 2; justify-content: flex-start; }
}

/* Agenda: date heading, then its events, nothing for the days between.
   Rows are <details>, so opening one is free of JavaScript and survives with it turned off. */
/* The agenda sits directly inside the card, which has no padding of its own, so the date
   headings were flush against the border while the rows looked inset. Its own gutter. */
.ag { display: flex; flex-direction: column; gap: 20px; padding: 18px; }
.ag-date { font-size: .74rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 10px; }
.ag-date.is-today { color: var(--brand-d); }
.ag-row { border-radius: 14px; background: #fff; border: 1px solid var(--line);
  margin-bottom: 10px; overflow: hidden; }
.ag-sum { display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: 12px; padding: 10px 12px 10px 10px; cursor: pointer; list-style: none; }
.ag-sum::-webkit-details-marker { display: none; }
/* The time chip is FILLED with the child's colour, so a parent reads the row by colour before
   they read a word of it. Unassigned has no colour and keeps the quiet sage tint. */
.ag-when { font-size: .82rem; font-weight: 700; color: var(--brand-d); background: var(--brand-soft);
  padding: 8px 10px; min-width: 74px; text-align: center; border-radius: 9px;
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.ag-row.has-kid .ag-when { background: var(--kid); color: #fff; }
.ag-body-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ag-title { font-weight: 600; font-size: .98rem; line-height: 1.35; overflow-wrap: anywhere; }
.ag-meta { font-size: .8rem; color: var(--muted); }
.ag-meta:empty { display: none; }
.ag-chev { display: flex; color: #B9B2A2; }
.ag-chev svg { width: 15px; height: 15px; }
.ag-row[open] .ag-chev { transform: rotate(90deg); }
.ag-row.is-holiday { background: var(--peach-soft); border-color: #F3D3C8; }
.ag-row.is-holiday .ag-when { background: var(--peach-soft); color: var(--peach-ink); }
.ag-body { padding: 0 14px 14px 14px; border-top: 1px solid var(--line); }
.ag-facts { display: grid; grid-template-columns: auto 1fr; gap: 5px 14px; margin: 12px 0 0;
  font-size: .86rem; }
.ag-facts dt { color: var(--muted); font-weight: 600; }
.ag-facts dd { margin: 0; overflow-wrap: anywhere; }
.ag-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.ag-del { margin-left: auto; }
@media (max-width: 560px) {
  .ag { gap: 16px; padding: 14px; }
  .ag-sum { gap: 10px; padding: 9px 10px 9px 9px; }
  .ag-when { min-width: 66px; font-size: .78rem; padding: 7px 8px; }
  .ag-title { font-size: .94rem; }
}

/* Extra calendars, listed under the Calendar row they belong to. */
.conn-extras { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.conn-extra { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: .82rem; }
.conn-extra-e { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }

/* The WhatsApp steps, revealed under the rows by the row's own button. */
.wa-how { margin-top: 12px; padding: 12px 14px; border-radius: 10px; background: var(--brand-soft); }
.wa-how .fs-steps { margin: 0; padding-left: 18px; line-height: 1.7; }
.wa-how p { margin: 10px 0 0; font-size: .82rem; }

/* PDF review rows */
.rev-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.rev-row { align-items: center; gap: 8px; }
.rev-row input[type=checkbox] { width: auto; flex: none; accent-color: var(--brand); }
.rev-date { flex: 0 0 120px; }
.rev-time { flex: 0 0 80px; }
.rev-cat { flex: 0 0 auto; align-self: center; }
.rev-title { flex: 2; }
.rev-child { flex: 0 0 110px; }
.rev-detail { flex: 2; }
@media (max-width: 640px) { .rev-row { flex-wrap: wrap; } .rev-date, .rev-title, .rev-child, .rev-detail { flex: 1 1 100%; } }

/* Note clarify step ("quick check" after Read my plan) */
.clarify-card { margin-bottom: 16px; }
.clarify-q { padding: 10px 0; border-top: 1px solid var(--line, #eee); }
.clarify-q:first-of-type { border-top: 0; }
.clarify-q p { margin: 0 0 8px; }
.clarify-choices { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-choice { display: inline-flex; cursor: pointer; }
.chip-choice input { position: absolute; opacity: 0; pointer-events: none; }
.chip-choice span { padding: 6px 12px; border: 1px solid var(--line, #ddd); border-radius: 999px;
  font-size: .88rem; background: var(--card, #fff); }
.chip-choice input:checked + span { background: var(--brand, #2F6F9E); border-color: var(--brand, #2F6F9E);
  color: #fff; }
.chip-choice input:focus-visible + span { outline: 2px solid var(--brand, #2F6F9E); outline-offset: 2px; }
/* A coordination item: an open question with the people who could answer it. Laid out as a
   question and its answers rather than as another row of form fields, because that is what it
   is: nobody is holding this yet, and that is the whole content of the item. The chips wrap
   rather than scroll, so a household with six people does not push "Not yet" off the edge. */
.ci-decide { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ci-decide .ci-decide-q { font-size: .85rem; font-weight: 700; color: var(--muted, #666);
  margin-right: 2px; }
/* Out-specifies `.form input { width: 100% }`, which is what laid the group tick out as a
   full-width block and pushed every heading off the right edge of the card. */
.form .ci-decide input[type="radio"] { width: auto; position: absolute; opacity: 0; }
.clarify-summary { margin: 0 0 14px; display: flex; flex-direction: column; gap: 12px; }
.clarify-item { position: relative; display: flex; flex-direction: column; gap: 6px; padding: 10px 34px 10px 0;
  border-top: 1px solid var(--line, #eee); }
.clarify-item:first-child { border-top: 0; padding-top: 0; }
/* Per-item ✕: drop just this one from the note instead of cancelling the whole card. */
.ci-drop { position: absolute; top: 8px; right: 0; width: 28px; height: 28px; padding: 0;
  font: inherit; font-size: 1.05rem; line-height: 1; border: 1px solid var(--line, #ddd);
  border-radius: 999px; background: var(--card, #fff); color: var(--muted, #7a7a70); cursor: pointer; }
.clarify-item:first-child .ci-drop { top: 0; }
.ci-drop:hover { border-color: rgba(201,83,63,.4); color: var(--high); }
.ci-dropped { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: .92rem;
  color: var(--muted, #7a7a70); padding: 4px 0; }
.ci-dropped-title { text-decoration: line-through; }
.ci-undo { font: inherit; font-size: .85rem; font-weight: 700; padding: 4px 12px; cursor: pointer;
  border: 1px solid var(--line, #ddd); border-radius: 999px; background: var(--card, #fff);
  color: var(--brand-d, #3a5a3a); }
.clarify-item.is-dropped > .ci-row,
.clarify-item.is-dropped > .ci-repeat,
.clarify-item.is-dropped > .ci-dup { display: none; }
.clarify-item.is-dropped .ci-drop { display: none; }
/* "already on your plan" — a heads-up, not an error: peach, not red, because saving anyway is
   a perfectly reasonable choice. */
.ci-dup { display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap; margin-top: 8px;
  background: var(--peach-soft); color: var(--peach-ink); border-radius: 10px;
  padding: 8px 11px; font-size: .87rem; line-height: 1.45; }
.ci-dup svg { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 2px; }
.ci-dup-t { flex: 1; min-width: 12ch; }
.ci-dup-go { flex: 0 0 auto; font-weight: 800; font-size: .85rem; text-decoration: none;
  color: #fff; background: var(--peach-ink); border-radius: 999px; padding: 4px 13px; }
.keep-note { margin: 0 0 10px; font-size: .9rem; }
.ci-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.clarify-item input { font: inherit; font-size: .9rem; padding: 6px 9px;
  border: 1px solid var(--line, #ddd); border-radius: 8px; background: var(--card, #fff); }
.ci-title { flex: 2 1 180px; font-weight: 600; }
.ci-child { flex: 1 1 110px; max-width: 150px; }
.ci-date { flex: 0 0 150px; }
.ci-time { flex: 0 0 132px; }  /* typed now, so it must hold "e.g. 4:30pm" */
/* The day and time boxes are wrapped in a label now, so the wrapper is the flex item and has to
   carry the width. Left on the input, the wrapper had no basis and the row collapsed. */
.ci-field.ci-f-date { flex: 0 0 150px; }
.ci-field.ci-f-time { flex: 0 0 132px; }
.ci-detail { flex: 2 1 180px; }
/* "Ends" is a second line, not two more boxes crammed onto the first: on a phone, four date and
   time inputs in one row is unreadable. Most things finish the day they start, so the row is
   hidden until the reader finds an end or the parent asks for one. */
/* Desktop twin of .ci-endadd / .m-fld-more: reveals a field, so it reads as an offer rather
   than a control competing with Save. */
.fld-more { display: block; margin: 2px 0 6px; padding: 0; background: none; border: 0;
  font: inherit; font-size: .86rem; font-weight: 600; color: var(--brand);
  text-decoration: underline; text-align: left; cursor: pointer; }

.ci-endadd { align-self: flex-start; margin: 2px 0 0; padding: 0; background: none; border: 0;
  font: inherit; font-size: .82rem; color: var(--brand); text-decoration: underline; cursor: pointer; }
.ci-ends { margin-top: 6px; }
.ci-endlbl { flex: 0 0 auto; font-size: .8rem; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em; }
.ci-type, .ci-slot { flex: 0 0 130px; font: inherit; font-size: .82rem; font-weight: 700; padding: 6px 8px;
  border: 1px solid var(--line, #ddd); border-radius: 8px; background: var(--brand-soft, #eef3ee);
  color: var(--brand-d, #3a5a3a); text-transform: none; cursor: pointer; }
.ci-repeat { display: inline-flex; align-items: center; gap: 9px; font-size: .95rem;
  font-weight: 600; color: var(--brand-d, #3a5a3a); cursor: pointer; padding: 8px 10px;
  margin-top: 2px; background: var(--brand-soft, #eef3ee); border-radius: 8px; }
.ci-repeat input { width: 18px; height: 18px; margin: 0; accent-color: var(--brand, #2F6F9E); cursor: pointer; }
/* Custom type dropdown (progressive enhancement of select.ci-type) that always opens DOWN,
   so mobile browsers never flip the menu upward over the heading. */
.kwdd { position: relative; flex: 0 0 132px; }
.kwdd-btn { width: 100%; font: inherit; font-size: .82rem; font-weight: 700; text-align: left;
  padding: 7px 26px 7px 10px; border: 1px solid var(--line, #ddd); border-radius: 8px;
  background: var(--brand-soft, #eef3ee); color: var(--brand-d, #3a5a3a); cursor: pointer; position: relative; }
.kwdd-btn::after { content: ""; position: absolute; right: 10px; top: 50%; width: 7px; height: 7px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-70%) rotate(45deg); opacity: .65; }
.kwdd-menu { position: absolute; top: calc(100% + 4px); left: 0; z-index: 60; min-width: 100%;
  background: var(--card, #fff); border: 1px solid var(--line, #ddd); border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0,0,0,.14); overflow: hidden; }
.kwdd-opt { display: block; width: 100%; text-align: left; font: inherit; font-size: .88rem;
  padding: 10px 14px; background: none; border: 0; cursor: pointer; white-space: nowrap; }
.kwdd-opt[aria-selected="true"] { font-weight: 700; color: var(--brand-d, #3a5a3a); }
.kwdd-opt:hover { background: var(--brand-soft, #eef3ee); }
@media (max-width: 640px) {
  .ci-title, .ci-detail { flex: 1 1 100%; }
  .ci-child { max-width: none; }
  /* Native date/time inputs don't shrink; let them flex so nothing pokes out of the card. */
  .ci-date { flex: 1 1 140px; min-width: 0; }
  .ci-time { flex: 1 1 120px; min-width: 0; }
  /* iOS Safari auto-zooms focused inputs under 16px; keep ours at 16px on phones. */
  .clarify-item input, .sched-row input { font-size: 16px; }
}

/* Per-section save rows on the Settings page */
.fieldset-save { margin-top: 10px; justify-content: flex-end; }

/* Senders/domains box nested under the "Choose senders" radio */
.senders-nest { margin: 4px 0 6px 30px; padding-left: 12px; border-left: 2px solid var(--line, #e5e0d6); }
@media (max-width: 560px) { .senders-nest { margin-left: 16px; } }

/* Shared schedule page (login-free /plan/<token>) */
.plan-agenda { display: flex; flex-direction: column; gap: 6px; }
.plan-daylabel { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.05rem;
  color: var(--ink); margin: 16px 0 4px; border-top: 3px solid var(--line-strong); padding-top: 12px; }
.plan-agenda > .plan-daylabel:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.plan-day { display: flex; flex-direction: column; gap: 8px; }
.plan-item { border: 1px solid var(--line); border-radius: 12px; padding: 10px 13px; background: var(--surface); }
.plan-item.is-done { opacity: .55; }
.plan-item.is-done .plan-item-title { text-decoration: line-through; }
.plan-item-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 3px; }
.plan-item-title { font-weight: 700; font-size: .98rem; }
.plan-item-sub { color: var(--muted); font-size: .86rem; margin-top: 2px; }

/* Missing-schedule nudge + manual dates modal */
.sched-done { opacity: .85; }
.sched-rows { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; }
.sched-row { display: flex; gap: 8px; flex-wrap: wrap; }
.sched-row input { font: inherit; font-size: .9rem; padding: 6px 9px; flex: 1 1 120px; min-width: 0;
  border: 1px solid var(--line, #ddd); border-radius: 8px; background: var(--card, #fff); }

/* Someday "Add date & details" modal: a compact two-column field grid. */
.sd2-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 12px 0 4px; }
.sd2-field { display: flex; flex-direction: column; gap: 4px; font-size: .82rem; font-weight: 600; color: var(--muted); }
.sd2-field small { font-weight: 400; }
.sd2-field.sd2-wide { grid-column: 1 / -1; }
.sd2-field input, .sd2-field select { font: inherit; font-size: .9rem; font-weight: 400; padding: 7px 9px;
  border: 1px solid var(--line, #ddd); border-radius: 8px; background: var(--card, #fff); color: inherit; width: 100%; }

/* Add-events box (dashboard rail): one card — switch, content area and button all
   inside, with identical geometry in both modes so toggling never reflows the page. */
.addbox { display: flex; flex-direction: column; gap: 10px; min-width: 0;
  border: 1px solid var(--line, #ddd); border-radius: 14px; background: var(--surface, #fff);
  padding: 12px; box-shadow: 0 1px 2px rgba(31,31,58,.04); }
/* "Coming up this week" row: the updated stamp sits inline beside the heading. */
.cu-updated { font-size: .8rem; font-weight: 600; color: var(--muted); text-align: right; }

/* One compact filter bar: category pills + kid pills together, counts inline. */
.cu-filterbar { display: flex; flex-direction: column; gap: 8px; margin: 0 0 14px; }
/* Two calm rows: category filters, then people, instead of one dense wrapped block. */
.cu-cats, .cu-people { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.cu-people { padding-top: 2px; }
.tab-n { font-weight: 700; font-size: .92em; opacity: .6; margin-left: 5px; }
.cu-tab.active .tab-n, .kid-tab.active .tab-n { opacity: .95; }

/* Skeleton event cards while the first scan runs. */
.skel-list { display: flex; flex-direction: column; gap: 10px; margin-top: 26px; text-align: left; }
.skel-card { background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  padding: 14px; display: flex; flex-direction: column; gap: 8px; }
.skel-line { display: block; height: 11px; border-radius: 6px;
  background: linear-gradient(90deg, #ece7db 25%, #f7f3ea 42%, #ece7db 60%);
  background-size: 200% 100%; animation: skel 1.3s linear infinite; }
.skel-line.w35 { width: 35%; } .skel-line.w50 { width: 50%; } .skel-line.w70 { width: 70%; }
@keyframes skel { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skel-line { animation: none; } }
.ab-switch { display: flex; gap: 4px; padding: 3px; border-radius: 10px;
  background: var(--brand-soft, #eef3f7); }
.ab-tab { flex: 1; font: inherit; font-size: .84rem; font-weight: 700; padding: 6px 10px;
  cursor: pointer; border: 0; border-radius: 8px; background: transparent;
  color: var(--muted, #667); text-align: center; }
.ab-tab.active { background: var(--surface, #fff); color: var(--ink, #1f1f3a);
  box-shadow: 0 1px 2px rgba(31,31,58,.12); }
.ab-tab:focus-visible { outline: 2px solid var(--brand, #2F6F9E); outline-offset: 2px; }
/* The pane is HARD-PINNED to one height, so the card is pixel-identical in both
   modes no matter what the contents do. */
.ab-pane { height: 200px; flex: none; display: flex; min-width: 0; }
.ab-pane[hidden] { display: none; }
.ab-form { flex: 1; display: flex; flex-direction: column; gap: 10px; min-width: 0; }
/* The content area fills whatever the footer doesn't use — same in both modes. */
.ab-area { flex: 1 1 auto; min-height: 0; box-sizing: border-box; width: 100%; }
textarea.ab-area { resize: none; font: inherit; font-size: .9rem; line-height: 1.45;
  padding: 10px 12px; border: 1px solid var(--line, #ddd); border-radius: 10px;
  background: var(--card, #fff);
  scrollbar-width: thin; scrollbar-color: transparent transparent; }
/* Scrollbar only materialises while hovering/typing; invisible at rest. */
textarea.ab-area:hover, textarea.ab-area:focus { scrollbar-color: rgba(31,31,58,.25) transparent; }
textarea.ab-area::-webkit-scrollbar { width: 8px; }
textarea.ab-area::-webkit-scrollbar-track { background: transparent; }
textarea.ab-area::-webkit-scrollbar-thumb { background: transparent; border-radius: 8px; }
textarea.ab-area:hover::-webkit-scrollbar-thumb,
textarea.ab-area:focus::-webkit-scrollbar-thumb { background: rgba(31,31,58,.22); }
/* Compact the dropzone innards so they fit the shared pane height.
   (Two-class selector so it beats the base .dropzone min-height further down.) */
.ab-area.dropzone { padding: 10px 12px; gap: 6px; min-height: 0; overflow: hidden; }
.addbox .dz-icon { width: 34px; height: 34px; }
.addbox .dz-icon .ico { width: 17px; height: 17px; }
.addbox .dz-text { gap: 1px; }
.addbox .dz-text strong { font-size: .88rem; }
.addbox .dz-sub { font-size: .76rem; }
/* Muted browse affordance inside the dropzone (clicks fall through to the zone). */
.dz-browse { margin-top: 5px; font-size: .78rem; font-weight: 700; color: var(--muted, #667);
  border: 1px dashed var(--line, #ccc); border-radius: 999px; padding: 3px 12px; }
.dropzone:hover .dz-browse { border-color: var(--brand, #2F6F9E); color: var(--brand-d, #245a80); }
/* Once files are picked, show the name(s) instead of the sub-line so nothing overflows. */
.dropzone.has-file .dz-sub { display: none; }
.dropzone.has-file { border-style: solid; border-color: var(--brand, #2F6F9E); }
/* The footer row: hint left, one-line action button right — identical in both modes. */
.ab-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  min-height: 36px; }
.ab-foot .btn { white-space: nowrap; flex: none; }
.ab-hint { color: var(--muted, #667); font-size: .78rem; line-height: 1.3; flex: 1 1 auto; min-width: 0; }
.ab-hint-link { font: inherit; font-size: .78rem; color: var(--muted, #667); background: none;
  border: 0; padding: 0; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
.ab-hint-link:hover { color: var(--brand-d, #245a80); }
.ab-hint-link .ico-xs { width: 14px; height: 14px; }
@media (max-width: 640px) { textarea.ab-area { font-size: 16px; } }  /* no iOS zoom-on-focus */

/* Coming up this week (DailyNest-style single list) */
.cu-head { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 2px 10px; margin: 0 0 10px; }
.cu-head h2 { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.3rem; margin: 0; }
.cu-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.cu-tab { display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; font-weight: 600; padding: 6px 14px; border-radius: 20px; border: 1px solid var(--line); background: var(--surface); color: var(--muted); cursor: pointer; transition: border-color .15s ease, color .15s ease, background .15s ease; }
.cu-tab svg { width: 14px; height: 14px; }
.cu-tab:hover { border-color: var(--brand); color: var(--brand-d); }
.cu-tab.active { background: var(--brand); color: #fff; border-color: var(--brand); }
/* Per-kid filter chips: a lighter, dashed row under the category tabs. */
.cu-kidfilters { display: flex; gap: 8px; flex-wrap: wrap; margin: -4px 0 16px; }
.kid-tab { display: inline-flex; align-items: center; gap: 6px; font-size: .82rem; font-weight: 600; padding: 5px 13px; border-radius: 20px; border: 1px dashed var(--line); background: transparent; color: var(--muted); cursor: pointer; transition: color .15s ease, background .15s ease, border-color .15s ease; --kid: var(--brand); }
.kid-tab svg { width: 13px; height: 13px; }
.kid-tab:hover { color: var(--ink); border-color: var(--kid); }
.kid-tab.active { background: var(--kid); border-color: var(--kid); border-style: solid; color: #fff; }
.kid-tab.kid-add { color: var(--brand-d); border-style: dotted; }
.kid-tab.kid-add:hover { background: var(--brand-soft); }
.kid-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--kid, var(--muted)); flex: none; }
.kid-dot-none { background: transparent; border: 1.5px solid var(--line); }
.kid-tab.active .kid-dot { background: #fff; }
.kid-tab.active .kid-dot-none { border-color: rgba(255,255,255,.6); }
.kid-count { font-size: .72rem; font-weight: 800; line-height: 1; padding: 2px 6px; border-radius: 999px;
  background: var(--band); color: var(--muted); }
.kid-tab.active .kid-count { background: rgba(255,255,255,.25); color: #fff; }
/* Tappable suggestion chips under the priority fields. */
.chip-suggest { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.sg-chip { font-size: .78rem; font-weight: 600; color: var(--brand-d); background: var(--brand-soft);
  border: 1px solid #DCE7DC; border-radius: 999px; padding: 4px 11px; cursor: pointer; transition: opacity .15s; }
.sg-chip:hover { filter: brightness(.98); }
.sg-chip.used { opacity: .45; }
/* Detected-kids suggestion banner: names spotted in the inbox, one tap to add. */
.kid-suggest { background: var(--brand-soft); border: 1px solid #DCE7DC; border-radius: 16px;
  padding: 14px 16px; margin: 0 0 18px; }
.kid-suggest-head { display: flex; gap: 8px; align-items: center; color: var(--brand-d);
  font-size: .9rem; font-weight: 700; margin-bottom: 10px; }
.kid-suggest-head svg { width: 16px; height: 16px; flex: none; }
.kid-suggest-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.kid-suggest-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 999px; padding: 4px 6px 4px 14px; }
.kid-suggest-chip .inline-form { margin: 0; display: inline-flex; }
.ks-name { font-weight: 700; font-size: .9rem; color: var(--ink); }
.ks-count { font-size: .72rem; font-weight: 700; color: var(--muted); background: var(--band);
  border-radius: 999px; padding: 1px 7px; }
.ks-add { display: inline-flex; align-items: center; gap: 4px; background: var(--brand); color: #fff;
  border: 0; border-radius: 999px; padding: 5px 12px; font-size: .82rem; font-weight: 700; cursor: pointer; }
.ks-add svg { width: 12px; height: 12px; }
.ks-add:hover { filter: brightness(1.05); }
.ks-dismiss { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px;
  background: transparent; border: 0; border-radius: 50%; color: var(--muted); cursor: pointer; }
.ks-dismiss svg { width: 14px; height: 14px; }
.ks-dismiss:hover { background: var(--band); color: var(--ink); }
.cu-list { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow); overflow: hidden; }
.cu-item { display: flex; gap: 16px; padding: 16px 18px; border-top: 1px solid var(--line); }
.cu-item:first-child { border-top: 0; }
.cu-item.flagged { background: #faf9ff; }
.cu-when { flex: 0 0 118px; display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.cu-day { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; font-weight: 700; color: #6b6757; }
.cu-time { display: block; font-size: .8rem; color: var(--brand-d); font-weight: 600; margin-top: 2px; }
.cu-body { flex: 1; min-width: 0; }
.cu-tags { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }
.todo-tag { font-size: .66rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: var(--high); color: #fff; }
.confirmed-tag { display: inline-flex; align-items: center; gap: 4px; font-size: .66rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: var(--brand-soft); color: var(--brand-d); }
.confirmed-tag svg { width: 11px; height: 11px; }
.rsvp-tag { display: inline-flex; align-items: center; gap: 4px; font-size: .66rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700; padding: 2px 8px; border-radius: 6px; background: var(--peach-soft); color: var(--peach-ink); }
.rsvp-tag svg { width: 11px; height: 11px; }
.cu-body h3 { font-size: 1.02rem; margin: 2px 0 4px; }
.cu-body p { color: #4c4c63; font-size: .92rem; margin: 0 0 8px; }
/* One consistent secondary-text style for description + price, so the card doesn't
   emphasise everything at once. The amount stays slightly bolder to remain scannable. */
.cu-amount { color: var(--muted); font-weight: 600; font-size: .92rem; margin: 0 0 8px; }
.cu-actions { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.link-action { display: inline-flex; align-items: center; gap: 5px; background: none; border: 0; padding: 0; cursor: pointer; font-size: .85rem; font-weight: 600; color: var(--brand-d); transition: color .15s ease; }
.link-action .ico-xs { opacity: .8; }
.link-action:hover { text-decoration: underline; }
.link-action.danger { color: var(--muted); }
.link-action.danger:hover { color: var(--high); }
/* Per-card "⋯" overflow menu: primary actions stay inline, the rest live here. */
.cu-more-wrap { position: relative; display: inline-flex; margin-left: auto; }
.cu-more { padding: 4px 6px; border-radius: 6px; color: var(--muted); }
.cu-more:hover { color: var(--brand-d); text-decoration: none; background: var(--band); }
.cu-more svg { width: 18px; height: 18px; }
/* Fixed (viewport-anchored) so it is never clipped by .cu-agenda's overflow:hidden;
   JS sets top/right from the button's position on open. */
.cu-menu { position: fixed; z-index: 60; min-width: 182px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow);
  padding: 6px; display: flex; flex-direction: column; gap: 2px; }
.cu-menu .link-action { width: 100%; justify-content: flex-start; padding: 9px 11px; border-radius: 8px; }
.cu-menu .link-action:hover { background: var(--band); text-decoration: none; }
/* Lighter category label (no pill) + flagged as a single gold icon, not a tag. */
.cu-cat { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); }
/* Family whereabouts: an 'away' information card. Location sits softly beside the trip title,
   and the paste box carries a one-line hint about the auto drop-off. */
.cu-loc { font-weight: 600; color: var(--muted); font-size: .82em; }
.ab-away-hint { display: flex; gap: 6px; align-items: flex-start; font-size: 12.5px; color: var(--muted);
  margin: 8px 2px 0; line-height: 1.4; }
.ab-away-hint svg { width: 13px; height: 13px; flex: 0 0 auto; margin-top: 2px; }
.away-share svg { width: 13px; height: 13px; }
.cu-item[data-private="1"] .away-share { color: var(--muted); }
.cu-cat-todo { color: var(--high); }
.cu-flag { display: inline-flex; align-items: center; color: var(--gold); }
.cu-flag svg { width: 14px; height: 14px; }
.cu-lock { display: inline-flex; align-items: center; color: var(--faint); }
.cu-lock svg, .cu-lock .ico { width: 13px; height: 13px; }

/* ---------- Coming up: agenda grouped by date ---------- */
.cu-agenda { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow); overflow: hidden; }
.cu-group { display: flex; border-top: 3px solid var(--line-strong); }
.cu-group:first-child { border-top: 0; }
/* Date tile / rail: one per day, vertically centred within its (possibly tall) row */
.cu-date { flex: 0 0 86px; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; padding: 16px 8px; background: var(--band); border-right: 1px solid var(--line); text-align: center; }
.cu-date-mon { font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--brand-d); }
.cu-date-num { font-family: "Fraunces", Georgia, serif; font-size: 1.7rem; font-weight: 600; line-height: 1.05; color: var(--ink); }
.cu-date-dow { font-size: .7rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
/* "Today"/"Tomorrow" in the weekday slot, title-case (narrower than caps so the long
   "Tomorrow" can't stretch the tile) and accented so they read as relative. */
.cu-date-dow.cu-date-rel { color: var(--brand-d); font-weight: 700; text-transform: none; letter-spacing: 0; font-size: .76rem; }
/* Highlight the current day in peach to signal urgency (matches today's cards) */
.cu-date.is-today { background: var(--peach-soft); }
.cu-date.is-today .cu-date-num { color: var(--peach-ink); }
.cu-date.is-today .cu-date-rel { color: var(--peach-ink); }
/* Undated items live in their own section below the dated agenda, not in the date rail */
.cu-someday-wrap { margin-top: 22px; }
.cu-someday-head { display: flex; align-items: baseline; gap: 9px; margin: 0 2px 10px; }
/* Collapsible lower-priority sections (Someday, Travel): the summary is a quiet clickable
   header with a chevron that rotates open; no default disclosure triangle. */
.cu-collapse > summary { cursor: pointer; list-style: none; }
.cu-collapse > summary::-webkit-details-marker { display: none; }
.cu-collapse > summary::before { content: ""; flex: none; width: 7px; height: 7px; margin-right: 2px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(-45deg); transition: transform .15s ease; }
.cu-collapse[open] > summary::before { transform: rotate(45deg); }
.cu-collapse > summary.cu-someday-head { align-items: center; }
.cu-collapse > summary.cu-section { display: flex; align-items: center; gap: 8px; }
.cu-collapse > summary:hover { color: var(--brand-d); }
.cu-someday-head span { font-family: "Fraunces", Georgia, serif; font-size: 1.2rem; font-weight: 600; color: var(--ink); }
.cu-someday-head small { font-size: .82rem; color: var(--muted); font-weight: 600; }
.cu-group-items { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* Row content (block); category shown by a small understated icon before the title */
/* Category is shown by a colour-coded left border (inset bar), not a pill on every card. */
.cu-agenda .cu-item { display: block; padding: 11px 14px; border-top: 1px solid var(--line);
  --cat: #8a8f98; box-shadow: inset 3px 0 0 var(--cat); }
.cu-agenda .cu-item:first-child { border-top: 0; }
.cu-agenda .cu-item.cat-academics, .cu-agenda .cu-item.cat-school_admin { --cat: var(--brand); }
.cu-agenda .cu-item.cat-activities, .cu-agenda .cu-item.cat-travel { --cat: #2f6f9e; }
.cu-agenda .cu-item.cat-appointments { --cat: var(--appt); }
.cu-agenda .cu-item.cat-money, .cu-agenda .cu-item.cat-bills { --cat: var(--peach-ink); }
.cu-agenda .cu-item.cat-health { --cat: #2f8f76; }
.cu-agenda .cu-item.cat-personal, .cu-agenda .cu-item.cat-logistics { --cat: #8a8f98; }
.cu-agenda .cu-item.cat-todo { --cat: var(--high); }
.cu-agenda .cu-item.cat-info { --cat: #8a8f98; }
/* Edit-item modal fields: label stacked above a full-width control. */
.fld { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; text-align: left; }
.fld > span { font-size: .8rem; font-weight: 600; color: var(--muted, #6b7280); }
.fld input, .fld select { font: inherit; font-size: 16px; padding: 8px 10px;
  border: 1px solid var(--line, #ddd); border-radius: 8px; background: var(--card, #fff); width: 100%; }
.fld-row { display: flex; gap: 10px; }
.fld-row .fld { flex: 1 1 0; min-width: 0; }
.cu-agenda .cu-item.flagged { background: #fffdf4; }
/* Recurring add row on Settings: let the inputs wrap on narrow screens. */
.rec-row { flex-wrap: wrap; gap: 8px; align-items: center; }
.rec-row input, .rec-row select { flex: 1 1 130px; min-width: 0; }
.rec-row .btn { flex: 0 0 auto; }
/* "What should we call you?" onboarding card. */
.namecard { margin: 6px 0 14px; }
.namecard-text { display: flex; flex-direction: column; gap: 2px; margin-bottom: 10px; }
.namecard-text strong { font-size: 1.02rem; }
.namecard-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.namecard-row input { flex: 1 1 200px; min-width: 0; font: inherit; font-size: 16px; padding: 8px 11px;
  border: 1px solid var(--line, #ddd); border-radius: 8px; background: var(--card, #fff); }
.namecard-row .btn { flex: 0 0 auto; }
/* First-login walkthrough tour. */
.tour-card { max-width: 420px; text-align: center; position: relative; }
.tour-skip { position: absolute; top: 12px; right: 14px; background: none; border: 0;
  color: var(--muted, #6b7280); font: inherit; font-size: .85rem; cursor: pointer; }
.tour-ico { margin: 6px auto 14px; width: 58px; height: 58px; display: flex; align-items: center;
  justify-content: center; border-radius: 16px; background: var(--brand-soft, #eef3ee); color: var(--brand-d, #3a5a3a); }
.tour-ico svg { width: 28px; height: 28px; }
.tour-slide h3 { margin: 0 0 8px; font-family: "Fraunces", serif; font-weight: 600; font-size: 1.2rem; }
.tour-slide p { color: var(--muted, #6b7280); line-height: 1.55; margin: 0; }
.tour-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 22px; }
.tour-dots { display: flex; gap: 6px; }
.tour-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--line, #ddd); }
.tour-dot.on { background: var(--brand, #2F6F9E); }
.tour-nav { display: flex; gap: 8px; }
/* Spotlight guided tour: a dim overlay with a "hole" cut around the real control, plus a floating
   tip. .tour-spot captures clicks so the page underneath can't be operated mid-tour; the dimming
   comes from the hole's huge box-shadow (a bright cut-out over the target), and .is-plain dims the
   whole screen for the intro/outro steps that have no anchor. */
.tour-spot { position: fixed; inset: 0; z-index: 4000; }
.tour-spot.is-plain { background: rgba(20, 25, 18, .66); }
.tour-hole { position: fixed; border-radius: 12px; pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(20, 25, 18, .66), 0 0 0 2px rgba(255, 255, 255, .85) inset;
  transition: top .22s ease, left .22s ease, width .22s ease, height .22s ease; }
.tour-tip { position: fixed; z-index: 4001; width: min(320px, calc(100vw - 32px));
  background: var(--card, #fff); color: var(--ink, #23291f); border-radius: 14px;
  padding: 18px 18px 14px; box-shadow: 0 18px 50px -12px rgba(0, 0, 0, .45);
  border: 1px solid var(--line, #e6e0d4); }
.tour-tip h3 { margin: 2px 26px 6px 0; font-family: "Fraunces", serif; font-weight: 600; font-size: 1.12rem; }
.tour-tip p { margin: 0; color: var(--muted, #5E6B5E); line-height: 1.5; font-size: .95rem; }
@media (prefers-reduced-motion: reduce) { .tour-hole { transition: none; } }
/* Today = urgent: warm peach card with a peach accent bar (wins over category + .flagged) */
.cu-agenda .cu-item.is-today { background: #fff5ef; box-shadow: inset 3px 0 0 var(--peach); }
/* The category label picks up the card's category colour: the text carries the coding,
   not a filled card background. */
.cu-agenda .cu-item .cu-cat { color: var(--cat); }
/* Card top row: people on the left, category + status badges pushed to the top-right */
.cu-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.cu-top-left { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cu-badges { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.cat-badge { display: inline-flex; align-items: center; gap: 5px; font-size: .68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; padding: 3px 9px; border-radius: 7px; background: var(--band); color: var(--muted); }
.cat-badge .ico-cat { width: 13px; height: 13px; }
.cat-badge.cat-academics, .cat-badge.cat-school_admin { background: var(--brand-soft); color: var(--brand-d); }
.cat-badge.cat-activities { background: #e4eef5; color: #2f6f9e; }
.cat-badge.cat-appointments { background: var(--appt-soft); color: var(--appt); }
.cat-badge.cat-money { background: var(--peach-soft); color: var(--peach-ink); }
.cat-badge.cat-health { background: #e1f0ea; color: #2f8f76; }
.cat-badge.cat-personal { background: #eceef2; color: #6b7280; }
/* Meta row: time chip · category name · status badges · people (pushed right) */
.cu-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 3px; }
.cu-top .cu-time { display: inline-flex; align-items: center; gap: 4px; font-size: .78rem; font-weight: 700;
  color: #8a5a23; background: #f6ecdd; padding: 2px 8px; border-radius: 6px; }
.cu-cat-name { font-size: .82rem; font-weight: 700; color: var(--muted); }
/* Who it's FOR (child avatar) + who's GOT IT (assignees), grouped together on the right */
.cu-people { display: inline-flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-left: auto; }
.who-chip { display: inline-flex; align-items: center; gap: 6px; font-size: .78rem; font-weight: 700;
  color: var(--ink); background: #fff; border: 1px solid var(--line); padding: 2px 11px 2px 3px; border-radius: 999px; }
.who-chip::before { content: attr(data-initial); display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%; background: var(--peach-soft); color: var(--peach-ink); font-size: .68rem; }
/* Understated category icon, just left of the title */
.cu-titleico { display: inline-flex; vertical-align: -3px; margin-right: 8px; }
.cu-titleico .ico-cat { width: 17px; height: 17px; display: block; }
.cu-titleico.cat-academics, .cu-titleico.cat-school_admin { color: var(--brand); }
.cu-titleico.cat-activities { color: #2f6f9e; }
.cu-titleico.cat-appointments { color: var(--appt); }
.cu-titleico.cat-money { color: var(--peach-ink); }
.cu-titleico.cat-health { color: #2f8f76; }
.cu-titleico.cat-personal { color: #9aa1ad; }
.cu-agenda .cu-item h3 { font-size: 1rem; margin: 0 0 3px; }
.cu-agenda .cu-item p { color: var(--muted); font-size: .88rem; line-height: 1.4; margin: 0 0 6px; }
.assignee { display: inline-flex; align-items: center; gap: 4px; }
.assignee .ico-xs { opacity: .8; }
/* "Who's got it?" modal: current assignees as removable chips + an add field */
.assign-chips { display: flex; flex-wrap: wrap; gap: 7px; margin: 12px 0 10px; min-height: 26px; align-items: center; }
.assign-chip { display: inline-flex; align-items: center; gap: 7px; font-size: .85rem; font-weight: 700;
  color: var(--brand-d); background: var(--brand-soft); padding: 4px 5px 4px 12px; border-radius: 999px; }
.assign-chip-x { border: 0; background: rgba(61,90,71,.16); color: var(--brand-d); width: 18px; height: 18px;
  border-radius: 50%; cursor: pointer; line-height: 1; font-size: .95rem; display: inline-flex;
  align-items: center; justify-content: center; padding: 0; }
.assign-chip-x:hover { background: var(--brand-d); color: #fff; }
.assign-add { display: flex; gap: 8px; }
.assign-add input { flex: 1; }

/* ---------- Inline upload dropzone (rectangle, right of the header) ---------- */
.dropzone-form { margin: 0; }
/* Dropzone fills the right grid column (= sidebar width), so it sits right above the rail. */
.hero-row .dropzone-form { display: flex; }
.dropzone { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 10px; padding: 22px 20px; min-height: 160px; cursor: pointer;
  background: var(--surface); border: 1.5px dashed #d8cfbb; border-radius: 14px;
  transition: border-color .15s ease, background .15s ease; }
.dropzone:hover { border-color: var(--brand); background: #fbfcfb; }
.dropzone:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.dropzone.is-over { border-color: var(--brand); border-style: solid; background: var(--brand-soft); }
.dropzone.is-loading { opacity: .65; pointer-events: none; }
.dz-icon { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 12px; background: var(--brand-soft); color: var(--brand-d); }
.dz-icon .ico { width: 21px; height: 21px; }
.dz-text { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 0; }
.dz-text strong { font-size: .96rem; color: var(--ink); line-height: 1.25; }
.dz-sub { font-size: .83rem; color: var(--muted); }
.dz-file { font-size: .9rem; font-weight: 700; color: var(--brand-d); }
.dz-help { display: inline-flex; align-items: center; gap: 6px; margin-top: 2px;
  background: none; border: 0; cursor: pointer; font-size: .84rem; font-weight: 700; color: var(--brand-d);
  padding: 6px 10px; border-radius: 9px; }
.dz-help:hover { background: var(--brand-soft); }
.dz-help .ico-xs { width: 15px; height: 15px; }
@media (max-width: 820px) {
  .hero-row { flex-direction: column; align-items: stretch; }
  .hero-row .dropzone-form { flex: none; }
}
@media (max-width: 560px) {
  .cu-date { flex-basis: 62px; padding: 13px 5px; }
  .cu-date-num { font-size: 1.4rem; }
  .cu-people { margin-left: 0; }
}

/* Scan-scope chooser icon + landing micro lock */
.option-ico { flex: none; margin-top: 1px; color: var(--brand); }
.micro svg { width: 14px; height: 14px; vertical-align: -2px; margin-right: 6px; color: var(--brand); }
.wa-loc { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); }
.wa-loc .ico-xs { opacity: .8; }
.wa-time.date-badge { min-width: 0; align-self: flex-start; }
.cu-edit { margin-top: 12px; padding: 14px; background: var(--band); border: 1px solid var(--line); border-radius: 12px; }
.cu-edit .sm { display: block; font-size: .78rem; color: var(--muted); margin-bottom: 8px; }
.cu-edit-row { display: flex; gap: 10px; }
.cu-section { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.2rem; margin: 26px 0 12px; }
.trip-line { padding: 6px 0; font-size: .92rem; }
.trip-line .muted { font-size: .85rem; }
@media (max-width: 560px) {
  .cu-item { flex-direction: column; gap: 6px; }
  .cu-when { flex: none; flex-direction: row; gap: 8px; align-items: center; }
  .cu-edit-row { flex-direction: column; gap: 0; }
}

/* Family timeline */
/* ---------- Timeline ---------- */
/* Stat cards sit to the right of the header (like the dashboard's dropzone) */
.tl-stats { display: flex; gap: 12px; flex: 0 0 auto; align-self: center; }
.tl-stat { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 14px 20px;
  box-shadow: var(--shadow); text-align: center; min-width: 88px; cursor: pointer; font: inherit;
  transition: border-color .15s ease, box-shadow .15s ease; }
.tl-stat:hover { border-color: var(--brand); }
.tl-stat.active { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-soft); }
/* Timeline filter bar: search + per-kid pills. */
.tl-filters { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 4px 0 18px; }
.tl-filters .tl-search-wrap { flex: 1 1 240px; }
.tl-filters .cu-kidfilters { margin: 0; }
.tl-num { display: block; font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.9rem; line-height: 1; color: var(--brand-d); }
.tl-lbl { color: var(--muted); font-size: .8rem; font-weight: 600; }
.tl-stat.is-events .tl-num { color: #2f6f9e; }
.tl-stat.is-actions .tl-num { color: var(--high); }
/* Search + child filter tabs */
.tl-controls { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 4px 0 16px; }
.tl-search-wrap { position: relative; display: flex; align-items: center; flex: 1 1 220px; max-width: 340px; }
.tl-search-wrap .ico-xs { position: absolute; left: 12px; color: var(--muted); pointer-events: none; }
.tl-search { width: 100%; padding: 9px 14px 9px 34px; border: 1px solid var(--line); border-radius: 10px;
  font: inherit; font-size: .92rem; background: var(--surface); color: var(--ink); }
.tl-search:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-soft); }
.tl-tabs { margin-bottom: 0; }
/* Empty + recent-scans */
.tl-empty-ico { display: inline-flex; color: var(--brand); margin-bottom: 6px; }
.tl-empty-ico .ico { width: 30px; height: 30px; }
.tl-section { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.3rem; margin: 30px 0 12px; }
.tl-runs { list-style: none; padding: 0; margin: 0; background: var(--surface); border: 1px solid var(--line);
  border-radius: 14px; box-shadow: var(--shadow); overflow: hidden; }
.tl-runs li { display: flex; justify-content: space-between; align-items: center; padding: 12px 18px;
  border-top: 1px solid var(--line); font-size: .92rem; }
.tl-runs li:first-child { border-top: 0; }
.tl-run-at { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; color: var(--ink); }
.tl-run-at .ico { width: 16px; height: 16px; color: var(--brand); }
.tl-run-moments { color: var(--muted); font-weight: 600; }
@media (max-width: 820px) { .tl-stats { align-self: stretch; } }
@media (max-width: 560px) { .tl-stats { width: 100%; } .tl-stat { flex: 1; min-width: 0; } }

/* Timeline = vertical month-grouped spine (deliberately distinct from the dashboard's day cards) */
.tl-timeline { margin-top: 2px; }
.tl-month-head { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.5rem; color: var(--ink); margin: 22px 0 14px; }
.tl-month:first-child .tl-month-head { margin-top: 4px; }
.tl-spine { position: relative; }
.tl-spine::before { content: ''; position: absolute; left: 7px; top: 8px; bottom: 12px; width: 2px; background: var(--line); }
.tl-node { position: relative; padding: 0 0 22px 34px; }
.tl-node::before { content: ''; position: absolute; left: 1px; top: 3px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--surface); border: 2.5px solid var(--brand); box-sizing: border-box; }
.tl-node.is-today::before { background: var(--peach); border-color: var(--peach-ink); }
.tl-node-date { font-weight: 700; font-size: .92rem; color: var(--ink); margin-bottom: 9px; }
.tl-rel { color: var(--brand-d); }
.tl-node.is-today .tl-rel { color: var(--peach-ink); }
.tl-node-items { display: flex; flex-direction: column; gap: 8px; }
.tl-entry { display: flex; gap: 11px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 11px 14px; box-shadow: var(--shadow); }
.tl-entry-ico { flex: none; display: inline-flex; padding-top: 2px; }
.tl-entry-ico .ico-cat { width: 17px; height: 17px; display: block; }
.tl-entry-ico.cat-academics, .tl-entry-ico.cat-school_admin { color: var(--brand); }
.tl-entry-ico.cat-activities { color: #2f6f9e; }
.tl-entry-ico.cat-appointments { color: var(--appt); }
.tl-entry-ico.cat-money { color: var(--peach-ink); }
.tl-entry-ico.cat-health { color: #2f8f76; }
.tl-entry-ico.cat-personal { color: #9aa1ad; }
.tl-entry-body { flex: 1; min-width: 0; }
.tl-entry-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tl-entry-title { font-size: .98rem; color: var(--ink); }
.tl-entry-time { display: inline-flex; align-items: center; gap: 4px; font-size: .76rem; font-weight: 700; color: #8a5a23; background: #f6ecdd; padding: 2px 8px; border-radius: 6px; }
.tl-entry-time .ico-xs { width: 13px; height: 13px; }
.tl-entry-detail { color: #4c4c63; font-size: .88rem; margin: 4px 0 6px; }
.tl-entry .link-action { font-size: .82rem; }

/* ---------- Calendar (month grid, Outlook-style) ---------- */
.cal { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow); overflow: hidden; margin-top: 2px; }
.cal-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 14px 18px; }
.cal-title { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.4rem; color: var(--ink); margin: 0; }
.cal-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-left: auto; }
.cal-range { font-size: .9rem; font-weight: 600; color: var(--muted); }
/* Category key = icon + label, neutral (categories are shown by icon, not colour) */
.cat-key { display: inline-flex; align-items: center; gap: 6px; font-size: .76rem; font-weight: 700; color: var(--muted); }
.cat-key .ico-cat { width: 15px; height: 15px; }
/* Kid badge = full solid colour + person icon + name (colour = kid) */
.who-badge { display: inline-flex; align-items: center; gap: 5px; font-size: .8rem; font-weight: 800; color: #fff;
  background: #9a958a; padding: 4px 12px 4px 9px; border-radius: 999px; }
.who-badge .ico-xs { width: 13px; height: 13px; }
.cal-leg { font-size: .74rem; font-weight: 700; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; }
.cal-leg::before { content: ''; width: 9px; height: 9px; border-radius: 50%; }
.cal-leg.cat-academics::before { background: var(--brand); }
.cal-leg.cat-activities::before { background: #2f6f9e; }
.cal-leg.cat-appointments::before { background: var(--appt); }
.cal-nav { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.cal-nav-btn { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 9px; border: 1px solid var(--line); color: var(--ink); background: var(--surface); }
.cal-nav-btn:hover { border-color: var(--brand); color: var(--brand-d); background: var(--band); }
.cal-today-btn { font-size: .85rem; font-weight: 700; padding: 7px 14px; border-radius: 9px; border: 1px solid var(--line); color: var(--brand-d); }
.cal-today-btn:hover { border-color: var(--brand); background: var(--brand-soft); }
.cal-weekdays { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-top: 1px solid var(--line); background: var(--band); }
.cal-weekday { padding: 8px 10px; font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-cell { min-height: 108px; border-top: 1px solid var(--line); border-left: 1px solid var(--line); padding: 6px 7px 8px; }
.cal-cell:nth-child(7n+1) { border-left: 0; }
.cal-cell.is-other { background: #faf8f2; }
.cal-cell.is-other .cal-daynum { color: #b9b2a1; }
.cal-cell.is-weekend:not(.is-other) { background: #fcfbf7; }
.cal-daynum { font-size: .82rem; font-weight: 700; color: var(--ink); display: inline-flex; align-items: center; justify-content: center; min-width: 24px; height: 24px; }
.cal-cell.is-today .cal-daynum { background: var(--peach); color: #fff; border-radius: 50%; width: 24px; }
.cal-events { display: flex; flex-direction: column; gap: 3px; margin-top: 3px; }
.cal-event { font-size: .72rem; font-weight: 600; line-height: 1.3; padding: 2px 7px; border-radius: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: default; }
.cal-event-time { font-weight: 700; opacity: .85; }
.cal-event.is-unassigned { background: #e9e5db; color: var(--ink); }
.cal-ev-ico { display: inline-flex; vertical-align: -2px; margin-right: 3px; }
.cal-ev-ico .ico-cat { width: 12px; height: 12px; }
.cal-event.is-todo { box-shadow: inset 3px 0 0 var(--high); }
.cal-more { font-size: .68rem; font-weight: 700; color: var(--muted); padding: 1px 4px; }
@media (max-width: 720px) {
  .cal-cell { min-height: 74px; padding: 4px; }
  .cal-event { font-size: .62rem; padding: 1px 5px; }
  .cal-event-time { display: none; }
  .cal-weekday { font-size: .58rem; padding: 6px 4px; }
}

/* Calendar + "Up next" sidebar (titles in each kid's colour) */
/* "Up next" matches the calendar height: the column stretches and the list fills + scrolls. */
.cal-layout { display: flex; gap: 18px; align-items: stretch; }
.cal-layout .cal { flex: 1 1 auto; min-width: 0; margin-top: 0; }
.cal-aside { flex: 0 0 270px; background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--shadow); padding: 16px; display: flex; flex-direction: column; }
.cal-aside-title { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.18rem; margin: 0 0 10px; }
.cal-kids { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.cal-kid { font-size: .78rem; font-weight: 800; display: inline-flex; align-items: center; gap: 6px; }
.cal-kid::before { content: ''; width: 9px; height: 9px; border-radius: 50%; background: currentColor; }
/* "Up next" grouped by day; fills the aside (matching the calendar) and scrolls if longer.
   flex-basis 0 keeps the list from inflating the column, so the calendar sets the height. */
.upnext { margin: 0; padding: 0 6px 0 0; flex: 1 1 0; min-height: 0; overflow-y: auto; }
.upnext-day { font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--muted);
  margin: 14px 0 6px; padding-top: 12px; border-top: 1px solid var(--line); }
.upnext-day:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.upnext-day.is-today { color: var(--peach-ink); }
.upnext-item { padding: 3px 0 3px 2px; }
.upnext-title { font-size: .9rem; font-weight: 700; color: var(--ink); }
@media (max-width: 900px) {
  .cal-layout { flex-direction: column; align-items: stretch; }
  .cal-aside { flex: none; width: 100%; }
  /* stacked: the list takes its natural height (no fill/scroll) */
  .upnext { flex: 0 1 auto; overflow: visible; }
}

/* "Next N days" rolling grid, 3 wide */
.cal16-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 1px solid var(--line); }
.cal16-cell { min-height: 120px; border-bottom: 1px solid var(--line); border-left: 1px solid var(--line); padding: 9px 11px 11px; }
.cal16-cell:nth-child(3n+1) { border-left: 0; }
/* Public holiday: the whole box is tinted, because the useful question is "is anyone at school
   that day", which is about the DAY and not about an event on it. Light enough that a child's
   colour chip still reads on top of it, and it does not compete with is-today. */
.cal16-cell.is-holiday { background: #FBEDF0; }
.cal16-cell.is-holiday.is-weekend { background: #F7E6EA; }
.cal16-hol { display: block; margin-top: 3px; font-size: 11px; font-weight: 700; line-height: 1.25;
  color: #9C4A63; overflow: hidden; text-overflow: ellipsis; }
.cal16-cell:nth-last-child(-n+3) { border-bottom: 0; }
.cal16-cell.is-weekend { background: #fcfbf7; }
.cal16-cell.is-today { background: #fff5ef; box-shadow: inset 0 3px 0 var(--peach); }
.cal16-dayhead { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; margin-bottom: 7px; }
.cal16-dow { font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.cal16-cell.is-today .cal16-dow { color: var(--peach-ink); }
.cal16-daynum { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.1rem; color: var(--ink); }
.cal16-cell.is-today .cal16-daynum { color: var(--peach-ink); }
@media (max-width: 720px) {
  .cal16-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cal16-cell:nth-child(3n+1) { border-left: 1px solid var(--line); }
  .cal16-cell:nth-child(2n+1) { border-left: 0; }
}

/* Preview list */
.preview-out { margin-top: 14px; }
.preview-list { list-style: none; padding: 0; margin: 8px 0 0; }
.preview-list li { padding: 10px 0; border-bottom: 1px solid var(--line); }
.pv-top { display: flex; gap: 8px; align-items: center; }
.pv-subj { font-weight: 600; }
.pv-meta { color: var(--muted); font-size: .82rem; margin-top: 2px; }

/* Admin table */
.admin-table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.admin-table th, .admin-table td { text-align: left; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.admin-table th { font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); background: var(--band); }
.admin-table tr:last-child td { border-bottom: none; }
.admin-table .dim { color: var(--muted); white-space: nowrap; }
.admin-table form { margin: 0; }
.admin-table code { font-size: .82em; color: var(--muted); }
.admin-link { color: var(--brand-d); font-weight: 600; text-decoration: none; }
.admin-link:hover { text-decoration: underline; }
.pill.sm { font-size: .7rem; padding: 2px 8px; background: var(--band); color: var(--muted); font-weight: 700; }

/* Admin summary cards */
.admin-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; margin: 16px 0 20px; }
.admin-stat { background: var(--card, #fff); border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; display: flex; flex-direction: column; gap: 4px; }
.admin-stat-n { font-size: 1.7rem; font-weight: 800; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
.admin-stat-l { font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; }
.admin-h2 { font-size: 1.15rem; margin: 26px 0 10px; }
.admin-kv { width: 100%; border-collapse: collapse; font-size: .92rem; }
.admin-kv th { text-align: left; font-weight: 600; color: var(--muted); padding: 9px 14px; width: 42%; vertical-align: top; }
.admin-kv td { padding: 9px 14px; }
.admin-kv tr { border-bottom: 1px solid var(--line); }
.admin-kv tr:last-child { border-bottom: none; }

/* Scanning */
.spinner { width: 46px; height: 46px; margin: 0 auto 22px; border-radius: 50%; border: 4px solid var(--brand-soft); border-top-color: var(--brand); animation: spin .9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Footer */
.site-footer { background: #161630; color: #c9c9e0; padding: 40px 0; margin-top: 0; flex-shrink: 0; }
.footer-inner { display: flex; flex-direction: column; gap: 10px; }
.site-footer .brand { color: #fff; }
/* The one place the mark gets the white half it was drawn for. A dark ground is also the only
   place the sage reads as sage, so it lifts to the pale tint rather than staying at 600. */
.site-footer .brand-name { --wm-a: #fff; --wm-b: #9EC4AC; }
.site-footer p { color: #9a9ac0; font-size: .9rem; max-width: 520px; }

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .hero-grid, .showcase-grid { grid-template-columns: 1fr; gap: 32px; }
  .hero-copy h1 { font-size: 2.4rem; }
  .steps, .strip-grid { grid-template-columns: 1fr; }
  .features { grid-template-columns: 1fr 1fr; }
  .valueprops { grid-template-columns: 1fr; }
  .preview, .preview.three { grid-template-columns: 1fr; }
  .section { padding: 56px 0; }
}
@media (max-width: 820px) {
  /* iOS Safari zooms the whole page when a focused control's font is under 16px, and a
     zoomed page detaches the sticky header from the visible screen — content then shows
     above/behind the pill no matter how the header is styled (the recurring mobile
     header-bleed reports). Keep EVERY text control at 16px on phones so Safari never
     zooms. !important on purpose: no future small-font input may reintroduce this. */
  input:not([type="checkbox"]):not([type="radio"]), select, textarea { font-size: 16px !important; }
  /* On phones the frosted pill lets scrolling text ghost through the glass (and iOS
     renders backdrop-filter inconsistently mid-scroll), so make it near-opaque. */
  .topbar-inner { background: rgba(252,250,245,.96); }
  /* Collapse the top nav into a hamburger dropdown so Settings/Timeline stay reachable */
  .nav-toggle { display: flex; }
  .topnav { display: none; position: absolute; top: 100%; left: 0; right: 0; flex-direction: column;
    align-items: stretch; gap: 0; background: #fff; border-bottom: 1px solid var(--line);
    padding: 6px 24px 14px; box-shadow: var(--shadow); }
  body.nav-open .topnav { display: flex; }
  /* Undo desktop's centred/absolute tabs so the menu stacks vertically. */
  .nav-links, .nav-account { position: static; transform: none; flex-direction: column;
    align-items: stretch; gap: 0; width: 100%; }
  .topnav a { padding: 13px 0; border-bottom: 1px solid var(--line); font-size: 1rem; }
  .nav-links a { padding: 13px 12px; border-radius: 8px; }
  .nav-links a.active { background: var(--brand-soft); }
  .topnav .pill { margin: 12px 0 4px; align-self: flex-start; }
  .topnav .btn { margin-top: 10px; text-align: center; }
}
@media (max-width: 560px) {
  .features { grid-template-columns: 1fr; }
  .hero-copy h1 { font-size: 2rem; }
  /* The hero pill row is inline-flex and does NOT wrap, so "SCHOOL · SPORTS ·
     APPOINTMENTS · TRAVEL" measures ~397px: wider than every phone screen, including a
     430px Pro Max. That overflow put the whole page into a sideways scroll, which is what
     made the hero look flush to the left edge with no breathing room. Let it wrap and
     tighten it so it fits; max-width stops it escaping the container again if the labels
     ever get longer. */
  .hero-pills { flex-wrap: wrap; max-width: 100%; row-gap: 5px; column-gap: 8px;
    padding: 8px 13px; letter-spacing: .08em; }
  /* Tighter, more concise connected dashboard on phones */
  .page.board-page { padding: 24px 18px 48px; }
  .board-page .display { font-size: 1.55rem; line-height: 1.15; margin-bottom: 6px; }
  .summary { font-size: .96rem; margin: 4px 0; }
  .board-page .meta { font-size: .82rem; }
  .hero-row { gap: 12px; margin-bottom: 14px; }
  .week-activities .wa-day { flex: 0 0 78%; }
  /* Compact agenda cards on phones: narrower date tile, smaller chips, and an action
     row that fits on ONE line (incl. the ... menu) so cards hug their text. */
  .cu-date { flex: 0 0 62px; padding: 10px 4px; }
  .cu-date-num { font-size: 1.35rem; }
  .cu-agenda .cu-item { padding: 10px 12px; }
  .cu-top .cu-time { font-size: .72rem; padding: 1px 7px; }
  .who-chip { font-size: .72rem; padding: 1px 9px 1px 2px; }
  .who-chip::before { width: 17px; height: 17px; font-size: .62rem; }
  .assignee { font-size: .66rem; padding: 1px 7px; }
  .cu-actions { gap: 6px 10px; }
  .cu-actions .link-action { font-size: .78rem; }
  .cu-more { padding: 2px 4px; }
}

/* ---------- Dashboard: main content + a right-hand "Needs attention" rail ---------- */
/* Widen the board so the rail sits beside the main content instead of squeezing it. */
.page.board-page { max-width: 1240px; }
.board-layout { display: grid; grid-template-columns: 1fr; gap: 20px; align-items: start; }
.board-main { min-width: 0; }
/* Hero sits full-width above the two columns; the columns below flow independently
   (no shared row, so neither side leaves a gap under the other). */
.hero-text { margin-bottom: 24px; }
@media (min-width: 900px) {
  .board-layout { grid-template-columns: minmax(0, 1fr) 300px; gap: 28px; }
  .board-side { position: sticky; top: 84px; align-self: start; }   /* rail to the right */
  .board-side .addbox { margin-bottom: 20px; }   /* top of the rail, above Needs attention */
}
@media (max-width: 899.98px) {
  /* Stacked: dissolve both columns so their cards become siblings. VALUE FIRST: the
     schedule (agenda) right under the hero, then Needs attention, and the add-events
     box LAST — a new parent's first sight is their week, not an empty paste box.
     gap stays 0 — each block keeps its own margins, as before. */
  .board-layout { display: flex; flex-direction: column; gap: 0; }
  .board-main, .board-side { display: contents; }
  .board-main > * { order: 10; }
  .board-main > .hero-text { order: 0; }
  /* Someday/Travel drop below the add box, so the phone reads: schedule, add box,
     then the lower-priority sections, then the rail panels. */
  .board-main > .cu-someday-wrap, .board-main > .cu-travel, .board-main > #cuEmpty { order: 14; }
  .board-side > * { order: 20; margin-bottom: 16px; }
  .board-side > .addbox { order: 12; margin: 4px 0 16px; }
}

.attn { background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--shadow); padding: 16px 16px 18px; }
.attn-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.attn-head h2 { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.12rem; margin: 0; }
.attn-count { font-size: .76rem; font-weight: 700; color: var(--brand-d); background: var(--brand-soft);
  border-radius: 20px; padding: 2px 10px; white-space: nowrap; }

/* completed-items display switch (strike out vs. hide) */
.done-switch { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 12px 0 4px; }
.done-switch-label { font-size: .78rem; font-weight: 700; color: var(--muted); }
.seg { display: inline-flex; background: var(--band); border: 1px solid var(--line); border-radius: 9px; padding: 2px; }
.seg-opt { font: inherit; font-size: .76rem; font-weight: 700; color: var(--muted); background: transparent;
  border: 0; border-radius: 7px; padding: 4px 10px; cursor: pointer; transition: background .12s, color .12s; }
.seg-opt:hover { color: var(--brand-d); }
.seg-opt.on { background: var(--surface); color: var(--brand-d); box-shadow: 0 1px 2px rgba(47,64,53,.12); }

.attn-body { margin-top: 6px; }
.attn-group { margin-top: 14px; }
.attn-group:first-child { margin-top: 8px; }
.attn-group-head { display: flex; align-items: center; justify-content: space-between;
  font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); margin: 0 2px 7px; }
.attn-n { background: var(--band); color: var(--muted); border-radius: 20px; padding: 0 7px; font-size: .68rem; font-weight: 700; }
.attn-overdue .attn-group-head { color: var(--high); }
.attn-overdue .attn-n { background: #fbe4df; color: var(--high); }
.attn-today .attn-group-head { color: var(--peach-ink); }
.attn-today .attn-n { background: var(--peach-soft); color: var(--peach-ink); }

.attn-item { display: flex; align-items: flex-start; gap: 10px; padding: 9px; border-radius: 11px; transition: background .12s; }
.attn-item:hover { background: var(--band); }
.attn-item.flagged { background: #fffdf4; }
.attn-overdue .attn-item { box-shadow: inset 3px 0 0 var(--high); }
.attn-today .attn-item { box-shadow: inset 3px 0 0 var(--peach); }

.attn-check { flex: none; width: 20px; height: 20px; margin-top: 1px; border-radius: 6px;
  border: 1.7px solid var(--line); background: var(--surface); color: transparent;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  transition: background .12s, border-color .12s, color .12s; }
.attn-check:hover { border-color: var(--brand); }
.attn-check .ico-xs { width: 13px; height: 13px; }
.attn-item.is-done .attn-check { background: var(--brand); border-color: var(--brand); color: #fff; }

.attn-main { flex: 1; min-width: 0; text-align: left; background: none; border: 0; padding: 0; cursor: pointer; font: inherit; color: inherit; display: block; }
.attn-title { display: block; font-weight: 700; font-size: .92rem; line-height: 1.3; color: var(--ink); }
.attn-main:hover .attn-title { color: var(--brand-d); }
.attn-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 3px; }
.attn-who { font-size: .72rem; font-weight: 700; color: var(--muted); }
.attn-due { font-size: .74rem; font-weight: 600; color: var(--muted); }
.attn-overdue .attn-due { color: var(--high); font-weight: 700; }
.attn-today .attn-due { color: var(--peach-ink); font-weight: 700; }

/* a completed item: kept in place, struck through and dimmed (or hidden via the switch) */
.attn-item.is-done { opacity: .6; }
.attn-item.is-done .attn-title { text-decoration: line-through; color: var(--muted); }
.cu-item.is-done { opacity: .62; }
.cu-item.is-done .cu-title { text-decoration: line-through; color: var(--muted); }
.cu-item.is-done .done-toggle { color: var(--ok); }
/* A confirmed activity reads as a positive plan, not a struck-out to-do. */
.cu-item.is-confirmed.is-done { opacity: 1; }
.cu-item.is-confirmed .cu-title { text-decoration: none; color: var(--ink); }

.attn-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;
  color: var(--muted); font-size: .9rem; padding: 22px 8px 8px; }
.attn-empty .ico { color: var(--ok); width: 28px; height: 28px; }

/* Reminders card: the parent's own to-dos/nudges, sitting above the attention pane */
.rem { background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--shadow); padding: 16px 16px 18px; margin-bottom: 16px; }
.rem-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.rem-head h2 { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.12rem; margin: 0; }
.rem-head .micro-link { display: inline-flex; align-items: center; gap: 4px; }
.rem-head .micro-link .ico, .rem-head .micro-link .ico-xs { width: 14px; height: 14px; }
.rem-sub { font-size: .78rem; color: var(--muted); margin: 4px 0 10px; }
.rem-body:empty { display: none; }
.rem-item { display: flex; align-items: flex-start; gap: 10px; padding: 9px; border-radius: 11px; transition: background .12s; }
.rem-item:hover { background: var(--band); }
.rem-item.is-overdue { box-shadow: inset 3px 0 0 var(--high); }
.rem-check { flex: none; width: 20px; height: 20px; margin-top: 1px; border-radius: 6px;
  border: 1.7px solid var(--line); background: var(--surface); color: transparent;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  transition: background .12s, border-color .12s, color .12s; }
.rem-check:hover { border-color: var(--brand); }
.rem-check .ico-xs { width: 13px; height: 13px; }
.rem-item.is-done .rem-check { background: var(--brand); border-color: var(--brand); color: #fff; }
.rem-main { flex: 1; min-width: 0; }
.rem-text { display: block; font-weight: 700; font-size: .92rem; line-height: 1.3; color: var(--ink); }
.rem-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 3px; }
.rem-who { font-size: .68rem; font-weight: 800; color: #fff; border-radius: 20px; padding: 1px 8px; }
.rem-when { font-size: .74rem; font-weight: 600; color: var(--muted); }
.rem-item.is-overdue .rem-when { color: var(--high); font-weight: 700; }
.rem-item.is-done { opacity: .6; }
.rem-item.is-done .rem-text { text-decoration: line-through; color: var(--muted); }
.rem-del { flex: none; background: none; border: 0; padding: 2px; cursor: pointer; color: var(--faint);
  border-radius: 6px; display: inline-flex; opacity: 0; transition: opacity .12s, color .12s; }
.rem-del .ico-xs { width: 14px; height: 14px; }
.rem-item:hover .rem-del, .rem-del:focus-visible { opacity: 1; }
.rem-del:hover { color: var(--high); }
.rem-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;
  color: var(--muted); font-size: .86rem; padding: 14px 8px 6px; }
.rem-empty .ico, .rem-empty .ico-xs { color: var(--brand); width: 24px; height: 24px; }
.rem-fields { display: flex; gap: 10px; }
.rem-fields label { flex: 1; }

/* "Good to know" prep notes on party/RSVP cards */
.gtk { display: flex; align-items: flex-start; gap: 8px; margin-top: 10px; padding: 8px 11px;
  border-radius: 10px; background: var(--brand-soft); color: var(--brand-d); font-size: .86rem; line-height: 1.4; }
.gtk .ico-xs { flex: none; margin-top: 2px; }
.gtk-suggest { background: var(--peach-soft); color: var(--peach-ink); flex-wrap: wrap; }
.gtk-rsvp { background: var(--peach-soft); color: var(--peach-ink); flex-wrap: wrap; }
/* Pure status lines (auto-completed, schedule-read) are informational, not important:
   drop the fill and render them as quiet secondary text so the highlighted background
   stays reserved for genuinely important / actionable "Good to know" notes. */
.gtk-auto, .gtk.sched-done { background: none; color: var(--muted); padding: 4px 0; margin-top: 6px; }
.gtk-auto { flex-wrap: wrap; }
.gtk-auto .gtk-edit { margin-left: 4px; }
.gtk-acts { display: inline-flex; gap: 6px; align-items: center; margin-left: auto; flex-wrap: wrap; }
.gtk-keep, .gtk-edit, .gtk-x { font: inherit; font-size: .78rem; font-weight: 700; border: 0;
  border-radius: 7px; padding: 3px 9px; cursor: pointer; display: inline-flex; align-items: center; gap: 3px; }
.gtk-keep { background: var(--brand); color: #fff; }
.gtk-keep .ico-xs { width: 13px; height: 13px; }
.gtk-edit { background: rgba(0, 0, 0, .07); color: inherit; }
.gtk-x { background: transparent; color: inherit; padding: 3px 5px; }
.gtk-x .ico-xs { width: 13px; height: 13px; }
.gtk-add { margin-top: 8px; background: transparent; border: 1px dashed var(--line); color: var(--muted);
  border-radius: 9px; padding: 6px 10px; font: inherit; font-size: .8rem; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px; }
.gtk-add:hover { border-color: var(--brand); color: var(--brand-d); }
.gtk-add .ico-xs { width: 14px; height: 14px; }

/* Family shopping list */
.shop-page .shop-head h1 { margin-bottom: 4px; }
.shop-who { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 14px 0 6px; }
.shop-who-input { max-width: 220px; }
.shop-who-hint { font-size: .8rem; color: var(--muted); }
.shop-add { display: flex; gap: 8px; margin: 10px 0 14px; flex-wrap: wrap; }
.shop-add .shop-item { flex: 2 1 220px; }
.shop-add .shop-store { flex: 1 1 140px; }
.shop-add .btn { flex: none; }
.shop-share-row { margin: 4px 0 14px; }
.shop-share-hint { color: var(--muted); margin: 0 0 12px; }
.shop-share-save { margin-top: 8px; }
.modal-card .ss-row { margin-bottom: 14px; }
.shop-share { background: var(--band); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin-bottom: 14px; }
.ss-label { display: flex; align-items: center; gap: 6px; font-size: .82rem; color: var(--muted); margin-bottom: 8px; }
.ss-label .ico { width: 15px; height: 15px; color: var(--brand); flex: none; }
.ss-name { display: flex; gap: 8px; margin-bottom: 8px; }
.ss-name input { flex: 1 1 220px; min-width: 0; }
.ss-name .btn { flex: none; }
.ss-row { display: flex; gap: 8px; flex-wrap: wrap; }
/* Invite row: the button with "or add your own: Gmail · Outlook" right beside it. */
.ss-invite-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 2px; }
.ss-own { font-size: .82rem; color: var(--muted); font-weight: 600; }
.ss-own a { font-weight: 700; }
.ss-url { flex: 1 1 220px; min-width: 0; font-size: .82rem; color: var(--ink); background: var(--surface); }
.ss-row .btn { flex: none; }
.ss-row form { flex: none; }
.shop-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.shop-count { font-size: .84rem; font-weight: 700; color: var(--muted); margin-right: auto; }
.shop-group { margin-top: 16px; }
.shop-store-head { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.02rem; margin: 0 0 6px;
  padding-bottom: 5px; border-bottom: 1px solid var(--line); }
.shop-item-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 6px; border-radius: 10px; transition: background .12s; }
.shop-item-row:hover { background: var(--band); }
.shop-check-form { flex: none; margin: 0; }
.shop-check { width: 22px; height: 22px; margin-top: 1px; border-radius: 6px; border: 1.7px solid var(--line);
  background: var(--surface); color: transparent; display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; transition: background .12s, border-color .12s, color .12s; }
.shop-check:hover { border-color: var(--brand); }
.shop-check .ico-xs { width: 13px; height: 13px; }
.is-bought .shop-check { background: var(--brand); border-color: var(--brand); color: #fff; }
.shop-main { flex: 1; min-width: 0; }
.shop-name { display: block; font-weight: 700; font-size: .95rem; color: var(--ink); }
.is-bought .shop-name { text-decoration: line-through; color: var(--muted); }
.shop-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 2px; }
.shop-by { font-size: .74rem; color: var(--muted); }
.shop-buy { font-size: .76rem; font-weight: 700; color: var(--brand-d); display: inline-flex; align-items: center; gap: 4px; }
.shop-buy .ico { width: 12px; height: 12px; }
.shop-del { flex: none; background: none; border: 0; padding: 3px; cursor: pointer; color: var(--faint);
  border-radius: 6px; display: inline-flex; opacity: 0; transition: opacity .12s, color .12s; }
.shop-del .ico-xs { width: 14px; height: 14px; }
.shop-item-row:hover .shop-del, .shop-del:focus-visible { opacity: 1; }
.shop-del:hover { color: var(--high); }
/* "We can't read your mailbox." The one banner in the app that IS an alarm: until it is dealt
   with the product does nothing at all. Warm red rather than the quiet band used for nudges,
   and no dismiss control, because dismissing it would hide the reason the app looks empty. */
.reconnect-banner { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; background: #fdf0ec; border: 1px solid #e8b4a4; border-left: 4px solid var(--high);
  border-radius: 12px; padding: 12px 16px; margin-bottom: 16px; font-size: .92rem; color: #7a2e18; }
.reconnect-banner strong { color: #5e2210; }
.m-reconnect { background: #fdf0ec; border: 1px solid #e8b4a4; border-left: 4px solid var(--high);
  border-radius: 12px; padding: 12px 14px; margin: 10px 12px 0; }
.m-reconnect-t { font-weight: 800; font-size: .9rem; color: #5e2210; margin-bottom: 3px; }
.m-reconnect-b { margin: 0 0 9px; font-size: .85rem; line-height: 1.4; color: #7a2e18; }
@media (prefers-color-scheme: dark) {
  .reconnect-banner, .m-reconnect { background: #3a1f16; border-color: #7a4132; color: #f3c9bb; }
  .reconnect-banner strong, .m-reconnect-t { color: #ffd9cc; }
  .m-reconnect-b { color: #f3c9bb; }
}

/* The stale-list nudge. Sits above the list, quiet rather than alarming: it is a question about
   housekeeping, not a warning, and it must not look like the app has found a problem. */
.shop-nudge { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; background: var(--band); border: 1px solid var(--line);
  border-radius: 12px; padding: 10px 14px; margin-bottom: 10px; }
.shop-nudge-text { margin: 0; font-size: .88rem; color: var(--muted); }
.shop-nudge-text strong { color: var(--ink); }
.shop-nudge-acts { display: flex; gap: 8px; flex-wrap: wrap; }

/* Select mode: pick several rows, then act on all of them at once. The whole row is the hit
   target (this is used one-handed while pushing a trolley), so the tick and the remove button
   are taken out of the way while picking — otherwise the two smallest controls on the row sit
   on top of the only thing you are trying to tap. */
.is-selecting .shop-item-row { cursor: pointer; padding-left: 34px; position: relative; }
.is-selecting .shop-check-form, .is-selecting .shop-del { pointer-events: none; opacity: .35; }
.is-selecting .shop-item-row::before { content: ""; position: absolute; left: 6px; top: 11px;
  width: 18px; height: 18px; border: 2px solid var(--line); border-radius: 5px; background: var(--card); }
.is-selecting .shop-item-row.is-picked::before { background: var(--brand); border-color: var(--brand); }
.is-selecting .shop-item-row.is-picked { background: var(--band); }
.shop-selbar { position: fixed; left: 50%; transform: translateX(-50%); bottom: 16px; z-index: 60;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: center;
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 10px 14px; box-shadow: 0 6px 24px rgba(0,0,0,.18); max-width: calc(100vw - 24px); }
.shop-selcount { font-size: .85rem; font-weight: 700; color: var(--muted); }
.shop-selacts { display: flex; gap: 8px; flex-wrap: wrap; }
/* The mobile subnav owns the bottom of the screen on a phone, so sit above it. */
body.subnav .shop-selbar { bottom: 74px; }
.shop-bought { margin-top: 6px; }
.shop-bought > summary { cursor: pointer; font-size: .8rem; font-weight: 700; color: var(--muted);
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 0; list-style: none; }
.shop-bought > summary::-webkit-details-marker { display: none; }
.shop-bought > summary .ico { width: 14px; height: 14px; color: var(--ok); }
.btn.sm.danger, .btn.ghost.sm.danger { color: var(--high); }

/* item detail popup (opened from a pane row) */
.detail-card { max-width: 440px; }
.detail-badges { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.detail-badges:empty { display: none; }
.detail-card h3 { font-size: 1.18rem; }
.detail-who { margin: 4px 0 0; font-size: .86rem; }
.detail-desc { margin: 8px 0 0; color: #4c4c63; font-size: .95rem; }
.detail-links { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 14px; }
.detail-foot { flex-wrap: wrap; }

/* Badges keep their label centred even when they carry no icon. */
.cat-badge, .date-badge, .todo-tag, .flag-badge, .noreply, .assignee,
.attn-count, .attn-n, .tag, .todo-tag, .actverb {
  display: inline-flex; align-items: center; justify-content: center; text-align: center;
}

/* PWA install banner (shown only on app pages, one-time dismissible; see pwa.js) */
.pwa-banner { position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 60;
  display: flex; align-items: center; gap: 10px; margin: 0 auto; max-width: 560px;
  padding: 12px 14px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 14px; box-shadow: 0 10px 34px rgba(31, 45, 33, .18); }
.pwa-banner-text { flex: 1; font-size: .9rem; line-height: 1.35; color: var(--ink); }
.pwa-banner .btn { flex: 0 0 auto; }
.pwa-banner-x { flex: 0 0 auto; background: none; border: 0; font-size: 1.35rem; line-height: 1;
  color: var(--muted); cursor: pointer; padding: 0 2px; }
@media (min-width: 620px) { .pwa-banner { left: auto; right: 16px; bottom: 16px; } }

/* Settings: child chip colour dot (matches the child's board colour) */
.child-list .rec-chip-name { display: flex; align-items: center; gap: 6px; }
.child-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }

/* Tomorrow at a glance: the focused evening-preview page the 9pm push opens into. */
.tw-wrap { max-width: 620px; margin: 24px auto; }
.tw-card { padding: 22px 22px 18px; }
.tw-head { border-bottom: 1px solid var(--line); padding-bottom: 12px; margin-bottom: 6px; }
.tw-title { font-family: "Fraunces", Georgia, serif; font-size: 24px; font-weight: 600; color: var(--ink); margin: 0; }
.tw-date { color: var(--muted); font-size: 14px; margin: 3px 0 0; }
/* Each section carries its own accent so the three read apart at a glance:
   Schedule = sage (calm), Needs attention = brick (urgent), Reminders = slate-lavender. */
.tw-section { margin-top: 16px; padding: 2px 0 4px 12px; border-left: 3px solid var(--line); border-radius: 2px; }
.tw-sub { font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 0 0 4px; }
.tw-section--schedule { border-left-color: var(--brand); }
.tw-section--schedule .tw-sub { color: var(--brand); }
.tw-section--attention { border-left-color: var(--high); }
.tw-section--attention .tw-sub { color: var(--high); }
.tw-section--reminders { border-left-color: var(--appt); }
.tw-section--reminders .tw-sub { color: var(--appt); }
.tw-kid { font-weight: 700; font-size: 14px; color: var(--ink); margin: 12px 0 2px; }
.tw-list { list-style: none; margin: 0; padding: 0; }
.tw-item { padding: 8px 0; border-bottom: 1px solid var(--line); }
.tw-item:last-child { border-bottom: 0; }
.tw-line { font-size: 14.5px; color: var(--ink); line-height: 1.45; }
.tw-time { font-weight: 700; margin-right: 6px; }
.tw-note { color: var(--muted); font-size: 12.5px; margin-top: 2px; line-height: 1.4; }
.tw-empty { padding: 22px 0; text-align: center; }
.tw-empty-title { font-weight: 700; color: var(--ink); margin: 0; }
.tw-empty-sub { color: var(--muted); font-size: 14px; margin: 4px 0 0; }
.tw-actions { margin-top: 20px; }
.tw-actions .btn { display: block; width: 100%; text-align: center; }

/* ---------- Upload review: one calm card per item, with a checkable citation ---------- */
.usum { background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--shadow); padding: 16px 18px; margin: 10px 0 20px; }
.usum-doc { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.05rem; color: var(--ink); margin: 0 0 6px; }
.usum-count { margin: 0; color: var(--ink); font-size: .95rem; }
.usum-trust { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 0; }
.usum-hint { margin: 10px 0 0; color: var(--muted); font-size: .84rem; }
.ubadge { font-size: .72rem; font-weight: 800; border-radius: 20px; padding: 3px 10px; }
.ubadge.ok { background: var(--brand-soft); color: var(--brand-d); }
.ubadge.warn { background: var(--peach-soft); color: var(--peach-ink); }

.ulist { display: flex; flex-direction: column; gap: 12px; }
.ucard { position: relative; display: flex; gap: 13px; background: var(--surface); border: 1px solid var(--line);
  border-left: 4px solid var(--line-strong); border-radius: 16px; box-shadow: var(--shadow);
  padding: 15px 16px; transition: border-color .12s; }
.ucard-x { position: absolute; top: 8px; right: 8px; z-index: 2; width: 30px; height: 30px; border: 0;
  background: transparent; color: var(--muted); font-size: 22px; line-height: 1; cursor: pointer;
  border-radius: 8px; display: grid; place-items: center; touch-action: manipulation; }
.ucard-x:hover { background: var(--band); color: var(--high); }
.ucard.is-removed { display: none; }
.ucard.cat-activities { border-left-color: var(--brand); }
.ucard.cat-academics  { border-left-color: var(--low); }
.ucard.cat-appointments { border-left-color: var(--appt); }
.ucard.cat-bills { border-left-color: var(--high); }
.ucard-body { flex: 1; min-width: 0; }
.ucard-title { font-size: 1.02rem; font-weight: 800; color: var(--ink); margin: 0; line-height: 1.3; }

/* Big, obvious tick. The native box is hidden but still focusable. */
.ucard-add { flex: 0 0 auto; position: relative; width: 24px; height: 24px; margin-top: 2px; cursor: pointer; }
.ucard-add input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.ucard-add-box { display: block; width: 24px; height: 24px; border-radius: 8px;
  border: 2px solid var(--line-2, var(--line)); background: var(--surface); transition: background .12s, border-color .12s; }
.ucard-add-box::after { content: ""; position: absolute; left: 8px; top: 3.5px; width: 6px; height: 12px;
  border: solid #fff; border-width: 0 2.5px 2.5px 0; transform: rotate(45deg) scale(0); transition: transform .12s; }
.ucard-add input:checked + .ucard-add-box { background: var(--brand); border-color: var(--brand); }
.ucard-add input:checked + .ucard-add-box::after { transform: rotate(45deg) scale(1); }
.ucard-add input:focus-visible + .ucard-add-box { outline: 2px solid var(--brand); outline-offset: 2px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.ucard-meta { display: flex; flex-wrap: wrap; gap: 7px; margin: 8px 0 0; }
.uchip { font-size: .74rem; font-weight: 800; border-radius: 20px; padding: 3px 10px; white-space: nowrap; }
.uchip.when { background: var(--band); color: var(--ink); }
.uchip.who { background: var(--brand-soft); color: var(--brand-d); }
.uchip.todo { background: #fbe4df; color: var(--high); }
.ucard-detail { font-size: .83rem; color: var(--muted); margin: 8px 0 0; line-height: 1.45; }
.ucard-detail.prep { color: var(--brand-d); }

.ucard-controls { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.ufield { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ufield.wide { flex: 1 1 100%; }
.ufield-l { font-size: .64rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.ufield select, .ufield input { font: inherit; font-size: .86rem; padding: 8px 10px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--surface); color: var(--ink); min-width: 0; }
.ufield select { appearance: none; -webkit-appearance: none; padding-right: 28px; cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%235E6B5E' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat; background-position: right 10px center; }
.ufield select:focus, .ufield input:focus { outline: none; border-color: var(--brand); }

/* Citation + edit: quiet by default, open on demand. No raw date boxes shouting on the card. */
.ucite, .uedit { margin-top: 11px; }
.ucite summary, .uedit summary { cursor: pointer; font-size: .76rem; font-weight: 800; list-style: none;
  display: inline-flex; align-items: center; gap: 6px; border-radius: 20px; padding: 4px 11px; }
.ucite summary::-webkit-details-marker, .uedit summary::-webkit-details-marker { display: none; }
.ucite summary::before { content: ""; width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.ucite.is-verified summary { background: var(--brand-soft); color: var(--brand-d); }
.ucite.is-verified summary::before { background: var(--ok); }
.ucite.is-unverified summary { background: var(--peach-soft); color: var(--peach-ink); }
.ucite.is-unverified summary::before { background: var(--peach-ink); }
.ucite.is-photo summary { background: var(--band); color: var(--muted); }
.ucite.is-photo summary::before { background: var(--muted); }
.uedit summary { background: var(--band); color: var(--muted); }
.uedit summary:hover, .ucite summary:hover { filter: brightness(.97); }

.ucite-body { margin-top: 8px; padding-left: 11px; border-left: 2px solid var(--line); }
.ucite-ctx { font-size: .76rem; font-weight: 700; color: var(--muted); margin: 0 0 5px; }
.ucite-quote { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .74rem; color: var(--ink);
  background: var(--band); border-radius: 8px; padding: 8px 10px; margin: 0; overflow-x: auto; white-space: pre-wrap; word-break: break-word; }
.uedit-body { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.ulist-actions { margin-top: 22px; }

@media (max-width: 560px) {
  .ucard { padding: 14px; }
  .ucard-controls .ufield, .uedit-body .ufield { flex: 1 1 calc(50% - 5px); }
  .ufield.wide { flex: 1 1 100%; }
}

/* "Which child is yours?" picker */
.pick-list { display: flex; flex-direction: column; gap: 10px; margin: 6px 0 4px; }
.pick-opt { display: flex; align-items: flex-start; gap: 11px; padding: 12px 13px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--surface); cursor: pointer; transition: border-color .12s, background .12s; }
.pick-opt:hover { border-color: var(--brand); background: var(--band); }
.pick-opt input { margin-top: 3px; width: 19px; height: 19px; accent-color: var(--brand); flex: 0 0 auto; }
.pick-body { display: block; }
.pick-name { display: block; font-weight: 800; color: var(--ink); font-size: .95rem; }
.pick-meta { display: block; font-size: .78rem; color: var(--muted); margin-top: 2px; }

/* "We could not find your child" — say it plainly, never guess. */
.nochild { background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--peach);
  border-radius: 16px; box-shadow: var(--shadow); padding: 16px 18px; margin: 14px 0 18px; }
.nochild-lead { margin: 0; color: var(--ink); font-size: .98rem; font-weight: 700; line-height: 1.5; }
.nochild-why { margin: 8px 0 0; color: var(--muted); font-size: .86rem; line-height: 1.5; }
.nochild-sugg { margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--line); }
.nochild-sugg-l { margin: 0 0 7px; font-size: .78rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted); }
.nochild-names { display: flex; flex-wrap: wrap; gap: 7px; margin: 0 0 9px; }
.nochild-name { font-size: .82rem; font-weight: 700; color: var(--ink); background: var(--band);
  border: 1px solid var(--line); border-radius: 20px; padding: 3px 11px; }
.nochild-sugg-hint { margin: 0; color: var(--muted); font-size: .84rem; line-height: 1.5; }

/* Upload actions: one primary, one escape, and a quiet third choice that never competes. */
/* Universal reader: bucket headings, task title input, weekly toggle and bulk-assign row */
.usection-h { font-size: 1.05rem; font-weight: 700; margin: 26px 0 10px; letter-spacing: -.01em; }
.usection-h:first-of-type { margin-top: 6px; }
.ubulk { display: flex; align-items: center; gap: 8px; margin: 0 0 12px; font-size: .9rem; color: var(--muted); }
.ubulk select { padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; font: inherit; background: var(--surface); }
.ucard-title-input { width: 100%; font-size: 1.02rem; font-weight: 600; padding: 6px 8px; border: 1px solid transparent;
  border-radius: 8px; background: transparent; font-family: inherit; }
.ucard-title-input:focus { border-color: var(--line); background: var(--surface); outline: none; }
.uweekly { flex-direction: row; align-items: center; gap: 7px; align-self: end; font-size: .9rem; white-space: nowrap; }
.uweekly input { width: 16px; height: 16px; }
.ucard.task .ucard-body, .ucard.shop .ucard-body { padding-top: 2px; }
.up-forwho { background: var(--accent-soft, #e5efe6); border-radius: 10px; padding: 10px 14px; font-size: .92rem; margin: 0 0 16px; }
.m-panel-alt { font-size: .82rem; color: var(--muted); margin: 10px 2px 0; line-height: 1.45; }
.m-panel-alt a { font-weight: 600; }
.uactions { margin-top: 22px; display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.uactions-row { display: flex; gap: 10px; flex-wrap: wrap; }
.uactions-alt { font-size: .84rem; }
@media (max-width: 560px) {
  .uactions { align-items: stretch; }
  .uactions-row { flex-direction: column; }
  .uactions-row .btn { width: 100%; text-align: center; }
  .uactions-alt { text-align: center; }
}

/* Reading a file: a 20 to 60 second wait needs a heartbeat, not a frozen page. */
.reading { text-align: center; padding: 30px 20px 26px; }
.reading .spinner { margin: 0 auto 18px; }
.reading-title { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 1.25rem; color: var(--ink); margin: 0; }
.reading-file { font-size: .85rem; font-weight: 700; color: var(--brand-d); margin: 8px 0 0; word-break: break-word; }
.reading-step { font-size: .9rem; color: var(--ink); margin: 14px 0 0; min-height: 1.3em; transition: opacity .2s; }
/* Tabular figures so the seconds don't jitter the line width as they tick. */
.reading-elapsed { font-size: .82rem; font-weight: 700; color: var(--muted); margin: 8px 0 0;
  font-variant-numeric: tabular-nums; }
.reading-note { font-size: .8rem; color: var(--muted); margin: 10px 0 0; }

/* Timeline: a plain Week / Month toggle where the filter clutter used to be. */
.tl-views { margin-left: auto; display: inline-flex; background: var(--band); border: 1px solid var(--line);
  border-radius: 10px; padding: 2px; gap: 2px; }
.tl-view { font-size: .78rem; font-weight: 800; color: var(--muted); text-decoration: none;
  padding: 5px 14px; border-radius: 8px; transition: background .12s, color .12s; }
.tl-view:hover { color: var(--brand-d); }
.tl-view.on { background: var(--surface); color: var(--brand-d); box-shadow: 0 1px 2px rgba(47,64,53,.12); }

/* From the school calendar: the year you uploaded once, brought back when it matters. */
.syr { background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--shadow); padding: 16px 16px 14px; margin-bottom: 16px; }
.syr-head h2 { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.12rem; margin: 0 0 10px; }
.syr-list { list-style: none; margin: 0; padding: 0; }
.syr-item { padding: 11px 0 11px 11px; border-left: 3px solid var(--line-strong); border-bottom: 1px solid var(--line); }
.syr-item:last-child { border-bottom: 0; padding-bottom: 2px; }
.syr-item.k-closed { border-left-color: var(--high); }
.syr-item.k-parent { border-left-color: var(--brand); }
.syr-item.k-early  { border-left-color: var(--gold); }
.syr-item.is-now { background: #fdfcf8; }
.syr-tags { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }
.syr-tag { font-size: .64rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em;
  border-radius: 20px; padding: 2px 8px; }
.syr-tag.t-closed { background: #fbe4df; color: var(--high); }
.syr-tag.t-parent { background: var(--brand-soft); color: var(--brand-d); }
.syr-tag.t-early  { background: #fdf3dd; color: #7a5b12; }
.syr-when { margin-left: auto; font-size: .7rem; font-weight: 800; color: var(--muted); }
.syr-msg { margin: 0; font-size: .88rem; line-height: 1.45; color: var(--ink); }

/* Upload review: the same three facts, shown as you confirm them. */
.uchip.closed { background: #fbe4df; color: var(--high); }
.uchip.parent { background: var(--brand-soft); color: var(--brand-d); }
.uchip.early  { background: #fdf3dd; color: #7a5b12; }
.uchip.holiday { background: var(--slate-soft); color: var(--slate); }
.syr-item.k-holiday { border-left-color: var(--slate); }
.syr-tag.t-holiday { background: var(--slate-soft); color: var(--slate); }
.pick-opt.is-empty { border-style: dashed; opacity: .85; }
.pick-meta.warn { color: var(--peach-ink); }

/* "Someone else": name a child who is not on the roster yet. */
.pick-other .pick-inline { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 9px; }
.pick-other input[type="text"] { font: inherit; font-size: .88rem; padding: 8px 11px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--surface); color: var(--ink); min-width: 170px; }
.pick-other input[type="text"]:focus { outline: none; border-color: var(--brand); }
.pick-remember { display: inline-flex; align-items: center; gap: 6px; font-size: .78rem; font-weight: 700; color: var(--muted); cursor: pointer; }
.pick-remember input { width: 16px; height: 16px; accent-color: var(--brand); margin: 0; }
.pick-error { margin: 0 0 10px; font-size: .84rem; font-weight: 700; color: var(--high); }

/* ---------- Family calendar: tighter, and a quiet day takes a quiet amount of room ---------- */
.tl-page .hero-row { gap: 8px; margin-bottom: 10px; }
.tl-page .hero-text { margin-bottom: 6px; }
.tl-page .display { margin-bottom: 2px; }
.tl-page .summary { margin: 0 0 10px; font-size: .92rem; }
.tl-page .board-actions { display: flex; flex-direction: row; flex-wrap: wrap; gap: 8px; margin: 0; }
.tl-page .tl-kidfilters { margin: 4px 0 12px; }
.tl-page .cal-layout { gap: 16px; }
.tl-page .cal { margin-top: 0; }
.tl-page .cal-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin-bottom: 8px; }
.tl-page .cal-title { margin: 0; }
.tl-page .cal-range { color: var(--muted); font-size: .82rem; }

/* An empty day needs a date and nothing else; only a busy day earns height. */
.tl-page .cal16-cell { min-height: 66px; padding: 7px 9px 8px; }
.tl-page .cal16-cell.is-empty { min-height: 46px; }
.tl-page .cal16-dayhead { margin-bottom: 4px; }
.tl-page .cal16-daynum { font-size: 1rem; }
.tl-page .cal16-cell.is-empty .cal16-daynum { color: #b9b2a1; font-weight: 500; }
.tl-page .cal16-cell.is-empty .cal16-dow { opacity: .6; }

@media (max-width: 560px) {
  .tl-page .board-actions .btn { flex: 1 1 auto; justify-content: center; }
  .tl-page .cal16-cell { min-height: 58px; padding: 6px 8px 7px; }
  .tl-page .cal16-cell.is-empty { min-height: 40px; }
  .tl-page .tl-views { width: 100%; justify-content: center; }
}

/* ---------- "Up next": one clear reading order — day, then what, then the quiet detail ---------- */
.tl-page .cal-aside { padding: 16px 14px 16px 16px; }
.tl-page .cal-aside-title { font-size: 1.1rem; margin: 0 0 4px; }

/* The day is a divider, not a shout: small, wide-tracked, and it owns the space above it. */
.tl-page .upnext-day { font-size: .66rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
  color: var(--faint, #8B8A7E); margin: 18px 0 2px; padding-top: 14px; border-top: 1px solid var(--line); }
.tl-page .upnext-day:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.tl-page .upnext-day.is-today { color: var(--peach-ink); }

.tl-page .upnext-item { display: flex; align-items: flex-start; gap: 10px; padding: 9px 0 9px 2px; }
.tl-page .un-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; margin-top: 7px;
  background: var(--line-2, var(--line)); }
.tl-page .un-body { min-width: 0; }

/* The title carries the meaning, so it gets the contrast; the child moves to the dot. */
.tl-page .upnext-title { display: block; font-size: .9rem; font-weight: 700; line-height: 1.4;
  color: var(--ink); text-wrap: pretty; }
.tl-page .un-meta { display: block; margin-top: 3px; font-size: .72rem; font-weight: 600; color: var(--muted); }
.tl-page .un-meta:empty { display: none; }
.tl-page .upnext-item.is-todo .upnext-title { font-weight: 800; }
.tl-page .upnext-item.is-todo .un-dot { background: var(--high); }

/* Secondary text people actually READ (a date, a time, who it is for) must carry its own
   contrast. Measured on the card surface #FCFAF5:
     --faint  #8B8A7E = 3.34:1  fails WCAG AA (4.5:1)
     --muted  #5E6B5E = 5.38:1  scrapes AA, still weak at 12px
     this     #4A574C = 7.30:1  passes AAA, and stays clearly below the ink of a title
   Small type needs MORE contrast, not less, so the hierarchy is carried by size and weight. */
:root { --muted-strong: #4A574C; }

.tl-page .upnext-day { color: var(--muted-strong); font-size: .7rem; letter-spacing: .08em; }
.tl-page .un-meta { color: var(--muted-strong); font-size: .78rem; font-weight: 600; letter-spacing: .01em; }
.tl-page .cal-range { color: var(--muted-strong); font-size: .84rem; }
.tl-page .cal16-dow { color: var(--muted-strong); }
.tl-page .cal16-cell.is-empty .cal16-daynum { color: #8B8A7E; }   /* decorative only, not read */

/* "Not on the list?" — naming a child the roster has never seen. */
.pick-add { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin: 14px 0 6px;
  padding-top: 14px; border-top: 1px solid var(--line); }
.pick-add-l { font-size: .84rem; font-weight: 700; color: var(--muted-strong); }
.pick-add .pick-inline { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.pick-add input[type="text"] { font: inherit; font-size: .88rem; padding: 8px 11px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--surface); color: var(--ink); min-width: 170px; }
.pick-add input[type="text"]:focus { outline: none; border-color: var(--brand); }

/* "This file names Penelope, but we read no events for her." A quiet, serious note: it is not
   an error (nothing failed) and not a hint (ignoring it loses a child's whole schedule). */
.umiss { border: 1px solid var(--peach-ink); border-left-width: 4px; border-radius: 12px;
  background: var(--peach-soft); padding: 14px 16px; margin: 0 0 18px; }
.umiss-head { margin: 0; color: var(--peach-ink); font-weight: 700; font-size: .95rem; line-height: 1.45; }
.umiss-body { margin: 6px 0 0; color: var(--peach-ink); font-size: .86rem; line-height: 1.5; opacity: .92; }

/* "We also read 3 events for Penelope." The sibling the question is not about. */
.pick-also { margin: 4px 0 14px; padding: 10px 12px; border-radius: 10px;
  background: var(--surface-2, rgba(0,0,0,.03)); color: var(--ink);
  font-size: .88rem; line-height: 1.5; }

/* ---- Pricing (landing) + trial ---- */
.pricing-cards { grid-template-columns: repeat(2, 1fr); max-width: 640px; margin: 0 auto; }
.pricing-cards .feature { display: flex; flex-direction: column; text-align: center; }
.pricing-cards .feature p { flex: 1; }
.price-line { margin: 2px 0 10px; color: var(--ink); }
.price-line strong { font-family: Fraunces, Georgia, serif; font-size: 2.2rem; font-weight: 700; }
.price-line span { color: var(--muted); font-size: 1rem; }
.pricing-note { text-align: center; margin-top: 18px; font-size: .9rem; }
@media (max-width: 700px) { .pricing-cards { grid-template-columns: 1fr; } }

/* Upgrade page / settings card plan choices. Two cards, side by side, both priced per month so
   the comparison is one subtraction ($9 against $12) rather than $108 against $12. They stay
   2-up on a phone — stacking them turns a comparison into a scroll, and the yearly plan below
   the fold is the one nobody picks. */
.pricing-choices { display: flex; gap: 14px; justify-content: center; align-items: stretch;
  margin: 22px 0 10px; }
.pricing-choices.left { justify-content: flex-start; }
.plan-choice { position: relative; flex: 1 1 0; min-width: 0; max-width: 240px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  background: var(--surface, #fff); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px 16px 14px; text-align: left; }
.plan-choice.best { border-color: var(--brand); box-shadow: 0 6px 20px rgba(31,45,33,.07); }
.plan-badge { position: absolute; top: -10px; right: 12px; background: var(--brand-soft);
  color: var(--brand-d); border-radius: 999px; padding: 3px 10px;
  font-size: .68rem; font-weight: 800; letter-spacing: .3px; text-transform: uppercase; }
.plan-name { font-size: .74rem; font-weight: 800; letter-spacing: .5px; text-transform: uppercase;
  color: var(--muted); }
.plan-price { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 2.1rem;
  line-height: 1.05; color: var(--ink); }
.plan-per { font-family: inherit; font-size: .95rem; font-weight: 600; color: var(--muted); }
/* The terms are not fine print: "billed annually" is what stops $9 reading as a monthly plan,
   so it sits with the price, above the button, never below it. */
.plan-terms { font-size: .78rem; line-height: 1.4; color: var(--muted); min-height: 2.2em; }
.plan-choice .btn { margin-top: 10px; width: 100%; justify-content: center; text-align: center; }
@media (max-width: 420px) {
  .pricing-choices { gap: 10px; }
  .plan-choice { padding: 14px 11px 12px; }
  .plan-price { font-size: 1.7rem; }
  .plan-terms { font-size: .72rem; }
  .plan-choice .btn { padding-left: 8px; padding-right: 8px; }
}

/* Slim trial banner, at the top of every in-app page (_trial_banner.html). It sat inside the
   dashboard's `.board-page` until it turned out the phone hides that element wholesale, which
   meant the one screen most parents actually open never mentioned the trial at all. */
.trial-bar { padding: 16px 0 0; }
.trial-banner { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; background: var(--brand-soft); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 10px 16px; margin-bottom: 0; font-size: .92rem; }
.trial-banner > span { display: inline-flex; align-items: center; gap: 8px; }
.trial-banner .ico-xs { width: 15px; height: 15px; }
/* Lapsed reads as a warning, not as a countdown: the sage banner was easy to skim past, and
   after expiry it is the difference between "nice to know" and "the app has stopped working". */
.trial-banner.ended { background: var(--peach-soft); border-color: var(--peach-ink);
  color: var(--peach-ink); font-weight: 700; }
.trial-banner.ended .btn { background: var(--peach-ink); border-color: var(--peach-ink); color: #fff; }

/* Upload: a visible, additive file picker. The native input replaced its whole selection each
   time it opened and showed nothing, so five files chosen one by one silently became one. */
/* The file input covers the drop zone, invisible but real: the tap lands on the control itself.
   The old 1px pointer-events:none box needed a programmatic input.click() from inside the
   surrounding <label> -- two activations per tap, which iOS Safari resolves by opening no picker
   at all. A real-sized control can also be focused, so a required-file message can actually be
   shown rather than the form refusing to submit silently. */
.up-input-file { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.up-input-hidden { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.up-field { display: block; }
.up-drop { position: relative; margin-top: 8px; display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 22px 16px; border: 2px dashed var(--line); border-radius: 14px; cursor: pointer;
  color: var(--muted-strong, #4A574C); text-align: center; transition: border-color .12s, background .12s; }
.up-drop:hover, .up-drop:focus-visible { border-color: var(--brand); background: var(--surface-2, rgba(0,0,0,.02)); outline: none; }
.up-drop.is-over { border-color: var(--brand); background: var(--peach-soft); color: var(--peach-ink); }
.up-drop-text strong { color: var(--ink); }
.up-drop-icon .ico { width: 22px; height: 22px; }
.up-list { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
/* Shown only if the browser did not attach the file: better a instruction than a dead button. */
.up-err { margin: 12px 0 0; padding: 10px 12px; border-radius: 10px; font-size: .92rem;
  color: var(--high); background: rgba(201,83,63,.08); border: 1px solid rgba(201,83,63,.35); }
.up-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.up-item-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink); font-size: .92rem; }
.up-item-size { color: var(--muted); font-size: .78rem; white-space: nowrap; }
.up-item-rm { border: none; background: none; cursor: pointer; font-size: 1.3rem; line-height: 1;
  color: var(--muted); padding: 0 4px; border-radius: 6px; }
.up-item-rm:hover { color: var(--peach-ink); background: var(--peach-soft); }

/* An upload event that already happened (a swim heat from earlier in the meet). Kept, not
   dropped, but visibly marked so a past date on the review screen reads as intended. */
.uchip.past { background: var(--surface-2, rgba(0,0,0,.05)); color: var(--muted-strong, #4A574C); }
.uchip.when.past { opacity: .8; }

/* Group an upload review by child, and tint an already-run event in the palette's peach so it
   reads as informational history, not a live to-do. */
.ugroup-head { margin: 18px 0 2px; font-family: "Fraunces", Georgia, serif; font-weight: 600;
  font-size: 1.02rem; color: var(--ink); padding-left: 2px; }
.ugroup-head:first-of-type { margin-top: 4px; }
.ucard.is-past { background: var(--peach-soft); border-color: var(--peach); }
.ucard.is-past .ucard-title { color: var(--peach-ink); }

/* Upload review: a row the reader could not fully read (no date, or a heat with no printed
   start time). We never guess it; we flag it so the parent can trust or fix it. */
.uchip.warn { background: var(--peach-soft); color: var(--peach-ink); font-weight: 700; }
.ucard-detail.warn { color: var(--peach-ink); font-size: .84rem; }

/* =========================================================================
   MOBILE APP SHELL — a Today-first, bottom-tab phone experience.
   Hidden on desktop; on the phone it replaces the board (and the top nav /
   footer) with an app-like shell. All markup lives in _mobile_shell.html.
   ========================================================================= */
.mshell { display: none; }
.m-subnav { display: none; }

@media (max-width: 899.98px) {
  /* On the phone the shell IS the app: retire the marketing chrome + the board. */
  body.app-shell .topbar,
  body.app-shell .site-footer { display: none; }
  body.app-shell .board-page { display: none; }
  body.app-shell main { padding: 0; margin: 0; }
  body.app-shell { background: var(--linen); }
  /* App-shell layout: the shell is exactly one screen tall, the middle scrolls, and the tab bar
     is the last row of it. The bar used to be `position: fixed`, which only stays put while
     nothing above it creates a containing block — one `transform`, `filter` or `will-change` on
     any ancestor and it silently detaches and floats into the middle of the content. As a flex
     row it is pinned by the layout itself, so there is nothing left to break.
     `dvh` follows iOS as the URL bar shows and hides; `vh` is the fallback and must come first. */
  /* Lock the page to the viewport so ONLY the middle scrolls.
     The tab bar kept floating into the content because the whole document was still scrollable
     behind it: the shell was one screen tall, but anything else in the document (a flash banner,
     a stray margin) made the body taller than the screen, and the body carried the bar up with
     it. Pinning the body removes the outer scroll entirely — there is no second scrollbar left
     to drag the bar anywhere. Everything below is a flex chain from the body down to the
     scrolling region, and each link needs `min-height: 0` or it refuses to shrink and pushes the
     bar back off-screen. */
  body.app-shell { position: fixed; inset: 0; overflow: hidden;
    display: flex; flex-direction: column; }
  body.app-shell main { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  /* Trial banner inside the phone shell: a fixed-height first row, so it takes its space from
     the scrolling region rather than pushing the tab bar off the bottom of the screen.
     `flex: 0 0 auto` is load-bearing for the same reason `min-height: 0` is below. */
  body.app-shell .trial-bar { flex: 0 0 auto; padding: 10px 22px 0; }
  body.app-shell .trial-bar .container { max-width: none; padding: 0; }
  .trial-bar .trial-banner { font-size: .86rem; padding: 9px 12px; }
  /* The button wraps to its own line on a narrow phone; full width makes it an easy tap
     target instead of a stub floating at the left edge. */
  .trial-bar .trial-banner .btn { flex: 1 0 auto; text-align: center; }
  .mshell { position: relative; flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column;
    background: var(--linen); color: var(--ink); overflow: hidden; }
  /* Kill the 300ms tap delay on every interactive control (UX: tap-delay). */
  .m-tab, .m-fab, .m-todo, .m-opt, .m-mrow, .m-resp-opt, .m-panel-go, .m-fchip, .m-resp { touch-action: manipulation; }

  .m-appbar { flex: 0 0 auto; z-index: 4; display: flex; align-items: center; gap: 9px;
    padding: 12px 22px 10px; background: var(--linen); }
  .m-logo { width: 30px; height: 30px; border-radius: 9px; background: var(--sage-soft);
    display: grid; place-items: center; flex: 0 0 auto; }
  .m-logo img { width: 20px; height: 20px; }
  .m-brand { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 17px; letter-spacing: .2px; }

  /* Higher specificity than `body.app-shell main { padding:0 }` above, which otherwise
     zeroes this main's side padding and leaves the cards flush to the screen edge. */
  /* The one scrolling region. `min-height: 0` is load-bearing: without it a flex child refuses
     to shrink below its content and the whole shell grows instead, which puts the tab bar back
     off-screen. The tab bar is a sibling now, so the bottom padding only has to clear the
     floating + button rather than the bar itself. */
  body.app-shell .m-screens { flex: 1 1 auto; min-height: 0; overflow-y: auto;
    -webkit-overflow-scrolling: touch; padding: 4px 22px 92px; }
  .m-screen { display: none; animation: mfade .22s ease both; }
  .m-screen.is-active { display: block; }
  @keyframes mfade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
  @media (prefers-reduced-motion: reduce) { .m-screen { animation: none; } }

  .m-greet { margin: 2px 0 8px; }
  .m-greet h2 { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 25px; line-height: 1.12; margin: 0; }
  .m-date { color: var(--muted); font-size: 14px; margin-top: 8px; font-weight: 600; }
  .m-head { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 24px; margin: 6px 0 2px; }
  .m-sub { color: var(--muted); font-size: 13.5px; margin: 0 0 6px; }

  /* kid filter chips */
  .m-filter { display: flex; gap: 8px; margin: 10px 0 2px; overflow-x: auto; padding-bottom: 3px;
    -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .m-filter::-webkit-scrollbar { display: none; }
  .m-fchip { all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
    padding: 9px 15px; min-height: 40px; box-sizing: border-box; border-radius: 22px; font-size: 13px;
    font-weight: 800; color: var(--muted); background: var(--band); border: 1px solid var(--line);
    touch-action: manipulation; }
  .m-fchip i { width: 9px; height: 9px; border-radius: 50%; }
  .m-fchip.is-on { color: #fff; border-color: transparent; background: var(--ink); }
  .m-fchip.is-on i { background: #fff !important; }
  .m-hidden { display: none !important; }

  /* time-of-day eyebrow */
  .m-eyebrow { display: flex; align-items: center; gap: 8px; margin: 22px 2px 9px; }
  .m-lbl { font-size: 11.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
  .m-lbl.needs { color: var(--brick); }
  .m-lbl.later { color: var(--sage-d); }
  .m-count { font-size: 11px; font-weight: 800; color: var(--brick); background: var(--brick-soft);
    border-radius: 20px; padding: 1px 8px; }
  .m-rule { flex: 1; height: 1px; background: var(--line); }

  /* event card */
  .m-ev { background: var(--surface); border: 1px solid var(--line);
    border-left: 4px solid var(--kc, var(--line)); border-radius: 14px; box-shadow: var(--shadow);
    padding: 11px 13px; margin-bottom: 9px; }
  .m-ev-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 28px; }
  .m-ev-time { font-size: 12.5px; font-weight: 800; color: var(--muted); font-variant-numeric: tabular-nums; }
  .m-ev-actions { display: flex; align-items: center; gap: 6px; }
  .m-ev-more { all: unset; cursor: pointer; color: var(--faint); width: 30px; height: 30px;
    display: grid; place-items: center; border-radius: 8px; touch-action: manipulation; }
  .m-ev-more svg { width: 18px; height: 18px; }
  .m-di-more { all: unset; cursor: pointer; color: var(--faint); margin-left: auto; align-self: center;
    width: 28px; height: 28px; display: grid; place-items: center; border-radius: 8px; touch-action: manipulation; flex: 0 0 auto; }
  .m-di-more svg { width: 16px; height: 16px; }
  /* reminder/task row: the "..." sits top-right, over the tappable card (a sibling, so it
     never toggles done); the card gets right padding so text clears the button. */
  .m-remrow { position: relative; }
  .m-remrow .m-todo { padding-right: 42px; }
  .m-rem-more { all: unset; cursor: pointer; color: var(--faint); position: absolute; top: 8px; right: 8px;
    width: 30px; height: 30px; display: grid; place-items: center; border-radius: 8px; touch-action: manipulation; }
  .m-rem-more svg { width: 18px; height: 18px; }
  .m-select { width: 100%; box-sizing: border-box; font: inherit; font-size: 16px; border: 1px solid var(--line);
    border-radius: 12px; padding: 11px 13px; margin-top: 8px; background: var(--surface); color: var(--ink); }
  .m-del-btn { margin-top: 10px; width: 100%; padding: 12px; border: 1px solid var(--brick); border-radius: 12px;
    background: transparent; color: var(--brick); font-weight: 800; font-size: 14px; cursor: pointer; touch-action: manipulation; }
  .m-ev-kid { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 800;
    color: var(--kc, var(--muted)); margin: 10px 0 1px; }
  .m-kdot { width: 8px; height: 8px; border-radius: 50%; background: var(--kc, var(--muted)); }
  .m-ev-title { font-size: 15.5px; font-weight: 800; color: var(--ink); line-height: 1.25; }
  .m-ev-note { display: flex; gap: 6px; align-items: flex-start; margin-top: 8px; background: var(--sage-soft);
    color: var(--sage-d); border-radius: 10px; padding: 6px 10px; font-size: 12px; line-height: 1.4; }
  .m-ev-note svg { width: 13px; height: 13px; flex: 0 0 auto; margin-top: 1px; }
  .m-ev-rsvp { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px;
    background: var(--peach-soft); color: var(--peach-ink); border-radius: 10px; padding: 6px 10px; font-size: 12px; line-height: 1.4; }
  .m-ev-rsvp svg { width: 13px; height: 13px; flex: 0 0 auto; }
  .m-rsvp-yes { font: inherit; font-size: 12px; font-weight: 700; border: 0; border-radius: 8px;
    padding: 4px 12px; background: var(--brand); color: #fff; cursor: pointer; margin-left: auto; }
  .m-rsvp-yes.mini { padding: 2px 9px; font-size: 11.5px; margin-left: 4px; }
  .m-di-rsvp { display: inline-flex; gap: 5px; align-items: center; font-size: 12.5px; font-weight: 600; color: var(--peach-ink); flex-wrap: wrap; }
  .m-rsvp-tag { display: inline-flex; gap: 3px; align-items: center; font-size: 11px; font-weight: 700; color: var(--sage-d); }
  .m-rsvp-tag svg { width: 12px; height: 12px; }

  /* who's got it: a chip that opens a small inline picker (native details) */
  .m-resp-wrap { position: relative; }
  .m-resp-wrap summary { list-style: none; }
  .m-resp-wrap summary::-webkit-details-marker { display: none; }
  .m-resp { cursor: pointer; display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px;
    min-height: 36px; box-sizing: border-box; border-radius: 20px; font-size: 12.5px; font-weight: 800;
    color: var(--ink); background: var(--band); border: 1px solid var(--line); touch-action: manipulation; }
  .m-resp.none { background: transparent; border: 1.5px dashed var(--line-2); color: var(--muted); }
  .m-rav { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center;
    font-size: 10.5px; font-weight: 800; color: #fff; background: var(--sage); margin-left: -3px; }
  .m-resp-menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 6; min-width: 180px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow);
    padding: 6px; display: flex; flex-direction: column; }
  .m-resp-opt { all: unset; cursor: pointer; padding: 9px 11px; border-radius: 8px; font-size: 13.5px;
    font-weight: 700; color: var(--ink); }
  .m-resp-opt:active { background: var(--band); }
  .m-resp-opt.clear { color: var(--muted); font-weight: 600; border-top: 1px solid var(--line); margin-top: 2px; }

  /* to-do rows */
  .m-todo { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; background: var(--surface);
    border: 1px solid var(--line); border-radius: 14px; margin-bottom: 9px; box-shadow: var(--shadow);
    cursor: pointer; text-align: left; width: 100%; font: inherit; color: inherit; }
  .m-todo.urgent { border-left: 4px solid var(--brick); }
  .m-check { flex: 0 0 auto; width: 24px; height: 24px; margin-top: 1px; border-radius: 8px;
    border: 2px solid var(--line-2); background: var(--surface); color: transparent; display: grid; place-items: center;
    transition: background .15s, border-color .15s, color .15s; }
  .m-check svg { width: 15px; height: 15px; }
  .m-todo-body { flex: 1; min-width: 0; }
  .m-todo-t { display: block; font-weight: 800; font-size: 14.5px; color: var(--ink); line-height: 1.3; }
  .m-todo-m { display: flex; align-items: center; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
  .m-due { font-size: 12px; font-weight: 700; color: var(--muted); }
  .m-due.hot { color: var(--brick); }
  .m-amt { font-size: 12px; font-weight: 800; color: var(--sage-d); background: var(--sage-soft);
    border-radius: 16px; padding: 1px 8px; }
  .m-todo-kid { font-size: 12px; font-weight: 700; color: var(--muted); }
  .m-forwho { font-size: 12px; font-weight: 800; color: var(--slate); background: var(--slate-soft);
    border-radius: 16px; padding: 1px 9px; }
  .m-repeat { font-size: 11px; font-weight: 800; color: var(--sage-d); background: var(--sage-soft);
    border-radius: 16px; padding: 1px 8px; letter-spacing: .02em; }
  /* landed here from "Edit that one": hold a ring on the card so it's obvious which one it is
     once the edit sheet is dismissed */
  .m-ev.is-focused, .m-di.is-focused { outline: 2px solid var(--brand); outline-offset: 2px;
    border-radius: 14px; }

  .m-todo.done .m-check { background: var(--sage); border-color: var(--sage); color: #fff; }
  .m-todo.done .m-todo-t { text-decoration: line-through; color: var(--muted); }
  .m-todo.done { opacity: .6; }

  /* Today's meals + shopping. These sit under the schedule, so they are deliberately quiet: a
     coloured eyebrow to tell them apart at a glance, then plenty of room to read. */
  .m-lbl.meals { color: var(--peach-ink); }
  .m-lbl.shop { color: var(--slate); }
  /* neutral counterpart to .m-count: how many, without the "you're late" red */
  .m-tally { font-size: 11px; font-weight: 800; color: var(--muted); background: var(--band);
    border: 1px solid var(--line); border-radius: 20px; padding: 1px 8px; }
  .m-eyelink { font-size: 12px; font-weight: 800; color: var(--sage-d); text-decoration: none;
    padding: 4px 2px; touch-action: manipulation; }

  /* one card, a line per meal; tapping anywhere opens today's three fields */
  .m-meals { display: block; width: 100%; text-align: left; font: inherit; color: inherit;
    background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--peach-soft);
    border-radius: 14px; box-shadow: var(--shadow); padding: 2px 16px 13px; margin-bottom: 9px;
    cursor: pointer; touch-action: manipulation; }
  .m-meal { display: flex; align-items: baseline; gap: 14px; padding: 13px 0; }
  /* border-TOP between rows, not bottom: the edit line below is a span too, so :last-of-type
     would land on it and leave a stray rule under the final meal. */
  .m-meal + .m-meal { border-top: 1px solid var(--line); }
  .m-meal-l { flex: 0 0 74px; font-size: 11.5px; font-weight: 800; letter-spacing: .07em;
    text-transform: uppercase; color: var(--muted); }
  .m-meal-n { flex: 1; min-width: 0; font-size: 15px; font-weight: 700; color: var(--ink); line-height: 1.35; }
  .m-meals-edit { display: flex; align-items: center; gap: 6px; padding-top: 12px;
    border-top: 1px solid var(--line); font-size: 12.5px; font-weight: 800; color: var(--sage-d); }
  .m-meals-edit svg { width: 14px; height: 14px; flex: 0 0 auto; }

  /* a quiet full-width row: "nothing planned today", "3 more to buy" */
  .m-thin { display: flex; align-items: center; justify-content: space-between; gap: 14px;
    width: 100%; box-sizing: border-box; text-align: left; font: inherit; font-size: 14px;
    font-weight: 800; color: var(--ink); text-decoration: none; cursor: pointer;
    background: var(--band); border: 1px dashed var(--line-2); border-radius: 14px;
    padding: 15px 16px; margin-bottom: 9px; touch-action: manipulation; }
  .m-thin span { font-size: 12.5px; font-weight: 700; color: var(--sage-d); flex: 0 0 auto; }

  /* one row of "who is eating something else" on Today: which meal, who, and what. */
  .m-altrow { display: grid; grid-template-columns: 5.9rem 1fr 1fr auto; gap: 6px;
    align-items: center; margin-bottom: 7px; }
  .m-altrow select, .m-altrow input { min-width: 0; margin: 0; }
  .m-altrow-x { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px; cursor: pointer;
    font-size: 17px; line-height: 1; color: var(--sage-d); background: var(--band);
    border: 1px solid var(--line); }
  .m-altrow-add { width: 100%; margin: 2px 0 4px; padding: 9px 12px; font: inherit;
    font-size: 13px; font-weight: 800; color: var(--sage-d); cursor: pointer;
    background: var(--band); border: 1px dashed var(--line-2); border-radius: 12px; }

  /* the caveat on a meal: who is joining it and how many to cook for. */
  .m-meal-guest { display: block; margin-top: 3px; font-size: 12px; font-weight: 700;
    color: var(--sage-d); }

  /* somebody eating with you who does not live here. Not a button: the dish is not what changes,
     the number of people eating it is, so there is nothing here to edit. */
  .m-guest { display: flex; align-items: center; gap: 8px; width: 100%; box-sizing: border-box;
    font-size: 13.5px; font-weight: 800; color: var(--ink); background: var(--sage-soft);
    border-radius: 14px; padding: 12px 14px; margin-bottom: 9px; }
  .m-guest svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--sage-d); }
  .m-guest span { margin-left: auto; font-size: 12.5px; font-weight: 700; color: var(--sage-d); }

  .m-store { font-size: 12px; font-weight: 800; color: var(--sage-d); background: var(--sage-soft);
    border-radius: 16px; padding: 1px 9px; }

  /* add to the list without leaving Today. 16px text or iOS zooms the whole page on focus. */
  .m-shopadd { display: flex; align-items: center; gap: 8px; margin: 2px 0 9px; }
  .m-shopadd input { flex: 1; min-width: 0; box-sizing: border-box; font: inherit; font-size: 16px;
    padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px;
    background: var(--surface); color: var(--ink); }
  .m-shopadd button { flex: 0 0 auto; width: 46px; height: 46px; border: 0; border-radius: 12px;
    background: var(--brand); color: #fff; display: grid; place-items: center; cursor: pointer;
    touch-action: manipulation; }
  .m-shopadd button svg { width: 20px; height: 20px; }

  /* information notes (no action): calmer, no checkbox, slate accent */
  .m-info { display: flex; gap: 12px; padding: 12px 14px; background: var(--band);
    border: 1px solid var(--line); border-radius: 14px; margin-bottom: 9px; }
  .m-info-i { flex: 0 0 auto; color: var(--slate); margin-top: 1px; }
  .m-info-i svg { width: 18px; height: 18px; }
  .m-info-b { flex: 1; min-width: 0; }
  .m-info-t { font-weight: 800; font-size: 14.5px; color: var(--ink); line-height: 1.3; }
  .m-info-d { font-size: 13px; color: var(--muted); margin-top: 3px; line-height: 1.4; }
  .m-info-kid { font-size: 12px; font-weight: 700; color: var(--muted); margin-top: 4px; }
  .m-info-when { font-size: 12px; font-weight: 700; color: var(--muted); margin-top: 2px; }
  .m-info-loc { font-weight: 600; color: var(--muted); font-size: .92em; }
  .m-info.away .m-info-i { color: var(--sage); }
  .m-info.locked .m-info-i { color: var(--muted); }
  .m-info-acts { display: flex; gap: 16px; align-items: center; margin-top: 8px; }
  .m-info-edit, .m-info-lock { all: unset; cursor: pointer; display: inline-flex; align-items: center;
    gap: 4px; font-size: 12px; font-weight: 700; color: var(--sage-d); }
  .m-info-edit svg, .m-info-lock svg { width: 12px; height: 12px; }
  .m-info-x { all: unset; cursor: pointer; flex: 0 0 auto; align-self: flex-start; color: var(--faint);
    font-size: 22px; line-height: 1; width: 26px; height: 26px; display: grid; place-items: center;
    border-radius: 8px; touch-action: manipulation; }

  /* week day rows */
  .m-day { display: flex; gap: 13px; padding: 14px 0; border-bottom: 1px solid var(--line-2); }
  .m-day:last-child { border-bottom: 0; }
  .m-daytile { flex: 0 0 44px; text-align: center; }
  .m-dow { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
  .m-num { font-family: "Fraunces", Georgia, serif; font-size: 22px; font-weight: 600; color: var(--ink); line-height: 1; margin-top: 2px; }
  .m-day.today .m-num, .m-day.today .m-dow { color: var(--peach-ink); }
  .m-dayitems { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
  /* Who is away, on each day of a trip. A quiet band rather than a row in the list: it is not
     something anyone does at a time, so it must not read as an appointment or take the time
     column. It sits above the day's items because it frames them. */
  .m-away { display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 700;
    color: var(--muted); background: var(--wash, rgba(0, 0, 0, .035)); border-radius: 8px;
    padding: 5px 9px; line-height: 1.3; }
  .m-away svg { width: 13px; height: 13px; flex: 0 0 auto; opacity: .75; }
  /* One row: dot · fixed-width time · title (fills, wraps under itself) · who + "..." at the
     right. Everything TOP-aligned so a two-line title never leaves the dot/time floating. */
  .m-di { display: flex; align-items: flex-start; gap: 9px; }
  .m-di .m-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; margin-top: 6px; }
  /* Capped, and allowed to wrap inside itself. The cell used to be flex:0 0 auto with no ceiling,
     so a window like "12:00 PM to 1:00 PM" grew the column and pushed "Meeting with Kamaya" onto
     two lines. A time may take two short lines; the title should not have to. */
  .m-di .m-tm { font-size: 12px; font-weight: 800; color: var(--muted); flex: 0 0 auto;
    min-width: 58px; max-width: 92px; margin-top: 3px; font-variant-numeric: tabular-nums;
    letter-spacing: -.01em; }
  /* On a phone the time wraps INSIDE its own column instead of holding the row open. "7:30 to
     9:30 PM" took 92px of a 280px row, and the title paid for it a word at a time. Two short
     lines of time cost nothing, because the title beside it is usually taller anyway. The row
     itself is unchanged: one line, dot then time then title then who. */
  @media (max-width: 430px) {
    .m-di .m-tm { max-width: 62px; }
  }
  .m-di .m-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; line-height: 1.4; }
  .m-di .m-di-t { font-size: 14px; font-weight: 700; color: var(--ink); }
  /* An open coordination item, named as one. Without this it read as an ordinary to-do titled
     with the raw sentence, so "Thursday's completely on me" looked like an errand. */
  .m-di .m-decide { display: inline-block; font-size: 10.5px; font-weight: 800; letter-spacing: .02em;
    text-transform: uppercase; color: var(--peach-ink, #9a5b3d); background: var(--peach, #fdeee5);
    border-radius: 5px; padding: 1px 5px; vertical-align: 1px; }
  /* "Good to know" prep note under a week item, so the invite's note (e.g. "self-shave before
     the appointment") is visible in the Week tab, matching the web app's card. */
  .m-di-note { display: flex; gap: 5px; align-items: flex-start; font-size: 12.5px; font-weight: 600;
    color: var(--muted); line-height: 1.35; }
  .m-di-note svg { width: 12px; height: 12px; flex: 0 0 auto; margin-top: 2px; }
  /* Week row: assign chip + "..." grouped at the right; the chip is compact (avatar when
     assigned, a small person-plus icon when not) so it fits the dense day list. */
  .m-di-actions { display: inline-flex; align-items: center; gap: 2px; flex: 0 0 auto; align-self: flex-start; margin-top: 1px; }
  .m-di-actions .m-di-more { margin-left: 0; }
  .m-resp.mini { padding: 5px 8px; font-size: 12px; font-weight: 800; border-radius: 999px; max-width: 120px;
    overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .m-resp.mini.none { color: var(--faint); padding: 6px; }
  .m-resp.mini svg { width: 17px; height: 17px; }
  .m-resp.mini .m-rav { width: 17px; height: 17px; font-size: 10px; }

  /* more list */
  .m-morelist { display: flex; flex-direction: column; gap: 10px; margin-top: 6px; }
  .m-mrow { display: flex; align-items: center; gap: 13px; padding: 15px; background: var(--surface);
    border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); text-decoration: none; color: inherit;
    width: 100%; box-sizing: border-box; font: inherit; text-align: left; cursor: pointer; -webkit-appearance: none; appearance: none; }
  .m-fam-hint { color: var(--muted); font-size: 13px; line-height: 1.5; margin: 10px 2px 12px; }
  .m-fam-hint svg, .m-fam-hint .ico { width: 13px; height: 13px; vertical-align: -2px; }
  .m-panel-hint { color: var(--muted); font-size: 12px; line-height: 1.4; margin: 2px 2px 4px; }
  .m-mi { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; flex: 0 0 auto; }
  .m-mi svg { width: 19px; height: 19px; }
  .m-mi.sage { background: var(--sage-soft); color: var(--sage-d); }
  .m-mi.peach { background: var(--peach-soft); color: var(--peach-ink); }
  .m-mi.slate { background: var(--slate-soft); color: var(--slate); }
  .m-mi.band { background: var(--band); color: var(--sage-d); }
  .m-mt { flex: 1; }
  .m-mt b { display: block; font-size: 15px; font-weight: 800; color: var(--ink); }
  .m-mt span { font-size: 12.5px; color: var(--muted); }
  .m-chev { color: var(--faint); display: grid; place-items: center; }
  .m-chev-i { width: 18px; height: 18px; }
  .m-flink { display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 12px 15px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; margin-bottom: 8px; }
  .m-flink-n { font-size: 14.5px; font-weight: 800; color: var(--ink); }
  .m-flink-b { all: unset; cursor: pointer; font-size: 12.5px; font-weight: 800; color: #fff;
    background: var(--sage); border-radius: 20px; padding: 7px 14px; touch-action: manipulation; flex: 0 0 auto; }
  /* family roster management (rename / copy / remove / add) */
  .m-fperson { display: flex; align-items: center; gap: 8px; padding: 8px 10px; background: var(--surface);
    border: 1px solid var(--line); border-radius: 12px; margin-bottom: 8px; }
  .m-frename { flex: 1; min-width: 0; }
  .m-fname { width: 100%; box-sizing: border-box; font: inherit; font-size: 15px; font-weight: 800; color: var(--ink);
    border: 1px solid transparent; background: transparent; border-radius: 8px; padding: 7px 8px; }
  .m-fname:focus { border-color: var(--line); background: var(--band); outline: none; }
  .m-fremove { flex: 0 0 auto; }
  .m-fx { all: unset; cursor: pointer; color: var(--muted); font-size: 20px; line-height: 1; padding: 4px 8px;
    border-radius: 8px; touch-action: manipulation; }
  .m-fx:hover { color: var(--brick); }
  .m-fadd { display: flex; gap: 8px; margin-top: 10px; }
  .m-fadd input { flex: 1; min-width: 0; box-sizing: border-box; font: inherit; font-size: 16px; border: 1px solid var(--line);
    border-radius: 12px; padding: 10px 12px; background: var(--surface); color: var(--ink); }
  .m-fadd-btn { flex: 0 0 auto; border: 0; border-radius: 12px; background: var(--sage); color: #fff; font-weight: 800;
    font-size: 14px; padding: 0 18px; cursor: pointer; touch-action: manipulation; }
  .m-acct { margin-top: 14px; padding: 13px 15px; border: 1px dashed var(--line-2); border-radius: 14px;
    display: flex; align-items: center; justify-content: space-between; gap: 10px; }
  .m-who2 { font-size: 12.5px; color: var(--muted); }
  .m-who2 b { color: var(--ink); font-weight: 800; word-break: break-all; }
  .m-acct a { font-size: 12.5px; font-weight: 800; color: var(--sage-d); text-decoration: none; flex: 0 0 auto; }

  .m-empty { text-align: center; color: var(--muted); font-size: 13.5px; padding: 22px 10px; line-height: 1.5; }
  .m-empty-big { display: block; font-family: "Fraunces", Georgia, serif; font-size: 18px; color: var(--sage-d); margin-bottom: 3px; }

  /* Floating add button. Absolute inside the shell, not fixed to the viewport: it sat above the
     tab bar by counting pixels, so it drifted with the bar for exactly the same reason. Anchored
     to the shell it keeps its place above the bar whatever the viewport does. */
  .m-fab { position: absolute; right: 18px; bottom: calc(90px + env(safe-area-inset-bottom)); width: 56px; height: 56px;
    border-radius: 50%; background: var(--sage); color: #fff; border: 0; cursor: pointer;
    box-shadow: 0 6px 16px -3px rgba(61,90,71,.6); display: grid; place-items: center; z-index: 7; }
  .m-fab svg { width: 26px; height: 26px; }
  .m-fab:active { transform: scale(.94); }

  /* Bottom tab bar: the last row of the shell, not a fixed overlay. `flex: 0 0 auto` keeps it at
     its natural height and pinned to the bottom edge by the layout, so it cannot drift into the
     content the way a fixed element does the moment any ancestor becomes its containing block. */
  .m-tabbar { flex: 0 0 auto; z-index: 8;
    display: grid; grid-template-columns: repeat(4, 1fr);
    background: rgba(246,242,234,.94); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border-top: 1px solid var(--line); padding-bottom: env(safe-area-inset-bottom); }
  .m-tab { all: unset; cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; padding: 10px 0 12px; color: var(--faint); position: relative; }
  .m-tab svg { width: 24px; height: 24px; }
  .m-tab span { font-size: 10.5px; font-weight: 800; }
  .m-tab.is-on { color: var(--sage-d); }
  .m-badge { position: absolute; top: 4px; left: calc(50% + 6px); min-width: 16px; height: 16px; padding: 0 4px;
    border-radius: 10px; background: var(--brick); color: #fff; font-size: 10px; font-weight: 800; display: grid; place-items: center; }

  /* Sub-pages (shopping/timeline/settings) keep the same bottom tab bar as the shell so the
     phone navigation never disappears; the top hamburger is retired on these pages. */
  body.subnav .nav-toggle { display: none; }
  /* The SAME anchoring the shell uses, for the same reason. This bar was `position: fixed`, and
     on a phone a fixed bottom bar moves every time the address bar animates: it drifted up over
     the content while scrolling Settings, which is the "it keeps moving" nobody could pin down.
     Pinning the body removes the outer scroll, so there is nothing left to drag the bar
     anywhere, and the bar becomes the last ROW of a flex column instead of an overlay.
     `min-height: 0` on the scrolling link is load-bearing: without it a flex child refuses to
     shrink below its content and pushes the bar back off the bottom of the screen. */
  body.subnav { position: fixed; inset: 0; overflow: hidden;
    display: flex; flex-direction: column; }
  body.subnav main { flex: 1 1 auto; min-height: 0; overflow-y: auto;
    -webkit-overflow-scrolling: touch; padding-bottom: 28px; }
  body.subnav .site-footer { display: none; }
  .m-subnav { flex: 0 0 auto; z-index: 8;
    display: grid; grid-template-columns: repeat(4, 1fr);
    background: rgba(246,242,234,.94); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border-top: 1px solid var(--line); padding-bottom: env(safe-area-inset-bottom); }
  .m-subnav .m-tab { text-decoration: none; }

  /* add sheet + scrim */
  .m-scrim { position: fixed; inset: 0; background: rgba(31,41,33,.32); opacity: 0; pointer-events: none;
    transition: opacity .2s; z-index: 9; }
  .m-scrim.open { opacity: 1; pointer-events: auto; }
  .m-sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 10; background: var(--surface);
    border-radius: 22px 22px 0 0; padding: 10px 18px calc(20px + env(safe-area-inset-bottom));
    transform: translateY(100%); transition: transform .26s cubic-bezier(.2,.8,.2,1); }
  .m-sheet.open { transform: translateY(0); }
  .m-grab { width: 40px; height: 4px; border-radius: 4px; background: var(--line-2); margin: 4px auto 12px; }
  .m-sheet h3 { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 18px; margin: 0 2px 12px; }
  .m-opt { display: flex; align-items: center; gap: 13px; padding: 13px 8px; border-radius: 12px; cursor: pointer;
    text-decoration: none; color: inherit; width: 100%; background: none; border: 0; font: inherit; text-align: left; }
  .m-opt:active { background: var(--band); }
  .m-oi { width: 40px; height: 40px; border-radius: 11px; background: var(--sage-soft); color: var(--sage-d);
    display: grid; place-items: center; flex: 0 0 auto; }
  .m-oi svg { width: 20px; height: 20px; }
  .m-opt b { display: block; font-size: 14.5px; color: var(--ink); }
  .m-opt span span, .m-opt > span > span { font-size: 12.5px; color: var(--muted); }
  .m-panel { display: none; padding: 6px 4px 4px; }
  .m-panel.open { display: block; }
  .m-panel textarea, .m-panel input[type="text"] { width: 100%; box-sizing: border-box; font: inherit; font-size: 16px;
    border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; background: var(--surface); color: var(--ink); resize: vertical; }
  .m-panel-row { display: flex; gap: 8px; margin-top: 8px; }
  .m-panel-row input { flex: 1; min-width: 0; box-sizing: border-box; font: inherit; font-size: 16px;
    border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; background: var(--surface); color: var(--ink); }
  /* date/time fields read as plain text with a "DD / MM / YYYY" / "hh:mm" hint until tapped */
  .m-panel-row input::placeholder { color: var(--faint); opacity: 1; }
  /* Assignee picker: tap a name. Same chip language as the kid filters, and a far better phone
     target than a dropdown — every option is visible at once and nothing opens over the sheet. */
  .m-who { display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 4px; }
  .m-whochip { all: unset; cursor: pointer; display: inline-flex; align-items: center; white-space: nowrap;
    padding: 9px 15px; min-height: 40px; box-sizing: border-box; border-radius: 22px; font-size: 14px;
    font-weight: 800; color: var(--muted); background: var(--band); border: 1px solid var(--line);
    touch-action: manipulation; }
  .m-whochip.is-on { color: #fff; border-color: transparent; background: var(--sage); }
  .m-whochip.is-new { color: var(--brand-d, #3a5a3a); background: transparent; border-style: dashed; }
  .m-whochip.is-new.is-on { color: #fff; background: var(--sage); border-style: solid; }
  .m-who-err { margin: 2px 2px 0; font-size: 12.5px; font-weight: 700; color: var(--high); }
  .m-panel-go { margin-top: 10px; width: 100%; padding: 12px; border: 0; border-radius: 12px; background: var(--sage);
    color: #fff; font-weight: 800; font-size: 15px; cursor: pointer; }
  /* Working state: the note goes to a language model and takes seconds. Say so, and make it
     obvious the tap landed, rather than leaving a button that looks untouched. */
  .m-panel-go.is-busy { opacity: .72; cursor: default; }
  .m-panel-go:disabled { cursor: default; }
  /* Way back to the list of options, so a panel is not a dead end. */
  .m-panel-back { background: none; border: 0; padding: 2px 2px 8px; margin: 0 0 2px -2px;
    font: inherit; font-size: 14px; font-weight: 700; color: var(--muted); cursor: pointer; }
  .m-panel-back:hover { color: var(--ink); }
  /* Roomier edit sheets: a clear label above each field so every piece of the item is visible. */
  .m-fld-lbl { display: block; font-size: 11.5px; font-weight: 800; letter-spacing: .03em;
    text-transform: uppercase; color: var(--muted); margin: 15px 2px 6px; }
  .m-editform > .m-fld-lbl:first-of-type { margin-top: 6px; }
  /* The one link in the edit sheet that reveals a field rather than doing something. Reads as a
     quiet offer, not a control competing with Save. */
  .m-fld-more { display: block; margin: 12px 0 2px; padding: 0; background: none; border: 0;
    font: inherit; font-size: 13px; font-weight: 600; color: var(--brand);
    text-decoration: underline; text-align: left; cursor: pointer; }
  .m-editform input[type="text"], .m-editform .m-select {
    width: 100%; box-sizing: border-box; font: inherit; font-size: 16px; margin: 0;
    border: 1px solid var(--line); border-radius: 12px; padding: 13px 13px;
    background: var(--surface); color: var(--ink); }
  .m-editform .m-panel-row { margin-top: 0; }
  .m-editform .m-panel-row input { padding: 13px 13px; }
  .m-editform .m-panel-go { margin-top: 20px; padding: 14px; font-size: 15.5px; }
  /* "private, not shared with family" lock on a schedule item, and the edit-sheet share toggle */
  .m-lock { display: inline-flex; align-items: center; margin-left: 6px; color: var(--faint); vertical-align: middle; }
  .m-lock svg, .m-lock .ico { width: 12px; height: 12px; }
  .m-share-row { display: flex; align-items: flex-start; gap: 10px; margin-top: 14px; cursor: pointer; }
  .m-share-row input { width: 20px; height: 20px; flex: 0 0 auto; accent-color: var(--sage); margin-top: 1px; }
  .m-share-row b { font-weight: 800; font-size: 14px; color: var(--ink); }
  .m-share-row small { display: block; color: var(--muted); font-size: 12px; line-height: 1.4; margin-top: 2px; }
  .m-notify { display: flex; align-items: center; gap: 10px; margin-top: 12px; font-size: 13.5px;
    color: var(--ink); cursor: pointer; touch-action: manipulation; }
  .m-notify input { width: 20px; height: 20px; flex: 0 0 auto; accent-color: var(--sage); }
  .m-notify em { font-style: normal; color: var(--faint); }
  .m-panel > input + input { margin-top: 8px; }
  @media (prefers-reduced-motion: reduce) { .m-sheet, .m-scrim { transition: none; } }
}

/* =========================================================================
   FAMILY APP — a login-free, installable per-person view (/family/<who>/<code>)
   with the shared Schedule + Shopping and that person's tasks. Standalone page
   (body.famapp), so unlike the phone shell these styles apply at ALL widths and
   centre to a phone-width column on desktop.
   ========================================================================= */
body.famapp { background: var(--linen); margin: 0; }
.fa-app { max-width: 520px; margin: 0 auto; min-height: 100vh; background: var(--linen); color: var(--ink); position: relative; }
.fa-appbar { position: sticky; top: 0; z-index: 4; display: flex; align-items: center; gap: 11px; padding: 13px 20px; background: var(--linen); }
.fa-logo { width: 34px; height: 34px; border-radius: 10px; background: var(--sage-soft); display: grid; place-items: center; flex: 0 0 auto; }
.fa-logo img { width: 22px; height: 22px; }
.fa-brand { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 18px; line-height: 1.05; display: flex; flex-direction: column; }
.fa-brand em { font-style: normal; font-family: "Nunito Sans", sans-serif; font-weight: 700; font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.fa-flash { margin: 4px 20px; background: var(--sage-soft); color: var(--sage-d); border-radius: 12px; padding: 10px 14px; font-size: 13.5px; font-weight: 700; }

.fa-screens { padding: 4px 20px calc(98px + env(safe-area-inset-bottom)); }
.fa-screen { display: none; animation: mfade .22s ease both; }
.fa-screen.is-active { display: block; }
.fa-head { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 24px; margin: 8px 0 2px; }
.fa-sub { color: var(--muted); font-size: 13.5px; margin: 0 0 6px; }
.fa-eyebrow { display: flex; align-items: center; gap: 8px; margin: 20px 2px 9px; }
.fa-lbl { font-size: 11.5px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--sage-d); }
.fa-rule { flex: 1; height: 1px; background: var(--line); }

.fa-ev { background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--kc, var(--line)); border-radius: 14px; box-shadow: var(--shadow); padding: 11px 13px; margin-bottom: 9px; }
.fa-ev-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 22px; }
.fa-ev-time { font-size: 12.5px; font-weight: 800; color: var(--muted); font-variant-numeric: tabular-nums; }
.fa-ev-kid { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 800; color: var(--kc, var(--muted)); margin: 9px 0 1px; }
.fa-kdot { width: 8px; height: 8px; border-radius: 50%; background: var(--kc, var(--muted)); }
.fa-ev-title { font-size: 15.5px; font-weight: 800; color: var(--ink); line-height: 1.25; }
.fa-forwho { font-size: 12px; font-weight: 800; color: var(--slate); background: var(--slate-soft); border-radius: 16px; padding: 2px 10px; }
.fa-note { margin-top: 8px; background: var(--sage-soft); color: var(--sage-d); border-radius: 10px; padding: 6px 10px; font-size: 12px; line-height: 1.4; }
/* Compact meal-plan day cards on the shared family app: one tight card per day. */
.fam-md { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 8px 11px; margin-bottom: 7px; }
.fam-md.today { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand-soft) inset; }
.fam-md-head { display: flex; align-items: baseline; gap: 7px; font-size: 12.5px; font-weight: 800; color: var(--ink); margin-bottom: 3px; }
.fam-md-head .today { font-size: 8.5px; font-weight: 800; letter-spacing: .4px; text-transform: uppercase; color: #fff; background: var(--brand); border-radius: 7px; padding: 1px 6px; }
.fam-md-row { display: flex; gap: 8px; font-size: 12.5px; line-height: 1.45; }
.fam-md-k { flex: 0 0 58px; color: var(--muted); font-weight: 800; font-size: 9.5px; text-transform: uppercase; letter-spacing: .03em; padding-top: 2px; }
.fam-md-v { color: var(--ink); font-weight: 700; min-width: 0; }

.fa-todo { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; margin-bottom: 9px; box-shadow: var(--shadow); cursor: pointer; text-align: left; width: 100%; font: inherit; color: inherit; touch-action: manipulation; }
.fa-check { flex: 0 0 auto; width: 24px; height: 24px; margin-top: 1px; border-radius: 8px; border: 2px solid var(--line-2); background: var(--surface); color: transparent; display: grid; place-items: center; transition: background .15s, border-color .15s, color .15s; }
.fa-check svg { width: 15px; height: 15px; }
.fa-todo-b { flex: 1; min-width: 0; }
/* Quiet by design: tidying up is a footnote to the list, not a call to action competing with it. */
.fa-clear { display: block; margin: 4px 0 8px; padding: 9px 14px; width: 100%; font: inherit;
  font-size: 13px; font-weight: 700; color: var(--muted); background: transparent;
  border: 1px dashed var(--line); border-radius: 12px; cursor: pointer; touch-action: manipulation; }
.fa-clear:hover { color: var(--ink); border-color: var(--line-2, var(--line)); }
.fa-clear:disabled { opacity: .5; cursor: default; }
.fa-todo-t { display: block; font-weight: 800; font-size: 14.5px; color: var(--ink); line-height: 1.3; }
.fa-by { font-weight: 600; font-size: 12px; color: var(--muted); margin-left: 8px; }
.fa-todo-m { display: flex; align-items: center; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
.fa-due { font-size: 12px; font-weight: 700; color: var(--muted); }
.fa-due.hot { color: var(--brick); }
.fa-repeat { font-size: 11px; font-weight: 800; color: var(--sage-d); background: var(--sage-soft); border-radius: 16px; padding: 1px 8px; }
.fa-todo.done .fa-check { background: var(--sage); border-color: var(--sage); color: #fff; }
.fa-todo.done .fa-todo-t { text-decoration: line-through; color: var(--muted); }
.fa-todo.done { opacity: .6; }

.fa-empty { text-align: center; color: var(--muted); font-size: 13.5px; padding: 30px 10px; line-height: 1.5; }
/* Today stacks up to three sections, so a quiet day would otherwise be 90px of empty middle.
   A short line under its own heading reads as "nothing here" without the hole. */
.fa-empty.tight { text-align: left; padding: 2px 2px 6px; }
.fa-empty b { display: block; font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 18px; color: var(--sage-d); margin-bottom: 3px; }

.fa-fab { position: fixed; bottom: calc(90px + env(safe-area-inset-bottom)); right: max(18px, calc(50% - 242px)); width: 56px; height: 56px; border-radius: 50%; background: var(--sage); color: #fff; border: 0; cursor: pointer; box-shadow: 0 6px 16px -3px rgba(61,90,71,.6); display: grid; place-items: center; z-index: 7; touch-action: manipulation; }
/* Full-width call to action inside a family-app section (e.g. open the meal planner). */
.fa-cta { display: block; text-align: center; background: var(--sage); color: #fff; font-weight: 800; font-size: 15px; text-decoration: none; border-radius: 16px; padding: 14px; margin: 2px 0 16px; box-shadow: 0 6px 16px -6px rgba(61,90,71,.5); }
.fa-cta:active { transform: scale(.99); }
.fa-fab svg { width: 26px; height: 26px; }
.fa-fab:active { transform: scale(.94); }

.fa-tabbar { position: fixed; bottom: 0; left: 50%; transform: translateX(-50%); width: 100%; max-width: 520px; z-index: 8; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; background: rgba(246,242,234,.94); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); border-top: 1px solid var(--line); padding-bottom: env(safe-area-inset-bottom); }
.fa-tab { all: unset; cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; padding: 10px 0 12px; color: var(--faint); position: relative; touch-action: manipulation; }
.fa-tab svg { width: 22px; height: 22px; }
.fa-tab span { font-size: 10px; font-weight: 800; }
.fa-tab.is-on { color: var(--sage-d); }
.fa-badge { position: absolute; top: 4px; left: calc(50% + 8px); min-width: 16px; height: 16px; padding: 0 4px; border-radius: 10px; background: var(--brick); color: #fff; font-size: 10px; font-weight: 800; display: grid; place-items: center; }

.fa-scrim { position: fixed; inset: 0; background: rgba(31,41,33,.32); opacity: 0; pointer-events: none; transition: opacity .2s; z-index: 9; }
.fa-scrim.open { opacity: 1; pointer-events: auto; }
.fa-sheet { position: fixed; bottom: 0; left: 50%; transform: translateX(-50%) translateY(100%); width: 100%; max-width: 520px; z-index: 10; background: var(--surface); border-radius: 22px 22px 0 0; padding: 10px 20px calc(20px + env(safe-area-inset-bottom)); transition: transform .26s cubic-bezier(.2,.8,.2,1); box-sizing: border-box; }
.fa-sheet.open { transform: translateX(-50%) translateY(0); }
.fa-grab { width: 40px; height: 4px; border-radius: 4px; background: var(--line-2); margin: 4px auto 12px; }
.fa-form { display: none; }
.fa-form h3 { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 18px; margin: 0 0 12px; }
.fa-form textarea, .fa-form input[type="text"] { width: 100%; box-sizing: border-box; font: inherit; font-size: 16px; border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px; background: var(--surface); color: var(--ink); resize: vertical; }
.fa-form input + input { margin-top: 8px; }
.fa-row { display: flex; gap: 8px; margin-top: 8px; }
.fa-row input { flex: 1; min-width: 0; box-sizing: border-box; font: inherit; font-size: 16px; border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px; background: var(--surface); color: var(--ink); }
.fa-row input::placeholder { color: var(--faint); opacity: 1; }
.fa-go { margin-top: 10px; width: 100%; padding: 13px; border: 0; border-radius: 12px; background: var(--sage); color: #fff; font-weight: 800; font-size: 15px; cursor: pointer; }
@media (prefers-reduced-motion: reduce) { .fa-sheet, .fa-scrim, .fa-screen { transition: none; animation: none; } }

/* Family app: "turn on notifications" banner */
.fa-notif { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 4px 0 10px;
  background: var(--sage-soft); color: var(--sage-d); border-radius: 12px; padding: 11px 13px; font-size: 13px; font-weight: 700; }
.fa-notif button { all: unset; cursor: pointer; flex: 0 0 auto; background: var(--sage); color: #fff;
  font-size: 12.5px; font-weight: 800; border-radius: 20px; padding: 8px 15px; touch-action: manipulation; }

/* Assign-a-task modal (desktop board) */
.modal-sub { color: var(--muted); margin: 0 0 8px; }
.modal-row2 { display: flex; gap: 10px; }
.modal-row2 label { flex: 1; }
.modal-check { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: .9rem; color: var(--ink); cursor: pointer; }
.modal-check input { width: 18px; height: 18px; flex: 0 0 auto; accent-color: var(--brand); }

/* Desktop: assigned-tasks group under Needs attention */
.rem-for { font-size: .72rem; font-weight: 800; color: var(--appt); background: var(--appt-soft); border-radius: 12px; padding: 1px 8px; }
.rem-weekly { font-size: .68rem; font-weight: 800; color: var(--brand-d); background: var(--brand-soft); border-radius: 12px; padding: 1px 7px; letter-spacing: .02em; }
.rem-share { display: inline-flex; align-items: center; gap: 5px; margin-top: 7px; font-size: .74rem; font-weight: 700;
  color: var(--brand-d); background: none; border: 1px solid var(--line); border-radius: 8px; padding: 4px 9px; cursor: pointer; }
.rem-share:hover { background: var(--band); }
.rem-share .ico { width: 13px; height: 13px; }
.task-group .attn-group-head span:first-child { color: var(--appt); }

/* Mobile "Share with family" chooser */
.m-share-picks { display: flex; gap: 16px; margin: 2px 0 12px; flex-wrap: wrap; }
.m-share-url { flex: 1; min-width: 0; box-sizing: border-box; font: inherit; font-size: 12.5px;
  border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; background: var(--band); color: var(--ink); }

/* Family app: who-are-you picker, tasks header, assigner tag */
.fa-who { margin-left: auto; font-size: 11.5px; font-weight: 700; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.fa-who select { font: inherit; font-size: 13.5px; font-weight: 800; color: var(--ink); border: 1px solid var(--line);
  border-radius: 10px; padding: 5px 8px; background: var(--surface); }
.fa-tasks-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.fa-showall { font-size: 12.5px; font-weight: 700; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; cursor: pointer; white-space: nowrap; }
.fa-showall input { width: 16px; height: 16px; accent-color: var(--sage); }
.fa-bywho { font-size: 12px; font-weight: 700; color: var(--muted); background: var(--band); border-radius: 16px; padding: 1px 8px; }
.fa-select { width: 100%; box-sizing: border-box; font: inherit; font-size: 16px; border: 1px solid var(--line);
  border-radius: 12px; padding: 11px 13px; margin-top: 8px; background: var(--surface); color: var(--ink); }
/* the eyebrow shares the row with "Show everyone", so it has to claim the leftover width */
.fa-tasks-head .fa-eyebrow { flex: 1; min-width: 0; }

/* Family app: shopping row with a "..." for renaming, matching the main app's task rows */
.fa-shoprow { position: relative; }
.fa-shoprow .fa-todo { padding-right: 44px; }
.fa-row-more { all: unset; cursor: pointer; color: var(--faint); position: absolute; top: 8px; right: 8px;
  width: 32px; height: 32px; display: grid; place-items: center; border-radius: 8px; touch-action: manipulation; }
.fa-row-more svg { width: 18px; height: 18px; }
.fa-del { margin-top: 12px; width: 100%; padding: 13px; border: 1px solid var(--brick); border-radius: 12px;
  background: transparent; color: var(--brick); font: inherit; font-weight: 800; font-size: 15px;
  cursor: pointer; touch-action: manipulation; }

/* Family app: today's meals, one line each */
.fa-meals { background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow); padding: 2px 15px 3px; margin-bottom: 9px; }
.fa-meal { display: flex; align-items: baseline; gap: 14px; padding: 13px 0; }
.fa-meal + .fa-meal { border-top: 1px solid var(--line); }
.fa-meal-l { flex: 0 0 74px; font-size: 11.5px; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); }
.fa-meal-n { flex: 1; min-width: 0; font-size: 15px; font-weight: 700; color: var(--ink); line-height: 1.35; }
/* who is joining this meal, and how many to cook for -- said on the meal, for whoever cooks. */
.fa-meal-guest { display: block; margin-top: 2px; font-size: 12.5px; font-weight: 700;
  color: var(--sage-d, #4F745B); }
.fam-md-who.guest { color: var(--sage-d, #4F745B); }

/* Family app: "what are you adding?" — shown only where more than one answer makes sense */
.fa-pick h3 { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 18px; margin: 0 0 12px; }
.fa-pickopt { display: block; width: 100%; text-align: left; font: inherit; cursor: pointer;
  background: var(--band); border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px;
  margin-bottom: 9px; touch-action: manipulation; }
.fa-pickopt b { display: block; font-size: 15px; font-weight: 800; color: var(--ink); }
.fa-pickopt span { display: block; margin-top: 3px; font-size: 12.5px; font-weight: 600; color: var(--muted); line-height: 1.4; }
/* The say-it box in the family sheet. 16px on the textarea is not a style choice: anything
   smaller makes iOS zoom the page on focus, which is the recurring "the layout jumps" bug. */
.fa-saybox { display: block; }
.fa-saybox textarea { font-size: 16px; line-height: 1.5; }
.fa-saybox-hint { margin: 8px 0 0; font-size: 12.5px; font-weight: 600; color: var(--muted); line-height: 1.45; }
.fa-oneat { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 16px; padding-top: 13px; border-top: 1px solid var(--line); }
.fa-oneat > span { font-size: 12.5px; font-weight: 700; color: var(--muted); }
.fa-oneat-b { font: inherit; font-size: 13px; font-weight: 800; cursor: pointer;
  color: var(--sage-d); background: var(--band); border: 1px solid var(--line);
  border-radius: 999px; padding: 7px 14px; touch-action: manipulation; }

.fa-back { all: unset; cursor: pointer; display: inline-block; font-size: 13px; font-weight: 800;
  color: var(--sage-d); padding: 2px 0 10px; touch-action: manipulation; }

.fam-picks { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 4px; }

/* Share-with-family: member chips (desktop modal) */
.fam-members { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 10px; }
.fam-chip { display: inline-flex; align-items: center; gap: 2px; background: var(--band); border: 1px solid var(--line);
  border-radius: 20px; padding: 4px 6px 4px 13px; font-size: .85rem; font-weight: 700; color: var(--ink); }
.fam-chip .inline-form { display: inline-flex; margin: 0; }
.fam-chip-x { all: unset; cursor: pointer; color: var(--muted); font-size: 16px; line-height: 1; padding: 0 4px; }
.fam-chip-x:hover { color: var(--high); }
.fam-add { display: flex; gap: 8px; margin-bottom: 4px; }
.fam-add input { flex: 1; }

/* Share dialog: include-member checkboxes */
.m-who-flag { width: 20px; height: 20px; flex: 0 0 auto; accent-color: var(--sage); }
.fam-chip input.who-flag { width: 15px; height: 15px; accent-color: var(--brand); margin-right: 3px; }

/* "only for Neil" on a meal, so a glance doesn't imply the whole family is eating it. Top level,
   not inside the phone media query: the class only ever appears in the mobile shell anyway. */
.m-meal-who { display: inline-block; margin-left: 7px; padding: 1px 8px; border-radius: 999px;
  background: var(--peach-soft); color: var(--peach-ink); font-size: 10.5px; font-weight: 800;
  vertical-align: middle; }

/* How often a reminder or task comes back (daily / weekly / monthly / yearly). Top level, not
   inside the phone media query: the same partial is included in the desktop task modal. */
.kw-repeat { display: block; margin-top: 14px; }
.kw-repeat-lbl { display: block; font-size: 11.5px; font-weight: 800; letter-spacing: .03em;
  text-transform: uppercase; color: var(--muted); margin: 0 2px 6px; }
.kw-repeat select { margin-top: 0; }
.kw-repeat-hint { color: var(--muted); font-size: 12px; line-height: 1.4; margin: 6px 2px 0; }

/* ---- "Just say it": one box that takes the whole thought ----
   Primary and open on arrival, because choosing a category from a list before typing was asking
   the parent to do the sorting this app exists to do. The one-at-a-time doorways live under a
   quiet disclosure below. Top level, not inside the phone media query, so the sheet reads the
   same on a tablet. */
.m-addbox { margin: 2px 0 4px; }
.m-addbox textarea { width: 100%; box-sizing: border-box; font: inherit; font-size: 16px;
  line-height: 1.45; padding: 13px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--surface); color: var(--ink); resize: vertical; }
.m-addbox-hint { color: var(--muted); font-size: 12.5px; line-height: 1.45; margin: 8px 2px 10px; }
.m-addbox-go { display: flex; align-items: center; gap: 10px; }
.m-addbox-go .m-panel-go { flex: 1 1 auto; margin-top: 0; }
.m-addbox-clip { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
  color: var(--ink); text-decoration: none; font-size: 13px; font-weight: 700; }
.m-addbox-clip svg { width: 17px; height: 17px; }
.m-addmore { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 6px; }
.m-addmore > summary { list-style: none; cursor: pointer; padding: 10px 2px; font-size: 13.5px;
  font-weight: 700; color: var(--muted); }
.m-addmore > summary::-webkit-details-marker { display: none; }
.m-addmore > summary::after { content: " ›"; }

/* A row on the review screen shows only the fields its filing needs, so nothing asks which kid
   a bottle of milk is for. Hidden ones are display:none rather than just [hidden], because a
   flex row would otherwise keep their gap. */
.clarify-item [hidden] { display: none !important; }

/* ---- The exchange on the review screen ----
   The parent typed a paragraph and got back a wall of form rows with no sign anything had been
   understood. Showing what they said, and what was heard, is the difference between "did it get
   me?" and "yes, and here it is to check". */
.chat-said { position: relative; margin: 10px 0 0; padding: 12px 14px; border-radius: 14px 14px 14px 4px;
  background: var(--brand-soft, #eef3ee); color: var(--ink); font-size: .95rem; line-height: 1.5;
  white-space: pre-wrap; overflow-wrap: anywhere; }
.chat-who { display: block; font-size: .7rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 4px; }
.chat-reply { display: flex; gap: 10px; align-items: flex-start; margin: 12px 0 18px; }
.chat-reply p { margin: 0; font-size: 1rem; line-height: 1.55; color: var(--ink); }
.chat-dot { flex: 0 0 auto; width: 10px; height: 10px; margin-top: 7px; border-radius: 50%;
  background: var(--brand, #2F6F9E); }

/* ---- The review, grouped ----
   Every reminder together, every meal change together. Eight rows in the order the sentence
   happened to come out makes the parent hold the sorting in their own head, which is the job the
   box exists to do for them. */
.ci-group + .ci-group { margin-top: 18px; }
.ci-group-h { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: .82rem;
  font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.ci-group-n { display: inline-grid; place-items: center; min-width: 20px; height: 20px;
  padding: 0 6px; border-radius: 999px; background: var(--brand-soft, #eef3ee);
  color: var(--brand-d, #3a5a3a); font-size: .72rem; font-weight: 800; letter-spacing: 0; }
.ci-group-body { display: flex; flex-direction: column; gap: 14px; }

/* ---- The review, ordered by what needs her ----
   Twenty one cards demanding equal attention, when five actually need her, costs more than the
   typing it replaced. A group where nothing needs her folds to one line; folding never changes
   what gets saved, only what she has to read. */
.ci-group-t { display: flex; align-items: center; gap: 8px; width: 100%; padding: 4px 0;
  background: none; border: 0; font: inherit; font-size: .82rem; font-weight: 800;
  letter-spacing: .05em; text-transform: uppercase; color: var(--muted); cursor: pointer;
  text-align: left; }
.ci-group-caret { flex: 0 0 auto; width: 7px; height: 7px; border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor; transform: rotate(-45deg); opacity: .7; transition: transform .15s; }
.ci-group-t[aria-expanded="true"] .ci-group-caret { transform: rotate(45deg); }
.ci-group-ok { text-transform: none; letter-spacing: 0; font-weight: 600; color: var(--faint); }
.ci-group-need { text-transform: none; letter-spacing: 0; font-weight: 800; color: var(--peach-ink); }
.ci-need, .ci-guess { margin: 0 0 8px; font-size: .84rem; font-weight: 700; }
.ci-need { color: var(--peach-ink); }
.ci-guess { color: var(--muted); font-weight: 600; }
.clarify-item[data-attention="blocked"] { border-left: 3px solid var(--peach-ink); padding-left: 11px; }
.ci-whensaid { margin: 6px 0 0; font-size: .86rem; color: var(--muted); }
.ci-whensaid strong { color: var(--ink); }

/* One tick includes or drops a whole group. Never a submit: there is exactly one submission, at
   the bottom, for everything on the screen. */
/* `.form input { width: 100% }` above outranks a single class (one class plus an element beats
   one class, whatever the order), so the tick was laid out as a full-width block and pushed
   every group name off the right edge of the card. Nothing was wrong with the ticks or the
   folding: you simply could not read a single heading. Scoped here so it wins on specificity
   rather than on luck. */
.form .ci-group-h .ci-group-all,
.form .ci-group-all { width: 18px; height: 18px; min-width: 18px; flex: 0 0 auto; margin: 0;
  padding: 0; border-radius: 4px; accent-color: var(--brand, #2F6F9E); cursor: pointer; }
.form .ci-group-all:disabled { opacity: .35; cursor: default; }
/* Same trap, same fix: a heading must be allowed to shrink, or a long group name in a flex row
   pushes its own count off the edge. */
.ci-group-t { min-width: 0; }
.ci-group-t, .ci-group-h { flex-wrap: wrap; }

/* ---- Household rules ----
   Amber, not green, and named as what they are. A nut allergy is not a Tuesday item: it outlives
   the week, it changes what the meal planner will ever suggest, and it lands in Settings on the
   person it is about rather than on the plan. Different consequence, different colour. */
.ci-group[data-group="rule"] .ci-group-t { color: var(--peach-ink); }
.ci-group[data-group="rule"] .ci-group-n { background: var(--peach-soft); color: var(--peach-ink); }
.ci-group[data-group="rule"] .clarify-item { border-left: 3px solid var(--peach-ink); padding-left: 11px; }
.ci-group[data-group="rule"] .ci-group-body::before {
  content: "Saved to Settings for that person, not added to your week. These stay until you change them.";
  display: block; margin-bottom: 10px; font-size: .84rem; color: var(--peach-ink); }
.ci-until { display: inline-flex; align-items: center; gap: 7px; font-size: .82rem; font-weight: 700;
  color: var(--muted); }

/* ---- A helper's jobs, grouped by the person who has to do them ----
   The action on these is not "add to a week", it is "ask Josephine". Four jobs for one person
   are one conversation with her, not four, and the screen should read that way before the
   sending does. */
.ci-person + .ci-person { margin-top: 14px; }
.ci-person-h { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.ci-person-n { font-size: .95rem; font-weight: 800; color: var(--ink); }
.ci-person-c { display: inline-grid; place-items: center; min-width: 20px; height: 20px;
  padding: 0 6px; border-radius: 999px; background: var(--brand-soft, #eef3ee);
  color: var(--brand-d, #3a5a3a); font-size: .72rem; font-weight: 800; }
.ci-person-note { font-size: .78rem; color: var(--faint); }

/* The same idea on the photographed review: whose jobs these are, said once above them. */
.uperson-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 14px 0 6px; font-size: .95rem; font-weight: 800; color: var(--ink); }
.uperson-head:first-child { margin-top: 0; }
.uperson-note { font-size: .78rem; font-weight: 500; color: var(--faint); }

/* A clash is the one thing on the review a parent cannot work out by reading: two rows forty
   lines apart that happen to be the same Tuesday at four. */
.ci-clash { display: flex; align-items: flex-start; gap: 6px; margin: 0 0 8px; font-size: .84rem;
  font-weight: 700; color: var(--peach-ink); }
.ci-clash svg, .ci-clash .ico { width: 15px; height: 15px; flex: 0 0 auto; margin-top: 1px; }
.clarify-item[data-attention="check"]:has(.ci-clash) { border-left: 3px solid var(--peach-ink);
  padding-left: 11px; }

/* The verdict, on the upload review as well as the typed one. Same sentence, same helpers. */
.usum-verdict { margin: 0 0 4px; font-size: 1rem; font-weight: 800; color: var(--peach-ink); }
.usum-verdict.ok { color: var(--brand-d, #3a5a3a); }
.ucard[data-attention="blocked"] { border-left: 3px solid var(--peach-ink); }

/* A clash, said on the PLAN and not only on the review screen. Two 10:30 items for one child,
   forty lines apart, is the thing a parent cannot spot by reading; the warning used to exist
   for one screen and then be gone forever. Same words as the review, so one collision is never
   described two ways. */
.m-di-clash { display: flex; gap: 5px; align-items: flex-start; font-size: 12.5px; font-weight: 700;
  color: var(--peach-ink, #9a5b3d); line-height: 1.35; }
.m-di-clash svg { width: 12px; height: 12px; flex: 0 0 auto; margin-top: 2px; }

/* Where a group's items actually GO, said on the group. "Add to my week" is the only button on
   the screen, and a household rule does not live on a week: a parent who then looked for a nut
   allergy on Tuesday concluded it had been lost. */
.ci-group-note { margin: 0 0 10px; font-size: .84rem; font-weight: 600; color: var(--muted, #666);
  line-height: 1.4; }

/* What the read walked past. "14 items and they all look right" over a paragraph holding
   twenty-five instructions is the failure that hides every other failure: nothing about the
   answer suggests going to look. Quiet, but present, and never folded away. */
.ci-missed { margin: 0 0 14px; padding: 10px 12px; border: 1px dashed var(--line, #ddd);
  border-radius: 10px; background: var(--wash, rgba(0, 0, 0, .02)); }
.ci-missed-h { display: flex; gap: 6px; align-items: center; margin: 0 0 6px; font-size: .88rem;
  font-weight: 800; color: var(--muted, #666); }
.ci-missed-h svg { width: 14px; height: 14px; flex: 0 0 auto; }
.ci-missed ul { margin: 0 0 6px; padding-left: 18px; }
.ci-missed li { font-size: .88rem; line-height: 1.45; margin-bottom: 3px; }
.ci-missed-f { margin: 0; font-size: .82rem; color: var(--muted, #666); }

/* The one meal row that DELETES. It sits with the meal controls but reads as a sentence, not a
   field, because a row that removes a week of dinners must not look like a row that adds one. */
.ci-clearmeal { display: flex; align-items: center; gap: 7px; font-size: .86rem; font-weight: 700;
  color: var(--peach-ink, #9a5b3d); }
.form .ci-clearmeal input[type="checkbox"] { width: 16px; height: 16px; flex: 0 0 auto; }

/* How many are set, on the closed summary. The whole point of folding these away is that a
   parent can see whether anything is there without opening four lists. */
.fs-count { display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px;
  border-radius: 999px; background: var(--brand-soft, #e6ede8); color: var(--brand, #4F745B);
  font-size: .72rem; font-weight: 800; text-align: center; vertical-align: 1px; }

/* Clearing a limit from the warning itself. It has no list in Settings any more, so this is the
   only place it can go; a rule you cannot clear is worse than no rule. */
.m-limit-x { all: unset; cursor: pointer; margin-left: 6px; font-size: 11.5px; font-weight: 800;
  color: var(--sage-d); text-decoration: underline; touch-action: manipulation; }

/* The hint above an empty day or time box on the review screen. A date input takes no
   placeholder, so on a phone an empty one reads "dd/mm/yyyy" and says neither which date it
   wants nor that it is the thing holding the row up. Shown only while the field is empty. */
.ci-field { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ci-fieldhint { font-size: .68rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
  color: var(--peach-ink, #B5573F); padding-left: 2px; }
.form .ci-field > input { width: 100%; }

/* The optional inbox offer, shown to a household that has never had one (see
   _connect_inbox.html). Deliberately NOT styled like the reconnect banner above it: that one is
   a problem to fix and wears warning colours, this is an offer somebody is free to decline, and
   dressing an offer as an alert is how a family learns to ignore both. Quiet surface, brand
   accent on the rule, and "Not now" reads as a real choice rather than a dead end. */
.ci-card { border: 1px solid var(--line); border-left: 3px solid var(--brand);
  background: var(--surface); border-radius: 14px; padding: 16px 18px; margin-bottom: 18px; }
.ci-title { font-size: 1.02rem; margin: 0 0 6px; display: flex; align-items: center; gap: 9px; }
.ci-opt { font-size: .68rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); border: 1px solid var(--line); border-radius: 999px; padding: 2px 8px; }
.ci-lead { margin: 0 0 10px; font-size: .9rem; line-height: 1.5; color: var(--ink2, var(--ink)); }
.ci-facts { list-style: none; margin: 0 0 13px; padding: 0; display: grid; gap: 5px; }
.ci-facts li { display: flex; align-items: flex-start; gap: 8px; font-size: .84rem; color: var(--muted); }
.ci-facts .ico { flex: 0 0 auto; margin-top: 2px; }
.ci-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ci-actions form { margin: 0; }
.ci-no { background: none; border: none; padding: 6px 4px; font: inherit; font-size: .85rem;
  color: var(--muted); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.ci-no:hover, .ci-no:focus-visible { color: var(--ink); }
/* On the phone it sits inside the Today screen, which has its own 12px gutter. */
.m-screen .ci-card { margin: 10px 12px 0; }

/* Trial ended. Centred, generous, and short: the parent is locked out and their first question
   is whether their data survived, not which plan to compare. */
.te-page { display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 0; padding-top: 8vh; max-width: 460px; }
.te-mark { width: 72px; height: 72px; border-radius: 18px; margin-bottom: 26px; }
.te-title { font-size: clamp(1.7rem, 5vw, 2.1rem); font-weight: 800; margin: 0 0 14px;
  letter-spacing: -.01em; }
.te-lead { font-size: 1.05rem; line-height: 1.6; color: var(--muted); margin: 0 0 30px; }
.te-go { width: 100%; }
.te-go .btn { width: 100%; }
.te-alt { margin: 18px 0 0; }
/* A button that reads as a link: it posts a form (the yearly plan), so it cannot be an <a>. */
.te-link { display: inline-block; background: none; border: 0; padding: 6px 4px; cursor: pointer;
  font: inherit; font-size: .95rem; font-weight: 700; color: var(--brand); text-decoration: none; }
.te-link:hover { color: var(--brand-d); text-decoration: underline; }
a.te-link { margin-top: 10px; }
.te-help { margin-top: 6px; font-size: .9rem; color: var(--muted); text-decoration: none; }
.te-help:hover { text-decoration: underline; }

/* "Which email?" / "Which calendar?" — tappable provider cards.
   prov-, NOT pick-: upload_pick_child and upload_pick_owner already own .pick-list, .pick-name
   and .pick-other, so reusing that prefix silently restyled the "which child is this for?"
   screens. Whole row is the target, because a chevron-sized hit area on a phone is a miss. */
.prov-list { display: flex; flex-direction: column; gap: 12px; margin: 20px 0; }
.prov-row { display: grid; grid-template-columns: 44px 1fr auto auto; align-items: center;
  gap: 14px; padding: 16px; border-radius: 14px; background: var(--surface);
  border: 1px solid var(--line); text-decoration: none; color: inherit;
  transition: border-color .12s ease, transform .12s ease; }
.prov-row:hover, .prov-row:focus-visible { border-color: var(--brand); transform: translateY(-1px); }
/* A white tile with the provider's own colour on the glyph. Our line icons, not their brand
   marks: we do not hold those assets, and a hand-drawn Google or Apple logo reads as
   counterfeit rather than familiar. `color: inherit` is load-bearing — the shared .ico rule
   sets a colour ON the svg, so without it every glyph came out sage green. */
.prov-ic { display: flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  border-radius: 11px; background: #fff; border: 1px solid var(--line); color: var(--brand-d); }
.prov-ic svg { width: 21px; height: 21px; color: inherit; }
.prov-google    { color: #1A73E8; }
.prov-microsoft { color: #0F6CBD; }
.prov-icloud    { color: #4B9CD3; }
.prov-yahoo     { color: #6001D2; }
.prov-other     { color: var(--muted); }
.prov-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.prov-name { font-size: 1rem; font-weight: 700; }
.prov-sub { font-size: .84rem; color: var(--muted); line-height: 1.45; }
.prov-chev { display: flex; color: #B9B2A2; }
.prov-chev svg { width: 16px; height: 16px; }
/* Listed, and honest about it: the row still goes somewhere useful (tell us what you use)
   rather than to a sign-in we cannot finish. */
.prov-row.is-soon { background: transparent; }
.prov-soon { font-size: .68rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); background: var(--line); padding: 3px 8px; border-radius: 6px; }
.prov-privacy { display: flex; gap: 8px; align-items: flex-start; background: var(--brand-soft);
  color: var(--brand-d); font-size: .84rem; line-height: 1.5; padding: 11px 13px;
  border-radius: 10px; margin-top: 16px; }
.prov-privacy svg { width: 15px; height: 15px; flex: none; margin-top: 2px; }
.prov-alt { font-size: .84rem; margin-top: 14px; }
@media (max-width: 520px) {
  .prov-row { grid-template-columns: 44px 1fr auto; gap: 12px; padding: 14px; }
  .prov-soon { display: none; }
}

/* Family calendar header: title left, Back to dashboard hard right, on one line, and the whole
   page starts higher. It was costing three stacked rows (title, summary, button) plus 40px of
   top padding before the first event appeared. */
.tl-page { padding-top: 18px; }
.tl-hero { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: nowrap; }
.tl-hero .hero-text { margin: 0; min-width: 0; }
.tl-page .tl-hero .display { font-size: 1.65rem; margin: 0; }
.tl-page .tl-hero .summary { margin: 2px 0 0; }
.tl-back { flex: none; white-space: nowrap; }
@media (max-width: 560px) {
  .tl-page { padding-top: 12px; }
  .tl-page .tl-hero .display { font-size: 1.35rem; }
  .tl-page .tl-hero .summary { display: none; }  /* the title already says it */
  .tl-back { padding: 6px 10px; font-size: .8rem; }
}

/* The Family Calendar wears Today's header. .m-greet styling lives inside the phone media
   query (it was shell-only), so repeat it here for every width. */
.tl-greet { margin: 2px 0 10px; }
.tl-greet h2 { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 25px;
  line-height: 1.12; margin: 0; }
.tl-greet .m-date { color: var(--muted); font-size: 14px; margin-top: 8px; font-weight: 600; }

/* Edit panel inside an opened agenda row. */
.ag-edit { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line);
  display: flex; flex-direction: column; gap: 12px; }
.ag-form { display: flex; flex-direction: column; gap: 8px; }
.ag-form label { display: flex; flex-direction: column; gap: 4px; font-size: .78rem;
  font-weight: 700; color: var(--muted); }
.ag-form input { font: inherit; font-size: .9rem; padding: 8px 10px; border: 1px solid var(--line);
  border-radius: 9px; background: #fff; color: var(--ink); }
.ag-form input:focus { outline: none; border-color: var(--brand); }
.ag-form .btn { align-self: flex-start; }
/* Day, Starts, Ends. NOT three across on a phone: a native date control has an intrinsic
   minimum width that ignores flex shrinking, and the mobile rule below forces every input to
   16px to stop iOS zooming on focus, so three of them overflowed the row and the time box was
   drawn on top of the date. Day takes its own line, the two times share the next one, and all
   three sit in a row only once there is room. */
.ag-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
.ag-form-row > label:first-child { grid-column: 1 / -1; }
.ag-form-row label { min-width: 0; }
.ag-form-row input { width: 100%; min-width: 0; }
@media (min-width: 560px) {
  .ag-form-row { grid-template-columns: repeat(3, 1fr); }
  .ag-form-row > label:first-child { grid-column: auto; }
}
.ag-note { border-top: 1px dashed var(--line); padding-top: 12px; }

/* Connections, on a page of its own. */
.cx-list { display: flex; flex-direction: column; gap: 14px; margin: 18px 0; }
.cx-card { background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  padding: 16px; }
.cx-head { display: grid; grid-template-columns: 34px 1fr auto; align-items: start; gap: 12px; }
.cx-ic { display: flex; align-items: center; justify-content: center; width: 34px; height: 34px;
  border-radius: 9px; background: var(--brand-soft); color: var(--brand-d); }
.cx-ic svg { width: 17px; height: 17px; }
.cx-card.off .cx-ic { background: var(--line); color: var(--muted); }
.cx-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cx-name { font-size: 1rem; }
.cx-sub { font-size: .84rem; color: var(--muted); line-height: 1.45; overflow-wrap: anywhere; }
.cx-who { list-style: none; padding: 0; margin: 12px 0 0; }
.cx-who li { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 6px 0;
  font-size: .86rem; }
.cx-who li + li { border-top: 1px solid var(--line); }
.cx-w-e { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.cx-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.cx-steps { margin: 0; padding-left: 18px; line-height: 1.75; font-size: .88rem; }
.cx-tip { display: flex; gap: 8px; align-items: flex-start; background: var(--brand-soft);
  color: var(--brand-d); font-size: .82rem; line-height: 1.5; padding: 10px 12px;
  border-radius: 10px; margin: 12px 0 0; }
.cx-tip svg { width: 14px; height: 14px; flex: none; margin-top: 2px; }
/* The partner invite: a LINK, never their password. */
.cx-invite { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line); }
.cx-invite-p { font-size: .84rem; color: var(--muted); margin: 0 0 8px; line-height: 1.5; }
.cx-copy { display: flex; gap: 8px; }
.cx-copy input { flex: 1 1 auto; min-width: 0; font: inherit; font-size: .82rem; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 9px; background: #fff; color: var(--ink); }
.ag-form select { font: inherit; font-size: .9rem; padding: 8px 10px; border: 1px solid var(--line);
  border-radius: 9px; background: #fff; color: var(--ink); }
.ag-form-acts { display: flex; gap: 8px; align-items: center; margin-top: 4px; }
