/* ======================================================================
   Toach.ai — design tokens (Post-its on a Whiteboard, May 2026)
   Whiteboard surface, refined chambray blue, post-it card palette,
   handwritten Patrick Hand for section headers + margin notes.
   ====================================================================== */

:root {
  /* Surfaces — whiteboard */
  --bg: oklch(0.97 0.003 220);
  --surface: oklch(1.00 0.000 0);
  --surface-alt: oklch(0.95 0.004 220);
  --hair: oklch(0.83 0.008 220 / 0.6);

  /* Ink — warm near-black on cool paper */
  --text: oklch(0.20 0.012 60);
  --text-muted: oklch(0.40 0.015 65);
  --text-subtle: oklch(0.55 0.015 70);

  /* Refined chambray blue — system chrome, primary accent */
  --accent: oklch(0.55 0.18 235);
  --accent-soft: oklch(0.88 0.08 220);
  --accent-softer: oklch(0.94 0.04 235);
  --accent-deep: oklch(0.38 0.14 240);

  /* Sage / Toach voice — kept as a quieter functional accent */
  --toach: oklch(0.55 0.12 150);
  --toach-soft: oklch(0.92 0.04 150);
  --toach-deep: oklch(0.38 0.10 150);

  /* Coin gold — every coin count/cost in the app renders in this color */
  --coin-gold: oklch(0.60 0.13 80);

  /* State */
  --success: oklch(0.55 0.12 150);
  --success-soft: oklch(0.92 0.04 150);
  --slip: oklch(0.58 0.16 35);
  --slip-soft: oklch(0.93 0.04 35);

  /* Bubbles */
  --me-bubble: oklch(0.55 0.18 235);
  --me-bubble-text: #FFFFFF;
  --them-bubble: oklch(0.93 0.13 95);          /* yellow post-it */
  --them-bubble-text: oklch(0.22 0.04 70);

  /* Post-it palette — saturated, paper-like, with a 2-stop gradient */
  --pi-yellow:   oklch(0.93 0.13 95);
  --pi-yellow-2: oklch(0.88 0.16 92);
  --pi-pink:     oklch(0.88 0.10 10);
  --pi-pink-2:   oklch(0.82 0.13 8);
  --pi-blue:     oklch(0.88 0.08 220);
  --pi-blue-2:   oklch(0.82 0.10 222);
  --pi-mint:     oklch(0.91 0.09 155);
  --pi-mint-2:   oklch(0.86 0.11 155);
  --pi-peach:    oklch(0.90 0.10 50);
  --pi-peach-2:  oklch(0.85 0.13 50);
  --pi-lilac:    oklch(0.88 0.07 300);
  --pi-lilac-2:  oklch(0.82 0.10 300);

  /* Post-it shadow: tight bottom-right + soft ambient lift */
  --sh-postit: 0 1px 1px rgba(80,60,30,0.10), 1.5px 3px 4px rgba(80,60,30,0.10), 4px 8px 14px rgba(80,60,30,0.07);
  --sh-postit-lift: 0 2px 2px rgba(80,60,30,0.12), 2px 5px 8px rgba(80,60,30,0.14), 6px 14px 22px rgba(80,60,30,0.10);

  --font-ui: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", system-ui, sans-serif;
  --font-serif: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
  --font-hand: "Patrick Hand", "Caveat", -apple-system, system-ui, sans-serif;
  --font-script: "Caveat", "Patrick Hand", cursive;

  --radius: 14px;       /* softer rectangles — post-its sit alongside */
  --radius-sm: 10px;
  --radius-xs: 8px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  /* Bottom tab bar height (icons + label + safe area) */
  --tabbar-h: 64px;

  /* Bottom tab bar palette — chambray navy lifted slightly toward the
     v3 prototype. Active tab uses an amber pin-dot to mark the live tab. */
  --tabbar-bg: oklch(0.30 0.10 240);
  --tabbar-fg: oklch(0.88 0.04 235);
  --tabbar-fg-active: #FFFFFF;
  --tabbar-hair: rgba(255, 255, 255, 0.10);
  --tabbar-pin: oklch(0.82 0.14 70);
}

*, *::before, *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html, body {
  height: 100%;
  font-family: var(--font-ui);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow: hidden;
}

/* Whiteboard surface — very subtle marker-dust streaks + soft vignette.
   Layered onto the app's main scroll area so chat / login / modals get
   the same texture as the screen surfaces. */
body {
  background-image:
    linear-gradient(115deg, transparent 0%, oklch(0.93 0.01 220 / 0.15) 22%, transparent 24%, transparent 100%),
    linear-gradient(95deg, transparent 0%, transparent 60%, oklch(0.94 0.008 200 / 0.18) 72%, transparent 74%),
    linear-gradient(75deg, transparent 0%, transparent 30%, oklch(0.93 0.01 240 / 0.12) 38%, transparent 42%, transparent 100%),
    radial-gradient(ellipse at 50% 50%, oklch(0.985 0.002 220) 0%, oklch(0.95 0.005 220) 100%);
  background-size: 100% 220px, 100% 180px, 100% 260px, 100% 100%;
  background-repeat: repeat-y, repeat-y, repeat-y, no-repeat;
  background-attachment: fixed;
}

/* ======================================================================
   Toach orb — the signature. No mascot, just ambient presence.
   ====================================================================== */
.toach-orb {
  display: inline-block;
  border-radius: 50%;
  position: relative;
  flex-shrink: 0;
  vertical-align: middle;
  background: radial-gradient(circle at 35% 30%, #FFD89B 0%, var(--toach) 50%, var(--accent-deep) 100%);
  box-shadow:
    0 0 0 calc(var(--size, 22px) * 0.18) var(--toach-soft),
    inset 0 calc(var(--size, 22px) * 0.08) calc(var(--size, 22px) * 0.15) rgba(255,255,255,0.4);
  width: var(--size, 22px);
  height: var(--size, 22px);
  animation: toachPulse 3.4s ease-in-out infinite;
}
.toach-orb::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: inset calc(var(--size, 22px) * -0.12) calc(var(--size, 22px) * -0.12) calc(var(--size, 22px) * 0.2) rgba(120, 60, 20, 0.25);
}

@keyframes toachPulse {
  0%, 100% { box-shadow: 0 0 0 calc(var(--size, 22px) * 0.18) var(--toach-soft), inset 0 calc(var(--size, 22px) * 0.08) calc(var(--size, 22px) * 0.15) rgba(255,255,255,0.4); }
  50%      { box-shadow: 0 0 0 calc(var(--size, 22px) * 0.28) var(--toach-soft), inset 0 calc(var(--size, 22px) * 0.08) calc(var(--size, 22px) * 0.15) rgba(255,255,255,0.4); }
}

/* ======================================================================
   Screens
   ====================================================================== */
.screen {
  display: none;
  height: 100%;
  width: 100%;
}
.screen.active {
  display: flex;
  flex-direction: column;
}

/* ======================================================================
   Login
   ====================================================================== */
.login-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  gap: 32px;
  padding-top: calc(40px + var(--safe-top));
}

.login-logo {
  text-align: center;
}

.logo-icon {
  width: 72px;
  height: 72px;
  border-radius: 18px;
  background: linear-gradient(140deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: #fff;
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 2.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 20px;
  box-shadow: 0 8px 28px rgba(91, 168, 214, 0.35), 0 1px 0 rgba(255,255,255,0.3) inset;
}

.login-logo h1 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 2rem;
  letter-spacing: -0.02em;
  color: var(--text);
}

.login-logo p {
  font-family: var(--font-serif);
  color: var(--text-muted);
  margin-top: 8px;
  font-size: 1.05rem;
  line-height: 1.35;
}

.login-form {
  width: 100%;
  max-width: 340px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.login-form input {
  width: 100%;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 1rem;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
  -webkit-appearance: none;
}

.login-form input::placeholder {
  color: var(--text-subtle);
}

.login-form input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-softer);
}

.login-form button {
  padding: 14px;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.1s, filter 0.15s;
  margin-top: 6px;
  box-shadow: 0 4px 12px rgba(91, 168, 214, 0.25);
}

.login-form button:hover {
  filter: brightness(1.03);
}

.login-form button:active {
  transform: scale(0.98);
}

/* Sign in with Apple — Apple's Human Interface Guidelines require a black
   button with the Apple logo + "Sign in with Apple" wordmark, at least 44pt
   tall. We override the generic .login-form button styles to match HIG. */
.login-form .siwa-btn {
  background: #000;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  box-shadow: none;
  font-weight: 600;
  font-size: 0.95rem;
  border: 1px solid #000;
}
.login-form .siwa-btn:hover {
  filter: brightness(1.1);
}
.login-form .siwa-btn .siwa-icon {
  width: 18px;
  height: 18px;
  fill: #fff;
}

.siwa-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 4px;
}
.siwa-or {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text-subtle);
  font-size: 0.85rem;
  margin: 4px 0;
}
.siwa-or::before, .siwa-or::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--hair);
}
.login-form .siwa-action-btn,
.login-form .siwa-action-btn-secondary {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--hair);
  font-weight: 500;
  box-shadow: none;
  margin-top: 0;
}
.login-form .siwa-action-btn-secondary {
  background: transparent;
}
.join-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  margin-top: 4px;
}
.join-panel label {
  font-size: 0.85rem;
  color: var(--text-subtle);
}
.join-preview {
  color: var(--text);
  font-size: 0.95rem;
  margin: 0;
}
.login-form .join-cancel-btn {
  background: transparent;
  color: var(--text-subtle);
  box-shadow: none;
  border: none;
  font-weight: 400;
  margin-top: 0;
}

/* --- Household section in Settings -------------------------------------- */

.household-switcher {
  padding: 12px 16px;
}
.household-switcher-label {
  display: block;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-subtle);
  margin-bottom: 6px;
}
.household-switcher-select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 1rem;
  color: var(--text);
  font-family: var(--font-ui);
  -webkit-appearance: menulist;
}

.household-member-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--hair);
}
.household-member-row:last-child { border-bottom: none; }
.household-member-name {
  font-weight: 500;
  color: var(--text);
}
.household-member-sub {
  font-size: 0.8rem;
  color: var(--text-subtle);
  margin-top: 2px;
}
.household-role-badge {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--household-softer);
  color: var(--text-muted);
}
.household-role-badge.role-admin {
  background: var(--accent-softer, #E0EEF6);
  color: var(--accent, #5BA8D6);
}
.household-invite-display {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 1.1rem;
  letter-spacing: 0.08em;
  padding: 14px 16px;
  background: var(--household-softer);
  border-radius: var(--radius-sm);
  margin: 8px 16px;
  text-align: center;
}
.household-invite-link {
  font-size: 0.78rem;
  color: var(--text-subtle);
  word-break: break-all;
  padding: 0 16px 8px;
  text-align: center;
}

/* --- Generic modal overlay (used by Leave-household dialog) -------------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: 1000;
}
.modal-overlay.hidden { display: none; }
.modal-card {
  background: var(--surface);
  border-radius: var(--radius);
  padding: 22px;
  max-width: 420px;
  width: 100%;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
}
.modal-card h3 {
  margin: 0 0 8px;
  font-size: 1.1rem;
}
.modal-card p {
  color: var(--text-muted);
  font-size: 0.95rem;
  line-height: 1.45;
  margin: 0 0 12px;
}
.modal-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 14px;
}
.modal-actions button {
  flex: 0 0 auto;
}
/* Invite-code input inside the join-household dialog. Mirrors the login
   form fields so codes look the same wherever they're typed. */
.modal-card .join-code-field {
  width: 100%;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
  -webkit-appearance: none;
  box-sizing: border-box;
}
.modal-card .join-code-field:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-softer);
}

.leave-radio {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  font-size: 0.95rem;
  color: var(--text);
}
.leave-select {
  width: 100%;
  margin: 4px 0 12px 24px;
  max-width: calc(100% - 24px);
  padding: 8px 12px;
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.95rem;
}

.error-msg {
  color: var(--slip);
  font-size: 0.85rem;
  text-align: center;
  min-height: 1.2em;
  margin-top: 4px;
}

/* ======================================================================
   Chat header
   ====================================================================== */
.chat-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  padding-top: calc(10px + var(--safe-top));
  background: var(--bg);
  border-bottom: 0.5px solid var(--hair);
  flex-shrink: 0;
}

/* Center-aligned header for the chat screen — Toach orb is the focus */
#chat-screen .chat-header {
  justify-content: space-between;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  justify-content: center;
}

.header-avatar {
  --size: 32px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #FFD89B 0%, var(--toach) 50%, var(--accent-deep) 100%);
  position: relative;
  flex-shrink: 0;
  box-shadow: 0 0 0 6px var(--toach-soft);
}
.header-avatar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: inset -4px -4px 6px rgba(120, 60, 20, 0.25);
}

.header-info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.header-name {
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
  color: var(--text);
}

.header-status {
  font-size: 0.72rem;
  color: var(--text-subtle);
  margin-top: 1px;
}

.header-status.connected {
  color: var(--toach-deep);
}

.header-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  padding: 8px;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.header-btn:hover {
  background: var(--surface-alt);
  color: var(--text);
}


/* ======================================================================
   App header treatment — per-screen identity via colored icon badge.
   Layered on top of `.chat-header` so the chat screen is unaffected.
   Each screen carries an `.app-header` class plus an `.app-header-{name}`
   modifier; the modifier swaps the gradient + accent of the badge.
   ====================================================================== */

.app-header {
  /* A bit more breathing room than the bare chat header. */
  padding: 12px 16px;
  padding-top: calc(12px + var(--safe-top));
  background: var(--bg);
  /* Hairline still here — sits underneath the gradient strip — so the
     header reads as a defined edge even while the screen is loading
     before any badge gradient is computed. */
  border-bottom: 0.5px solid var(--hair);
  gap: 12px;
  /* Anchors the gradient accent strip + lets the inner content sit
     above any pseudo-element. */
  position: relative;
  z-index: 1;
}

/* Per-screen gradient accent strip (2.5px) — sits flush at the bottom
   of the header. Matches the badge gradient, so the header reads as a
   small "branded" surface for that screen. */
.app-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2.5px;
  background: linear-gradient(
    90deg,
    var(--hdr1, var(--accent)) 0%,
    var(--hdr2, var(--accent-deep)) 100%
  );
  /* Soft outer feather so the strip doesn't look like a slammed-on bar. */
  box-shadow: 0 1px 6px var(--hdr-shadow, rgba(91, 168, 214, 0.18));
}

.app-header .header-left {
  /* Left-align the title block when a badge is present — centering it
     looks awkward next to the colored icon. */
  justify-content: flex-start;
  flex: 1;
  min-width: 0;
}

.app-header .header-name {
  font-size: 1.15rem;       /* was 0.95rem — give the screen name presence */
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.15;
}

.app-header .header-status {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-top: 3px;
}

/* Badge: gradient-filled rounded square, white SVG icon centered. The
   gradient + soft glow is the main "appeal" lever — color comes from
   the per-screen `--hdr1` / `--hdr2` vars defined below. */
.header-icon-badge {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #FFFFFF;
  flex-shrink: 0;
  background: linear-gradient(
    135deg,
    var(--hdr1, var(--accent)),
    var(--hdr2, var(--accent-deep))
  );
  box-shadow: 0 4px 12px var(--hdr-shadow, rgba(91, 168, 214, 0.28));
  position: relative;
}
.header-icon-badge svg {
  display: block;
  /* Icons inside badges use stroke="currentColor" + stroke-width=2 —
     same convention as the tab bar so we share the SVG snippets. */
}
/* Subtle inner highlight so the badge feels dimensional, not flat. */
.header-icon-badge::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255,255,255,0.18), rgba(255,255,255,0) 55%);
  pointer-events: none;
}

/* Per-screen palettes. Each modifier sets the same three vars:
     --hdr1       gradient start (lighter end)
     --hdr2       gradient end   (deeper end)
     --hdr-shadow soft outer glow under the badge + strip
     --hdr-wash   the very-low-alpha tint painted on the screen body
   Defining all four in one place means tweaking a screen's identity
   color is a one-line change; badge, strip, and body wash all follow. */

/* Badge + strip vars (cascade DOWN to the header's badge and ::after). */
.app-header-today    { --hdr1: #6FBEE5; --hdr2: #3A83B0; --hdr-shadow: rgba(58, 131, 176, 0.32); }
.app-header-family   { --hdr1: #A8CFA1; --hdr2: #5E8E5D; --hdr-shadow: rgba(94, 142, 93, 0.32); }
.app-header-tasks    { --hdr1: #F1A98C; --hdr2: #C7795F; --hdr-shadow: rgba(199, 121, 95, 0.32); }
.app-header-decisions{ --hdr1: #4A6FB8; --hdr2: #1A2A4B; --hdr-shadow: rgba(26, 42, 75, 0.34); }
.app-header-settings { --hdr1: #94A3B8; --hdr2: #475569; --hdr-shadow: rgba(71, 85, 105, 0.28); }
.app-header-review   { --hdr1: #E8B97D; --hdr2: #B5824A; --hdr-shadow: rgba(181, 130, 74, 0.32); }
.app-header-chat     { --hdr1: #B8A5F0; --hdr2: #7E60D6; --hdr-shadow: rgba(126, 96, 214, 0.32); }

/* Per-screen body wash — a soft top-down gradient that tints the area
   under the header, fading to transparent so the white cards keep
   their pop. Scoped via `:has()` so we don't have to dual-tag each
   screen wrapper. The token has to live on the same element where the
   `background` rule applies (CSS vars cascade down, not up — the
   header's `.app-header-{name}` modifier is a descendant of `.screen`,
   so its vars wouldn't reach `.screen`'s background).

   ~340px wash height = roughly the header + a couple of cards. Past
   that everything reverts to the standard `--bg`. */
.screen:has(.app-header-today)     { --hdr-wash: rgba(91, 168, 214, 0.085); }
.screen:has(.app-header-family)    { --hdr-wash: rgba(139, 184, 138, 0.09); }
.screen:has(.app-header-tasks)     { --hdr-wash: rgba(241, 169, 140, 0.10); }
.screen:has(.app-header-decisions) { --hdr-wash: rgba(74, 111, 184, 0.07); }
.screen:has(.app-header-settings)  { --hdr-wash: rgba(148, 163, 184, 0.08); }
.screen:has(.app-header-review)    { --hdr-wash: rgba(232, 185, 125, 0.10); }
.screen:has(.app-header-chat)      { --hdr-wash: rgba(167, 139, 250, 0.085); }

.screen:has(.app-header) {
  background:
    linear-gradient(
      180deg,
      var(--hdr-wash, transparent) 0%,
      transparent 340px
    ),
    var(--bg);
}

/* Decisions detail header re-uses the back arrow on the left, so the
   badge would compete. Keep the title block centered + scaled down on
   that view; no badge. */
#decisions-detail-view .app-header .header-left {
  justify-content: center;
  text-align: center;
}
#decisions-detail-view .app-header .header-name {
  font-size: 1rem;
  font-weight: 600;
}

/* ======================================================================
   Quick actions
   ====================================================================== */
.quick-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 16px;
  background: var(--bg);
  border-bottom: 0.5px solid var(--hair);
  flex-shrink: 0;
}

.quick-actions.hidden {
  display: none;
}

.quick-actions button {
  padding: 8px 14px;
  background: var(--accent-softer);
  border: none;
  border-radius: 16px;
  color: var(--accent-deep);
  font-family: var(--font-ui);
  font-size: 0.82rem;
  font-weight: 500;
  cursor: pointer;
  transition: filter 0.15s, transform 0.1s;
  white-space: nowrap;
}

.quick-actions button:hover {
  filter: brightness(0.97);
}
.quick-actions button:active {
  transform: scale(0.97);
}

/* ======================================================================
   Messages — iMessage-style bubbles
   ====================================================================== */
.messages {
  flex: 1;
  overflow-y: auto;
  padding: 18px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  background: var(--bg);
}

/* Day stamp at the top */
.day-stamp {
  text-align: center;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-subtle);
  letter-spacing: 0.3px;
  text-transform: uppercase;
  margin-bottom: 14px;
  margin-top: 4px;
}

.welcome-msg {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 4px 4px 12px;
  max-width: 78%;
}

.welcome-msg .welcome-who {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  margin-left: 4px;
}

.welcome-icon {
  --size: 14px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #FFD89B 0%, var(--toach) 50%, var(--accent-deep) 100%);
  position: relative;
  flex-shrink: 0;
  box-shadow: 0 0 0 2.5px var(--toach-soft);
}
.welcome-icon::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: inset -1.5px -1.5px 2.5px rgba(120, 60, 20, 0.25);
}

.welcome-who-label {
  font-size: 11px;
  color: var(--text-subtle);
  font-weight: 500;
}

.welcome-msg p {
  background: var(--them-bubble);
  color: var(--them-bubble-text);
  padding: 9px 14px;
  border-radius: var(--radius);
  border-bottom-left-radius: 6px;
  font-family: var(--font-serif);
  font-size: 17px;
  line-height: 1.32;
  letter-spacing: 0.15px;
}

/* Message bubbles */
.message {
  display: flex;
  flex-direction: column;
  max-width: 78%;
  animation: fadeIn 0.22s ease-out;
}

.message.user {
  align-self: flex-end;
  align-items: flex-end;
  margin-top: 8px;
  margin-bottom: 4px;
}

.message.agent {
  align-self: flex-start;
  align-items: flex-start;
  margin-top: 8px;
  margin-bottom: 4px;
}

/* Small orb + "Toach" label above the first agent bubble */
.msg-who {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  margin-left: 4px;
}

.msg-who-label {
  font-size: 11px;
  color: var(--text-subtle);
  font-weight: 500;
}

.msg-who-orb {
  --size: 14px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #FFD89B 0%, var(--toach) 50%, var(--accent-deep) 100%);
  position: relative;
  flex-shrink: 0;
  box-shadow: 0 0 0 2.5px var(--toach-soft);
}
.msg-who-orb::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: inset -1.5px -1.5px 2.5px rgba(120, 60, 20, 0.25);
}

/* The user side doesn't use msg-avatar now (iMessage style) */
.msg-avatar {
  display: none;
}

.msg-bubble {
  padding: 9px 14px;
  word-wrap: break-word;
  white-space: pre-wrap;
  border-radius: var(--radius);
}

.message.user .msg-bubble {
  background: var(--me-bubble);
  color: var(--me-bubble-text);
  border-bottom-right-radius: 6px;
  font-family: var(--font-ui);
  font-size: 15.5px;
  line-height: 1.32;
  letter-spacing: -0.1px;
  font-weight: 400;
}

.message.agent .msg-bubble {
  background: var(--them-bubble);
  color: var(--them-bubble-text);
  border-bottom-left-radius: 6px;
  font-family: var(--font-serif);
  font-size: 17px;
  line-height: 1.32;
  letter-spacing: 0.15px;
  font-weight: 400;
}

.msg-time {
  font-size: 10.5px;
  color: var(--text-subtle);
  margin-top: 3px;
  padding: 0 6px;
  letter-spacing: 0.1px;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ======================================================================
   Typing indicator
   ====================================================================== */
.typing-indicator {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 4px 16px 0;
  flex-shrink: 0;
}

.typing-indicator.hidden {
  display: none;
}

.typing-avatar {
  display: none; /* orb is shown inline with the bubble via ::before if needed */
}

.typing-dots {
  display: flex;
  gap: 4px;
  padding: 12px 14px;
  background: var(--them-bubble);
  border-radius: var(--radius);
  border-bottom-left-radius: 6px;
}

.typing-dots span {
  width: 6px;
  height: 6px;
  background: var(--toach-deep);
  opacity: 0.5;
  border-radius: 50%;
  animation: typingBounce 1.2s infinite;
}

.typing-dots span:nth-child(2) { animation-delay: 0.15s; }
.typing-dots span:nth-child(3) { animation-delay: 0.3s; }

@keyframes typingBounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30%           { transform: translateY(-4px); opacity: 1; }
}

/* ======================================================================
   Input area
   ====================================================================== */
.input-area {
  padding: 8px 12px 14px;
  padding-bottom: calc(14px + var(--safe-bottom));
  background: var(--bg);
  border-top: 0.5px solid var(--hair);
  flex-shrink: 0;
  /* Anchor for the @mention autocomplete popover, which positions itself
     absolutely with `bottom: 100%` to float above the input. */
  position: relative;
}

.input-wrapper {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  background: var(--surface);
  border: 0.5px solid var(--hair);
  border-radius: 22px;
  padding: 6px;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.input-wrapper:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-softer);
}

#message-input,
#decision-input {
  flex: 1;
  background: none;
  border: none;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.38;
  resize: none;
  outline: none;
  max-height: 120px;
  padding: 8px 0;
  min-width: 0;
}

#message-input::placeholder,
#decision-input::placeholder {
  color: var(--text-subtle);
}

.send-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: opacity 0.15s, transform 0.1s, background 0.15s;
  margin-bottom: 2px;
}

.send-btn:disabled {
  background: var(--surface-alt);
  color: var(--text-subtle);
  cursor: default;
}

.send-btn:not(:disabled):active {
  transform: scale(0.9);
}

/* ── Mic button (voice input) ─────────────────────────────────────────── */
.mic-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface-alt);
  color: var(--text-muted);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s, transform 0.1s;
  -webkit-tap-highlight-color: transparent;
}
.mic-btn:active {
  transform: scale(0.9);
}
.mic-btn.listening {
  background: #E15A5A;
  color: #fff;
  animation: micPulse 1.2s ease-in-out infinite;
}
.mic-btn.unsupported {
  display: none;
}
@keyframes micPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(225, 90, 90, 0.45); }
  50%      { box-shadow: 0 0 0 8px rgba(225, 90, 90, 0); }
}

/* ── Paperclip / attach button ────────────────────────────────────────── */
.paperclip-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface-alt);
  color: var(--text-muted);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s, transform 0.1s;
  -webkit-tap-highlight-color: transparent;
}
.paperclip-btn:active {
  transform: scale(0.9);
}

/* ── Staged-photo preview above the input row ─────────────────────────── */
.chat-attachment-wrap {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
  padding: 8px 10px;
  background: var(--surface);
  border: 0.5px solid var(--hair);
  border-radius: 14px;
}
.chat-attachment-thumb {
  width: 44px;
  height: 44px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--surface-alt);
}
.chat-attachment-meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.chat-attachment-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
}
.chat-attachment-hint {
  font-size: 11px;
  color: var(--text-subtle);
}
.chat-attachment-remove {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.chat-attachment-remove:active {
  background: var(--surface-alt);
}

/* ======================================================================
   Scrollbar
   ====================================================================== */
.messages::-webkit-scrollbar,
.settings-body::-webkit-scrollbar {
  width: 4px;
}
.messages::-webkit-scrollbar-track,
.settings-body::-webkit-scrollbar-track {
  background: transparent;
}
.messages::-webkit-scrollbar-thumb,
.settings-body::-webkit-scrollbar-thumb {
  background: var(--hair);
  border-radius: 2px;
}

/* ======================================================================
   Settings — iOS-style grouped list
   ====================================================================== */
.settings-body {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0 32px;
  max-width: 680px;
  width: 100%;
  margin: 0 auto;
}

.settings-section {
  padding: 0 16px 24px;
}

.settings-section h3 {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-subtle);
  text-transform: uppercase;
  letter-spacing: 0.8px;
  padding: 0 16px 8px;
  margin: 0;
}

.settings-card {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow:
    0 1px 2px rgba(80, 55, 35, 0.04),
    0 1px 0 rgba(255, 255, 255, 0.8) inset,
    0 0 0 0.5px rgba(80, 55, 35, 0.04);
  overflow: hidden;
}

.settings-help {
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.45;
  padding: 0 16px 10px;
}

/* Two-column row inside a settings-section: label/sub on the left, action
   button on the right. Used for the Apple ID linking row, and reusable for
   future settings that pair a description with an action. */
.settings-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow:
    0 1px 2px rgba(80, 55, 35, 0.04),
    0 1px 0 rgba(255, 255, 255, 0.8) inset,
    0 0 0 0.5px rgba(80, 55, 35, 0.04);
}
.settings-row > div:first-child {
  flex: 1;
  min-width: 0;
}
.settings-row-title {
  font-weight: 600;
  font-size: 14px;
  color: var(--text);
}
.settings-row-sub {
  color: var(--text-muted);
  font-size: 12px;
  margin-top: 2px;
}
.settings-row .btn-secondary {
  flex-shrink: 0;
  width: auto;
}

/* ======================================================================
   Story 8: schedule photo intake (v24).
   ====================================================================== */
.schedule-import-card {
  padding: 16px;
}
.schedule-import-empty,
.schedule-import-loading,
.schedule-import-preview,
.schedule-import-result {
  display: block;
}
.schedule-import-empty.hidden,
.schedule-import-loading.hidden,
.schedule-import-preview.hidden,
.schedule-import-result.hidden {
  display: none;
}

/* Popup mode: triggered by the chat "Review and add" button. The body class
   is set by openScheduleImportFromChat / cleared by _closeScheduleImportModal.
   The preview (and post-confirm result) get a dim backdrop via ::before on
   body, then float as a centered card on top — the rest of the chat stays
   visible/dimmed behind so the user clearly understands they're in a
   transient confirmation step, not a different screen. */
body.schedule-import-modal-open::before {
  content: '';
  position: fixed;
  inset: 0;
  background: rgba(15, 31, 42, 0.45);
  z-index: 999;
  -webkit-backdrop-filter: blur(2px);
          backdrop-filter: blur(2px);
}
body.schedule-import-modal-open .schedule-import-preview,
body.schedule-import-modal-open .schedule-import-result {
  position: fixed;
  /* Centered card. Capped at 480px wide / 80vh tall on phones; on iPad it
     stays comfortable to read. The internal scroll handles long event lists
     without pushing the card off screen. */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1000;
  width: min(92vw, 480px);
  max-height: min(85vh, 720px);
  background: var(--surface);
  border-radius: 14px;
  padding: 16px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  box-shadow: 0 24px 64px rgba(15, 31, 42, 0.32),
              0 4px 12px rgba(15, 31, 42, 0.18);
}
/* Hide the bottom tab bar while the popup is open so taps land on the
   review buttons rather than slipping through to the tab bar. */
body.schedule-import-modal-open #tab-bar {
  display: none;
}
.schedule-import-loading p {
  margin: 4px 0;
  color: var(--text-muted);
}
.schedule-import-preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--hair);
  margin-bottom: 12px;
}
.schedule-import-preview-header strong {
  font-size: 15px;
  color: var(--text);
}
.schedule-import-preview-header .settings-help {
  display: inline;
  padding: 0 0 0 8px;
}

/* Recurring-group callout */
.schedule-import-recurring {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
}
.schedule-import-recurring-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  background: var(--accent-softer);
  border: 1px solid var(--accent-soft);
  border-radius: 10px;
  font-size: 13px;
  color: var(--text);
}
.schedule-import-recurring-row.active {
  background: var(--toach-soft);
  border-color: var(--toach-soft);
  color: var(--toach-deep);
}

/* Per-event row */
.schedule-import-rows {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 480px;
  overflow-y: auto;
  padding-right: 4px;  /* spacing from scrollbar */
}
.schedule-row {
  border: 1px solid var(--hair);
  border-radius: 12px;
  padding: 10px 12px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.schedule-row.medium { border-color: rgba(212, 138, 122, 0.4); }
.schedule-row.low    { border-color: var(--slip); border-width: 2px; }
.schedule-row-grouped {
  background: var(--surface-alt);
  color: var(--text-subtle);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
}
.schedule-row-grouped-tag {
  font-size: 11px;
  font-weight: 600;
  color: var(--toach-deep);
  background: var(--toach-soft);
  padding: 3px 8px;
  border-radius: 999px;
}
.schedule-row-fields {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 2fr;
  gap: 6px;
  align-items: center;
}
.schedule-row-fields input[type="text"],
.schedule-row-fields input[type="date"],
.schedule-row-fields input[type="time"] {
  border: 1px solid var(--hair);
  border-radius: 8px;
  padding: 6px 8px;
  font-size: 13px;
  font-family: inherit;
  color: var(--text);
  background: var(--surface);
  min-width: 0;
  width: 100%;
}
.schedule-row-fields input:focus {
  outline: none;
  border-color: var(--accent);
}
.schedule-allday-tag {
  font-size: 11px;
  color: var(--text-subtle);
  background: var(--surface-alt);
  padding: 4px 8px;
  border-radius: 6px;
  text-align: center;
  grid-column: span 2;
}

.schedule-row-targeting {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-muted);
}
.schedule-row-targeting select {
  border: 1px solid var(--hair);
  border-radius: 6px;
  padding: 4px 6px;
  font-size: 12px;
  font-family: inherit;
  background: var(--surface);
}
.schedule-attendees-label {
  margin-left: 8px;
}
.schedule-attendees {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.schedule-attendee-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--text-muted);
  cursor: pointer;
}
.schedule-attendee-chip input { display: none; }
.schedule-attendee-chip.on {
  background: var(--accent-softer);
  color: var(--accent-deep);
}

.schedule-row-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: -2px;
}
.schedule-confidence {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  cursor: help;
}
.schedule-confidence.medium {
  background: var(--slip-soft);
  color: var(--slip);
}
.schedule-confidence.low {
  background: var(--slip);
  color: white;
}
.schedule-recurring-anchor-tag {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--toach-deep);
  background: var(--toach-soft);
  padding: 2px 7px;
  border-radius: 999px;
}
.schedule-row-remove {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-subtle);
}
.schedule-row-remove:hover { color: var(--slip); }

.schedule-import-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--hair);
}
.schedule-import-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
}

.schedule-import-result .schedule-result-ok,
.schedule-import-result .schedule-result-partial {
  padding: 14px;
  border-radius: 12px;
  background: var(--success-soft);
}
.schedule-import-result .schedule-result-partial {
  background: var(--slip-soft);
}
.schedule-result-failures {
  font-size: 12px;
  margin: 8px 0 12px 18px;
}

/* Calendar row */
.account-row,
.connect-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 16px;
  position: relative;
}
.account-row + .account-row,
.account-row + .connect-row,
.connect-row + .connect-row,
.connect-row + .account-row {
  border-top: 0.5px solid var(--hair);
  margin-left: 60px;
  padding-left: 0;
}
.account-row + .account-row::before,
.account-row + .connect-row::before,
.connect-row + .connect-row::before,
.connect-row + .account-row::before {
  /* Visual separator is the border-top above — reset */
  content: none;
}

.account-row {
  padding: 13px 16px;
}

.account-provider-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--accent-softer);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--accent-deep);
}

.account-info {
  flex: 1;
  min-width: 0;
}

.account-email {
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-provider {
  font-size: 12px;
  color: var(--text-muted);
  text-transform: capitalize;
  margin-top: 1px;
}

.account-status-on {
  font-size: 12px;
  font-weight: 600;
  color: var(--toach-deep);
  background: var(--success-soft);
  padding: 3px 10px;
  border-radius: 10px;
  flex-shrink: 0;
}

/* v23: red pill when the auth layer recorded a recent error on this
   calendar. The error text is in title= for hover, and a one-line
   summary is appended to the provider line below the email. */
.account-status-error {
  font-size: 12px;
  font-weight: 600;
  color: #8a3a2a;          /* darker than --slip for contrast on the soft bg */
  background: var(--slip-soft);
  padding: 3px 10px;
  border-radius: 10px;
  flex-shrink: 0;
  cursor: help;
}
.account-row-error .account-provider {
  color: var(--slip);
}

/* Connect row (when no account of that provider) */
.connect-row {
  cursor: pointer;
  transition: background 0.1s;
}
.connect-row:hover {
  background: var(--accent-softer);
}
.connect-row .connect-label {
  flex: 1;
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
}
.connect-row .connect-sub {
  font-size: 12px;
  color: var(--text-subtle);
  margin-top: 1px;
}
.connect-row .connect-cta {
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  background: transparent;
  border: none;
  cursor: pointer;
}

/* Disconnect button on a connected row */
.btn-disconnect {
  background: transparent;
  color: var(--slip);
  border: none;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  padding: 6px 8px;
  border-radius: 8px;
}
.btn-disconnect:hover {
  background: var(--slip-soft);
}

/* Primary action buttons (Connect Google, etc.) */
.settings-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding: 12px 16px 0;
}

.btn-primary {
  flex: 1;
  background: var(--accent);
  color: #fff;
  border: none;
  padding: 11px 16px;
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  transition: filter 0.15s, transform 0.1s;
  min-width: 140px;
  box-shadow: 0 3px 8px rgba(91, 168, 214, 0.22);
}
.btn-primary:hover { filter: brightness(1.03); }
.btn-primary:active { transform: scale(0.98); }

.btn-secondary {
  background: var(--surface);
  color: var(--text);
  border: none;
  padding: 11px 16px;
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 14px;
  cursor: pointer;
  box-shadow:
    0 1px 2px rgba(80, 55, 35, 0.04),
    0 0 0 0.5px rgba(80, 55, 35, 0.1);
  transition: background 0.15s;
}
.btn-secondary:hover { background: rgba(0,0,0,0.03); }

/* Destructive logout section */
.settings-logout {
  padding: 0 16px;
  margin-top: 8px;
}

.btn-logout {
  width: 100%;
  background: var(--surface);
  color: var(--slip);
  border: none;
  padding: 14px;
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 15px;
  cursor: pointer;
  box-shadow:
    0 1px 2px rgba(80, 55, 35, 0.04),
    0 0 0 0.5px rgba(80, 55, 35, 0.04);
  transition: background 0.15s;
}
.btn-logout:hover {
  background: var(--slip-soft);
}

.settings-status {
  margin-top: 12px;
  font-size: 13px;
  color: var(--text-muted);
  word-break: break-all;
  padding: 0 16px;
  line-height: 1.4;
}

.settings-status.error {
  color: var(--slip);
}

/* Notification preferences */
.notif-device {
  padding: 14px 16px;
  margin-bottom: 12px;
}
.notif-device-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.notif-device-title {
  font-size: 15px;
  font-weight: 500;
}
.notif-device-status {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 2px;
}
.notif-ios-hint {
  margin-top: 10px;
  padding: 10px 0 0;
  border-top: 0.5px solid var(--hair);
  font-size: 12px;
}
.notif-prefs {
  padding: 4px 0;
}
.notif-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 13px 16px;
  font-size: 15px;
  cursor: pointer;
}
.notif-row + .notif-row {
  border-top: 0.5px solid var(--hair);
}
.notif-row input[type="checkbox"] {
  width: 44px;
  height: 26px;
  appearance: none;
  -webkit-appearance: none;
  background: #d9d4cc;
  border-radius: 13px;
  position: relative;
  cursor: pointer;
  transition: background 0.2s;
  flex-shrink: 0;
}
.notif-row input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 22px;
  height: 22px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  transition: transform 0.18s ease;
}
.notif-row input[type="checkbox"]:checked {
  background: #6b8e5a;
}
.notif-row input[type="checkbox"]:checked::after {
  transform: translateX(18px);
}
.notif-row input[type="checkbox"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Indented config line under a toggle (reminder lead, nudge times). */
.notif-row-config {
  padding-top: 0;
  padding-left: 28px;
  cursor: default;
  border-top: none !important;
}
.notif-config-label {
  font-size: 13px;
  color: var(--text-muted);
}
.notif-row-config select,
.notif-row-config input[type="time"] {
  font-size: 14px;
  padding: 6px 10px;
  border: 1px solid var(--hair);
  border-radius: 10px;
  background: var(--surface-alt);
  color: var(--text);
}

/* Family admin UI */
.family-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 16px;
}
.family-row + .family-row {
  border-top: 0.5px solid var(--hair);
}
.family-row-info {
  flex: 1;
  min-width: 0;
}
.family-row-name {
  font-weight: 500;
  font-size: 15px;
}
.family-row-meta {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.family-badge {
  display: inline-block;
  font-size: 11px;
  background: #e9e2d6;
  color: #776550;
  padding: 2px 7px;
  border-radius: 8px;
  margin-left: 6px;
  vertical-align: 1px;
}
.family-badge.admin {
  background: #dceadf;
  color: #3f6b4a;
}
.family-row-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}
.family-row-actions button {
  background: transparent;
  border: 0.5px solid var(--hair);
  color: var(--text-muted);
  padding: 6px 10px;
  font-size: 12px;
  border-radius: 6px;
  cursor: pointer;
}
.family-row-actions button:hover { background: rgba(0,0,0,0.03); }
.family-row-actions .danger { color: var(--slip); }

.family-add {
  padding: 14px 16px;
}
.family-add input[type="text"],
.family-add input[type="email"] {
  width: 100%;
  padding: 10px 12px;
  margin-bottom: 10px;
  border: 0.5px solid var(--hair);
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-family: var(--font-ui);
  background: var(--surface);
}
.family-add input:focus {
  outline: none;
  border-color: var(--accent);
}
.family-admin-check {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0 12px;
  font-size: 14px;
  color: var(--text-muted);
  cursor: pointer;
}
.family-admin-check input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
}
.family-add-actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}
.family-add-actions .btn-secondary { flex: 0 0 auto; }
.family-add-actions .btn-primary { flex: 1; }

.family-temp {
  margin-top: 12px;
  padding: 14px 16px;
  background: #fff7df;
  border: 0.5px solid #e8d89a;
  border-radius: var(--radius);
}
.family-temp.hidden { display: none; }
.family-temp-pw {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 18px;
  font-weight: 600;
  padding: 8px 10px;
  background: #fff;
  border: 0.5px solid #e8d89a;
  border-radius: 6px;
  margin: 6px 0 6px;
  letter-spacing: 0.5px;
  user-select: all;
}

/* ======================================================================
   Responsive — keep comfortable max width on desktop
   ====================================================================== */
@media (min-width: 768px) {
  .messages,
  .input-area {
    max-width: 680px;
    margin-left: auto;
    margin-right: auto;
    width: 100%;
  }
}

/* ============================================================
   Today screen
   ============================================================ */

#today-screen .today-body,
#review-screen .review-body {
  flex: 1;
  overflow-y: auto;
  padding: 20px 20px calc(32px + var(--safe-bottom));
  -webkit-overflow-scrolling: touch;
}

.today-current {
  background: linear-gradient(135deg, var(--accent-softer) 0%, var(--toach-soft) 100%);
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  padding: 18px 20px;
  margin-bottom: 20px;
  box-shadow: 0 1px 2px rgba(15, 31, 42, 0.04);
  /* Defensive against long unbroken strings (Zoom URLs in location,
     pasted tokens in titles). max-width keeps us inside the parent;
     min-width: 0 lets flex/grid children shrink. The actual wrap is
     done by overflow-wrap on the text children below — we deliberately
     don't set overflow:hidden here because the post-it variant has a
     washi-tape decoration with top:-7px that needs to bleed past the
     box. */
  max-width: 100%;
  min-width: 0;
}

.today-current .now-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--toach-deep);
  margin-bottom: 6px;
}

.today-current .now-title {
  font-family: var(--font-serif);
  font-size: 22px;
  color: var(--text);
  line-height: 1.2;
  margin-bottom: 4px;
  /* See .today-current — break long unbroken tokens at any character so
     Zoom URLs / meeting tokens wrap inside the card. */
  overflow-wrap: anywhere;
  word-break: break-word;
}

.today-current .now-meta {
  font-size: 13px;
  color: var(--text-muted);
  overflow-wrap: anywhere;
  word-break: break-word;
}

.timeline {
  list-style: none;
  padding: 0;
  margin: 0;
}

.timeline-loading {
  color: var(--text-subtle);
  font-size: 14px;
  text-align: center;
  padding: 40px 0;
  list-style: none;
}

.timeline-item {
  display: grid;
  grid-template-columns: 64px 20px 1fr;
  gap: 12px;
  padding: 10px 0;
  align-items: start;
  position: relative;
}

.timeline-item + .timeline-item::before {
  content: "";
  position: absolute;
  left: 72px;
  top: -8px;
  bottom: calc(100% - 18px);
  width: 2px;
  background: var(--hair);
}

.timeline-time {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  padding-top: 4px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.timeline-marker {
  display: flex;
  justify-content: center;
  padding-top: 6px;
}

.timeline-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--surface);
  display: inline-block;
}

.timeline-dot-event { background: var(--accent); }
.timeline-dot-task { background: var(--toach); }

.timeline-content {
  padding-top: 2px;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}

.timeline-title {
  font-size: 15px;
  color: var(--text);
  line-height: 1.35;
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
  /* Break unbroken tokens (long URLs etc.) at any character so they
     don't push the timeline row wider than the viewport. */
  overflow-wrap: anywhere;
  word-break: break-word;
}

.timeline-loc {
  display: block;
  font-size: 12px;
  color: var(--text-subtle);
  margin-top: 2px;
  /* Calendar events commonly carry a Zoom/Meet URL in location; without
     this the unbroken URL token would horizontally overflow the row. */
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* State variants */
.timeline-past .timeline-time,
.timeline-past .timeline-title,
.timeline-past .timeline-loc {
  color: var(--text-subtle);
}
.timeline-past .timeline-dot {
  background: var(--text-subtle);
  opacity: 0.5;
}

.timeline-now {
  background: var(--accent-softer);
  margin: 6px -12px;
  padding: 12px;
  border-radius: var(--radius-sm);
}
.timeline-now .timeline-dot {
  box-shadow: 0 0 0 3px var(--surface), 0 0 0 6px rgba(91, 168, 214, 0.25);
}
.timeline-now .timeline-title {
  font-weight: 600;
}

/* Per-event reminder bell on timed calendar events. */
.timeline-reminder-btn {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  background: none;
  border: none;
  color: var(--text-subtle);
  padding: 3px 5px;
  border-radius: 8px;
  cursor: pointer;
}
.timeline-reminder-btn:hover {
  background: var(--surface-alt);
  color: var(--text);
}
.timeline-reminder-btn.has-override {
  color: #6b8e5a;
}
.timeline-reminder-mins {
  font-size: 11px;
  font-weight: 600;
}

/* Badges */
.task-done,
.task-high {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 999px;
}
.task-done {
  background: var(--success-soft);
  color: var(--toach-deep);
}
.task-high {
  background: var(--slip-soft);
  color: var(--slip);
}
.timeline-owner {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(96, 165, 250, 0.18);
  color: #1e3a8a;
}

/* Unscheduled */
.today-unscheduled {
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--hair);
}
.today-unscheduled h4 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin: 0 0 12px;
  font-weight: 600;
}
.today-unscheduled ul {
  list-style: none;
  padding: 0;
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.unsched-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--hair);
  font-size: 14px;
}
.unsched-item:last-child { border-bottom: none; }
.unsched-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--toach);
  flex-shrink: 0;
}
.unsched-title {
  flex: 1;
  color: var(--text);
}
.unsched-mins {
  font-size: 12px;
  color: var(--text-subtle);
  font-variant-numeric: tabular-nums;
}

/* Empty state */
.today-empty {
  text-align: center;
  padding: 60px 20px;
  color: var(--text-muted);
}
.today-empty p {
  margin: 0 0 6px;
  font-family: var(--font-serif);
  font-size: 18px;
  color: var(--text);
}
.today-empty .subtle {
  font-family: var(--font-ui);
  font-style: normal;
  font-size: 13px;
  color: var(--text-subtle);
}

/* ============================================================
   Review screen
   ============================================================ */

.review-section {
  margin-bottom: 28px;
}
.review-section h3 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin: 0 0 10px;
  font-weight: 600;
}
.review-section .subtle {
  font-size: 13px;
  color: var(--text-subtle);
  margin: 0 0 10px;
}

.review-list {
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.review-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--hair);
  font-size: 14px;
  color: var(--text);
}
.review-item:last-child { border-bottom: none; }
.review-title {
  flex: 1;
  line-height: 1.35;
}
.review-meta {
  font-size: 12px;
  color: var(--text-subtle);
  font-variant-numeric: tabular-nums;
}
.review-check {
  color: var(--toach-deep);
  font-weight: 600;
  width: 18px;
  text-align: center;
}
.review-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-subtle);
  opacity: 0.6;
  margin: 0 5px;
  flex-shrink: 0;
}
.review-done .review-title { color: var(--text-muted); }

#review-completed-summary {
  margin-top: 10px;
  font-family: var(--font-serif);
  font-size: 14px;
  color: var(--toach-deep);
}

.btn-small {
  background: var(--accent-softer);
  color: var(--accent-deep);
  border: none;
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.btn-small:hover {
  background: var(--accent-soft);
}

.review-rollover {
  margin-top: 12px;
  display: flex;
  justify-content: flex-end;
}

#review-note {
  width: 100%;
  min-height: 80px;
  padding: 14px 16px;
  font-family: var(--font-serif);
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  resize: vertical;
  box-sizing: border-box;
  outline: none;
}
#review-note:focus {
  border-color: var(--accent);
}

.review-save-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
}

/* Date navigation (Today + Review) */
.date-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;             /* was 6 — more breathing room around the pill */
  padding: 10px 16px 8px;
  background: var(--bg);
  border-bottom: 1px solid rgba(40, 70, 90, 0.12);
}
.date-nav-btn {
  /* Bumped from 36px to 40px so the chevrons sit on a clearer target.
     Outline + soft elevation reads as a real button instead of "text
     floating in space" — was the failure mode of the previous design. */
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text);
  border: 1px solid rgba(40, 70, 90, 0.18);
  box-shadow: 0 1px 2px rgba(15, 31, 42, 0.06);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s, transform 0.05s, box-shadow 0.15s;
}
.date-nav-btn svg {
  display: block;
}
.date-nav-btn:hover {
  background: var(--surface-alt);
  color: var(--text);
  border-color: rgba(40, 70, 90, 0.32);
}
.date-nav-btn:active {
  transform: scale(0.94);
  box-shadow: 0 1px 1px rgba(15, 31, 42, 0.08) inset;
}
.date-nav-today {
  /* Was a quiet ghost-button. Now reads as a proper pill: solid surface,
     outline, full-strength text, slightly larger. Tap-to-jump-to-today
     is a real action so it deserves a real-button affordance. */
  background: var(--surface);
  color: var(--text);
  border: 1px solid rgba(40, 70, 90, 0.18);
  font-size: 14px;
  font-weight: 700;
  padding: 9px 20px;
  border-radius: 999px;
  cursor: pointer;
  letter-spacing: 0.01em;
  box-shadow: 0 1px 2px rgba(15, 31, 42, 0.06);
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.05s;
}
.date-nav-today:hover {
  background: var(--accent-softer);
  border-color: var(--accent);
  color: var(--accent-deep);
}
.date-nav-today:active {
  transform: scale(0.97);
}

/* Date-nav pill picker overlay.
   ----------------------------
   The visible pill is the <button>; a native <input type="date"> sits
   directly on top of it at opacity 0. iOS handles the tap natively and
   pops its system date picker — no JS showPicker() needed, which is
   what fixes the "I clicked but nothing happened" bug from the earlier
   offscreen-input approach (Safari refused to open the picker on an
   input positioned at left:-9999px with pointer-events:none).

   The input is sized via `inset: 0` to exactly cover the button. The
   chevrons sit OUTSIDE the host span so their taps are untouched. */
.date-nav-today-host {
  position: relative;
  display: inline-block;
}
.date-nav-today-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: 0;
  padding: 0;
  margin: 0;
  background: transparent;
  font: inherit;
  /* Above the button visually so the tap reaches the input first. */
  z-index: 2;
  -webkit-appearance: none;
  appearance: none;
}

/* ============================================================
   Tasks screen
   ============================================================ */

/* ======================================================================
   Tasks screen scope segmented control (Personal | Household).
   Sits above the Open/Done status tabs as a separate filter axis.
   ====================================================================== */
.scope-segmented {
  display: flex;
  margin: 12px 16px 0;
  /* Track tone bumped from `--surface` (white) to a navy-tinged 6%
     wash so the segmented control reads as a real grouped surface. The
     coral screen wash made the previous white-on-white track invisible. */
  background: rgba(40, 70, 90, 0.07);
  border: 1px solid rgba(40, 70, 90, 0.14);
  border-radius: 12px;
  padding: 4px;
  gap: 4px;
  box-shadow: inset 0 1px 2px rgba(15, 31, 42, 0.04);
}
.scope-seg {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--text-muted);
  /* Bumped from 12/600 to 13/700 + tighter letterspacing so labels read
     bold even before the user notices which side is active. */
  font-size: 13px;
  font-weight: 700;
  padding: 9px 14px;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  letter-spacing: 0.01em;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s, transform 0.05s;
}
.scope-seg:active {
  transform: scale(0.97);
}
.scope-seg.active {
  /* Solid navy gradient + white text is unambiguously "selected".
     Sky-blue tints (the old `--accent-softer`) failed against the
     screen's coral wash. Navy passes WCAG AA at >12:1 contrast vs
     white text and matches the bottom tab bar palette so the visual
     language is consistent across the app. */
  background: linear-gradient(135deg, #2D3E5A 0%, #1A2A4B 100%);
  color: #FFFFFF;
  box-shadow:
    0 2px 6px rgba(15, 31, 42, 0.24),
    inset 0 1px 0 rgba(255, 255, 255, 0.10);
}
.scope-seg-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--accent);   /* always sky blue — the "personal" cue */
  opacity: 1;
  display: inline-block;
}
.scope-seg.active .scope-seg-dot {
  /* On dark fill, lift the dot to a brighter sky and ring it so it
     stays crisp against the gradient. */
  background: #7CC4E8;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.20);
}
.scope-seg.active.scope-seg-household {
  /* Household keeps the same bold dark treatment but in a slightly
     warmer slate to differentiate from personal. The dot's absence on
     this segment is itself the "household" cue. */
  background: linear-gradient(135deg, #5E6E7D 0%, #3F4D5C 100%);
  color: #FFFFFF;
  box-shadow:
    0 2px 6px rgba(63, 77, 92, 0.30),
    inset 0 1px 0 rgba(255, 255, 255, 0.10);
}

/* ======================================================================
   Household scope tokens. Neutral gray-blue so the household color
   doesn't fight any of the per-user owner-palette colors.
   ====================================================================== */
:root {
  --household: #6B7A89;
  --household-soft: #E5EAEF;
  --household-softer: #EFF2F5;
}

/* ======================================================================
   Fairness view (Story 2). One header band on Tasks/Household with a
   window selector + a one-line leaderboard. Per-row chips below the
   meta line on each unclaimed chore.
   ====================================================================== */
.fairness-header {
  padding: 10px 16px 8px;
  border-bottom: 1px solid var(--hair);
  background: var(--bg);
}
.fairness-header.hidden { display: none; }
.fairness-window-segmented {
  display: inline-flex;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: 999px;
  padding: 2px;
  gap: 2px;
  margin-bottom: 6px;
}
.fairness-window-seg {
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  padding: 4px 12px;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
}
.fairness-window-seg.active {
  background: var(--household-softer);
  color: var(--household);
}
.fairness-leaderboard {
  font-size: 12px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
}
.fairness-leaderboard b {
  color: var(--text);
  font-weight: 600;
}
.fairness-leader-name {
  display: inline-block;
}
.fairness-leader-name + .fairness-leader-name::before {
  content: " · ";
  opacity: 0.5;
}

/* Per-row chip on unclaimed household chores (Tasks/Household list). */
.task-row-fairness {
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-subtle);
  font-variant-numeric: tabular-nums;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
}
.task-row-fairness-name {
  white-space: nowrap;
}

/* Household-chore visual cues on Tasks list rows. A dashed circle replaces
   the solid one; a household badge marks the row; an unclaimed badge
   stands out in the warm-orange "slip" color. */
.task-row-circle.dashed {
  border-style: dashed;
  border-color: var(--household);
}
.task-badge {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--text-muted);
}
.task-badge-household {
  background: var(--household-soft);
  color: var(--household);
}
.task-badge-unclaimed {
  background: var(--slip-soft);
  color: var(--slip);
}
.task-badge-assignee {
  background: var(--accent-softer);
  color: var(--accent-deep);
}

/* "Reassign…" link tucked at the right edge of household-chore rows. */
.task-row-reassign {
  margin-left: 6px;
  font-size: 12px;
  color: var(--text-muted);
  background: transparent;
  border: none;
  padding: 4px 6px;
  cursor: pointer;
  font-family: inherit;
}
.task-row-reassign:hover, .task-row-reassign:active {
  color: var(--accent-deep);
}

/* Reassign modal contents — reuses the family-modal/.family-modal-card
   shell from Family View so it looks at home. */
.reassign-task-title {
  font-size: 13px;
  color: var(--text-muted);
  margin-bottom: 14px;
  line-height: 1.4;
}
.reassign-members {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.reassign-member {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--hair);
  border-radius: 12px;
  background: var(--surface);
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  text-align: left;
  width: 100%;
}
.reassign-member:hover, .reassign-member:active {
  background: var(--accent-softer);
  border-color: var(--accent);
}
.reassign-member-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  color: white;
  flex-shrink: 0;
}
.reassign-member-name {
  flex: 1;
}
.reassign-member-self {
  font-size: 11px;
  color: var(--text-subtle);
}

/* Claimed household chore in an assignee's column — keep the per-owner
   border color but tint the background so it reads as a chore, not a
   personal task. */
.family-block-task.household {
  background: var(--household-softer) !important;
}
.family-block-task.household .family-block-title::before {
  content: "🏠 ";
  font-size: 9px;
}

.tasks-tabs {
  display: flex;
  gap: 6px;
  padding: 10px 16px;
  background: var(--bg);
  /* Border darkened to match the bumped contrast on the scope control
     above — both controls read as a single defined "filter shelf". */
  border-bottom: 1px solid rgba(40, 70, 90, 0.14);
}
.tasks-tab {
  flex: 1;
  border: none;
  /* Tinted track on every tab (active or not) so they read as real
     segmented buttons rather than transparent text. */
  background: rgba(40, 70, 90, 0.06);
  color: var(--text-muted);
  font-size: 14px;       /* was 13 */
  font-weight: 700;      /* was 600 */
  padding: 9px 14px;
  border-radius: 999px;
  cursor: pointer;
  letter-spacing: 0.01em;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s, transform 0.05s;
}
.tasks-tab:active {
  transform: scale(0.97);
}
.tasks-tab.active {
  /* Same navy fill as the scope control's active state. White text on
     navy is the loudest readable combo and ties into the bottom-bar /
     scope-control language. */
  background: linear-gradient(135deg, #2D3E5A 0%, #1A2A4B 100%);
  color: #FFFFFF;
  box-shadow:
    0 2px 6px rgba(15, 31, 42, 0.24),
    inset 0 1px 0 rgba(255, 255, 255, 0.10);
}

.tasks-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 16px 20px;
  -webkit-overflow-scrolling: touch;
}

.tasks-group {
  margin-bottom: 20px;
}
.tasks-group h4 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  font-weight: 600;
  margin: 4px 4px 8px;
}

.tasks-list {
  list-style: none;
  padding: 0;
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.task-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--hair);
}
.task-row:last-child { border-bottom: none; }

.task-row-check {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.task-row-circle {
  width: 20px;          /* was 18 — slightly larger target */
  height: 20px;
  border-radius: 50%;
  /* Was 2px solid var(--hair) (~8% alpha) which was nearly invisible
     against the white card. Bumped to a 2.5px ring in `--text-muted`
     so the "I can tap this to complete" affordance is unmistakable. */
  border: 2.5px solid var(--text-muted);
  display: inline-block;
  transition: border-color 0.15s, background 0.15s, transform 0.1s;
}
.task-row-check:hover .task-row-circle {
  /* Stronger hover so the affordance is even more obvious on hover. */
  border-color: var(--toach-deep);
  background: var(--toach-soft);
}
.task-row-check:active .task-row-circle {
  transform: scale(0.92);
}
.task-row-check-mark {
  color: var(--toach-deep);
  font-weight: 600;
  font-size: 16px;
}

.task-row-main {
  flex: 1;
  min-width: 0;
}
.task-row-title {
  font-size: 15px;
  color: var(--text);
  line-height: 1.35;
  word-wrap: break-word;
}
.task-row-meta {
  margin-top: 3px;
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--text-subtle);
  font-variant-numeric: tabular-nums;
}

.task-category {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--text-muted);
}

.task-row-active {
  background: linear-gradient(90deg, var(--accent-softer) 0%, transparent 100%);
}
.task-row-active .task-row-title {
  font-weight: 600;
}
.task-row-active .task-row-circle {
  border-color: var(--accent);
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--surface), 0 0 0 6px rgba(91, 168, 214, 0.2);
  animation: task-active-pulse 2s ease-in-out infinite;
}
@keyframes task-active-pulse {
  0%, 100% { box-shadow: 0 0 0 3px var(--surface), 0 0 0 6px rgba(91, 168, 214, 0.2); }
  50% { box-shadow: 0 0 0 3px var(--surface), 0 0 0 8px rgba(91, 168, 214, 0.12); }
}

.task-row-done .task-row-title {
  color: var(--text-subtle);
  text-decoration: line-through;
  text-decoration-color: var(--text-subtle);
}
.task-row-done .task-row-check {
  cursor: default;
}

.task-row-actual {
  font-size: 12px;
  color: var(--text-subtle);
  font-variant-numeric: tabular-nums;
}

.btn-complete {
  background: var(--success-soft);
  color: var(--toach-deep);
}
.btn-complete:hover {
  background: var(--toach-soft);
}

.tasks-empty {
  text-align: center;
  padding: 60px 20px;
}
.tasks-empty p {
  margin: 0 0 6px;
  font-family: var(--font-serif);
  font-size: 18px;
  color: var(--text);
}
.tasks-empty .subtle {
  font-family: var(--font-ui);
  font-style: normal;
  font-size: 13px;
  color: var(--text-subtle);
}

.tasks-add {
  padding: 10px 16px calc(14px + var(--safe-bottom));
  background: var(--bg);
  border-top: 1px solid var(--hair);
  display: flex;
  align-items: center;
  gap: 8px;
}
.tasks-add input {
  flex: 1;
  min-width: 0;
  padding: 12px 16px;
  font-size: 15px;
  font-family: var(--font-ui);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: 999px;
  outline: none;
  box-sizing: border-box;
  transition: border-color 0.15s;
}
.tasks-add input:focus {
  border-color: var(--accent);
}
.tasks-add input::placeholder {
  color: var(--text-subtle);
}
.tasks-add-btn {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: none;
  background: var(--accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.15s, transform 0.1s, opacity 0.15s;
}
.tasks-add-btn:active {
  transform: scale(0.92);
}
.tasks-add-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

/* ======================================================================
   Bottom Tab Bar — persistent navigation across Today / Tasks / Chat / Review
   ====================================================================== */
.tab-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: stretch;
  background: var(--tabbar-bg);
  /* Hairline at the top of the bar — uses the on-dark hair token so it
     reads as a soft separation from the app body without being a hard
     bright line. */
  border-top: 1px solid var(--tabbar-hair);
  padding-bottom: var(--safe-bottom);
  z-index: 1000;
  /* Slightly stronger lift shadow because the navy bar sits over a near-
     white app body — a 0.05 alpha was tuned for white-on-white. */
  box-shadow: 0 -2px 14px rgba(15, 31, 42, 0.18);
}
.tab-bar.hidden {
  display: none;
}
.tab-btn {
  flex: 1;
  background: transparent;
  border: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 8px 4px 10px;
  color: var(--tabbar-fg);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: color 0.15s, transform 0.1s;
  -webkit-tap-highlight-color: transparent;
}
.tab-btn svg {
  display: block;
  flex-shrink: 0;
  /* SVGs use stroke="currentColor" so they inherit color naturally. */
}
.tab-btn:active {
  transform: scale(0.94);
}
.tab-btn.active {
  color: var(--tabbar-fg-active);
}
.tab-btn.active svg {
  /* Beef up stroke on active so the icon visually "fills in" against the
     dark background — same spirit as the previous 1.7→2 bump. */
  stroke-width: 2.1;
}

/* When tab bar is visible, leave room at the bottom of every screen.
   Tab bar already absorbs safe-bottom; chat input / tasks-add then drop their
   own safe-bottom padding so we don't double up. */
body:not(.no-tabbar) #today-screen,
body:not(.no-tabbar) #tasks-screen,
body:not(.no-tabbar) #chat-screen,
body:not(.no-tabbar) #decisions-screen,
body:not(.no-tabbar) #review-screen,
body:not(.no-tabbar) #settings-screen {
  padding-bottom: calc(var(--tabbar-h) + var(--safe-bottom));
}

body:not(.no-tabbar) .input-area {
  padding-bottom: 12px;
}

body:not(.no-tabbar) .tasks-add {
  padding-bottom: 14px;
}

/* ======================================================================
   Family View
   Multi-column day grid: time axis on the left, one column per household
   member. Blocks are absolute-positioned within each column's canvas.
   ====================================================================== */

.family-body {
  flex: 1;
  overflow: hidden;
  background: var(--bg);
  padding: 0;
}

/* Single-scroller layout: .family-cols-wrap is THE scroll container for both
   axes, and the time gutter rides inside it pinned with position:sticky.
   The previous structure (vertical scroll on .family-body, horizontal on a
   nested .family-cols-wrap) hit an iOS WebKit behavior where a touch starting
   inside the nested horizontal scroller never handed the vertical component
   up to the outer scroller — so the grid only scrolled up/down when the drag
   started on the time gutter (which lived outside the nested scroller). With
   one scroller, a drag anywhere pans the grid in any direction. */
.family-grid {
  display: block;
  position: relative;
  height: 100%;
}

.family-time-axis {
  position: sticky;
  left: 0;
  z-index: 6;
  width: 56px;
  flex: 0 0 56px;
  /* Was `var(--surface-alt)` (#EEF4F7) on a 0.18 hair — both too pale to
     anchor the eye when reading times across a wide column grid. Now a
     navy-tinged tone in the same family as the bottom tab bar so the
     left rail reads as a clear gutter rather than fading into the wash.
     The tint is stacked over the page background so the gutter is opaque —
     it must cover the columns that now slide beneath it. */
  border-right: 1px solid rgba(40, 70, 90, 0.30);
  background: linear-gradient(rgba(40, 70, 90, 0.10), rgba(40, 70, 90, 0.10)), var(--bg);
  flex-shrink: 0;
  /* Pushed down to align with the column canvas tops — the column header +
     all-day row take up vertical space inside each column, so without this
     offset the ticks would float above where events actually render. The
     value is set by _alignFamilyCanvasOffset after layout. */
  margin-top: var(--family-canvas-offset, 0);
}

.family-time-tick {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  border-top: 1px dashed transparent;
  font-size: 11px;
  color: var(--text);   /* was var(--text-muted) — full-strength for legibility */
  font-weight: 600;     /* was 500 */
  font-variant-numeric: tabular-nums;
}

.family-time-tick > span {
  position: absolute;
  top: -7px;
  right: 6px;
  /* The label background needs to match the gutter exactly so it reads
     as "the time, on the gutter" rather than a pill on a different
     surface. Using rgba(...) with 1.0 alpha by stacking the gutter tint
     over the bg ensures consistency even when the screen wash bleeds in. */
  background: linear-gradient(rgba(40, 70, 90, 0.10), rgba(40, 70, 90, 0.10)), var(--bg);
  padding: 1px 4px;
  border-radius: 4px;
}

.family-cols-wrap {
  position: relative;
  display: flex;
  /* flex-start, NOT stretch: with the wrap now height-constrained (it's the
     scroll container), stretch sized each member column to the ~viewport
     height instead of the full 24h canvas — so below roughly 11am the
     columns' white surface ended and the zebra hour bands showed through as
     stray bars. flex-start lets each column size to its content (header +
     all-day row + the 24h canvas), which also defines the scroll extent. */
  align-items: flex-start;
  /* The one true scroller — both axes. See .family-grid comment. */
  height: 100%;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 16px;
}

/* Current-time indicator — a thin red line across all columns at the local
   (household Eastern) time, shown only when the grid is on today's date.
   Positioned inside .family-hourlines so it shares the canvas offset and
   lines up exactly with the hour gridlines and event blocks. */
.family-now-line {
  position: absolute;
  left: 0;
  /* Width set in JS to the wrap's scrollWidth so the line spans every
     column, including ones scrolled in from the right. */
  height: 0;
  border-top: 2px solid #E5484D;
  /* Above the sticky time gutter (z 6) so the line reads across the whole
     row, gutter included — matches the Apple/Google calendar treatment. */
  z-index: 7;
  pointer-events: none;
}
.family-now-dot {
  position: absolute;
  /* Sits on the gutter/canvas boundary (gutter is 56px wide). */
  left: 51px;
  top: -4px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #E5484D;
}

/* Alternating hour bands for readability — every other hour gets a subtle
   tint so the eye can follow rows across columns. Bands sit behind the
   gridlines and blocks. */
.family-hourlines {
  position: absolute;
  inset: 0;
  /* Override inset's top so the hour gridlines start at the canvas top
     (below the column heads + all-day rows) rather than at the cols-wrap
     top. Same offset as the time axis — keeps tick labels on the left
     visually aligned with the gridlines that cross the columns. */
  top: var(--family-canvas-offset, 0);
  pointer-events: none;
  z-index: 0;
}

.family-hourline {
  position: absolute;
  left: 0;
  right: 0;
  border-top: 1px solid rgba(40, 70, 90, 0.10);
}

.family-hourband {
  position: absolute;
  left: 0;
  right: 0;
  background: rgba(91, 168, 214, 0.04);
  pointer-events: none;
}

.family-col {
  flex: 1 1 0;
  min-width: 140px;
  border-right: 1px solid rgba(40, 70, 90, 0.12);
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 1;
}

.family-col:last-child {
  border-right: none;
}

/* Column header — bumped contrast so it reads as a real header band, not
   a faint divider. Light gradient + bottom border + solid name color. */
.family-col-head {
  position: sticky;
  top: 0;
  z-index: 3;
  background: linear-gradient(180deg, var(--surface) 0%, var(--surface-alt) 100%);
  border-bottom: 1px solid rgba(40, 70, 90, 0.18);
  padding: 12px 10px 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  box-shadow: 0 2px 4px rgba(15, 31, 42, 0.04);
}

/* Name pill — replaces the prior avatar (circled initial) + name combo.
   Colored background uses the per-user palette generated from a hash of
   the username, so each member has a stable identity color across the
   app. The pill takes the full available column width and shows the
   complete name without truncation in normal column sizes. */
.family-col-name-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.005em;
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Per-user background + color come from `oc.bg` / `oc.fg` inline (set
     in app.js renderFamilyView). Falls back to a neutral pill so old
     code paths still render something legible. */
  background: var(--surface-alt);
  color: var(--text);
  box-shadow: inset 0 0 0 1px rgba(40, 70, 90, 0.08);
}

.family-col-gear {
  border: none;
  background: rgba(40, 70, 90, 0.06);
  color: var(--text-muted);
  cursor: pointer;
  padding: 6px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.family-col-gear:hover, .family-col-gear:active {
  background: var(--accent-softer);
  color: var(--accent-deep);
}

.family-allday-row {
  padding: 6px 6px;
  border-bottom: 1px solid rgba(40, 70, 90, 0.12);
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  background: var(--surface-alt);
}

.family-allday {
  font-size: 11px;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
  cursor: pointer;
}

.family-col-canvas {
  position: relative;
  /* Sized by its inline height (the full 24h grid), NOT by flexing. With the
     column no longer stretched to the wrap (see .family-cols-wrap), a
     flex-grow basis-0 canvas would collapse instead of spanning the day. */
  flex: 0 0 auto;
  background: var(--surface);
}

/* Visible-hours band (the user's selected start→end). The band used to draw
   accent borders at its top/bottom edges, but with the default range starting
   at 8 AM that read as a mysterious blue line at 8AM (mistaken for a broken
   time indicator — the red now-line is the real one). The range still drives
   the initial scroll anchor; it just has no visual marker now. */
.family-col-window {
  position: absolute;
  left: 0;
  right: 0;
  background: transparent;
  border: none;
  pointer-events: none;
}

.family-block {
  position: absolute;
  left: 4px;
  right: 4px;
  border-radius: 8px;
  border: 1px solid;
  padding: 4px 6px;
  font-size: 11px;
  line-height: 1.2;
  overflow: hidden;
  cursor: default;
  box-shadow: 0 1px 2px rgba(15, 31, 42, 0.06);
}

.family-block-event {
  /* Filled block — calendar event from a connected calendar. */
}

.family-block-task {
  /* Outlined block — Toach-managed task, visually distinct from events. */
  background: var(--surface);
  border-style: dashed;
  border-width: 1.5px;
}

.family-block-title {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.family-block-time {
  font-size: 10px;
  opacity: 0.85;
  margin-top: 1px;
}

.family-block-status {
  margin-left: 4px;
  font-weight: 700;
}

/* Family-block detail popup. Triggered by tapping any non-pool event/task
   block in the Family timeline. Backdrop dismisses on tap; the inner card
   stops propagation so taps inside (e.g. selecting text in a long title)
   don't fire the dismiss. */
.family-block-popup {
  position: fixed;
  inset: 0;
  background: rgba(15, 31, 42, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1100;
  padding: 20px;
  -webkit-backdrop-filter: blur(2px);
          backdrop-filter: blur(2px);
}
.family-block-popup.hidden { display: none; }
.family-block-popup-card {
  background: var(--surface);
  border-radius: 14px;
  padding: 18px 20px 16px;
  width: 100%;
  max-width: 380px;
  box-shadow: 0 24px 64px rgba(15, 31, 42, 0.32),
              0 4px 12px rgba(15, 31, 42, 0.18);
}
.family-block-popup-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}
.family-block-popup-kind {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.family-block-popup-close {
  border: none;
  background: transparent;
  font-size: 22px;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px 8px;
  margin: -4px -8px;
}
.family-block-popup-close:hover { color: var(--text); }
.family-block-popup-title {
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
  /* No truncation here — the whole point of the popup is to show the full
     title that the inline block had to cut off. Wraps freely. */
  white-space: normal;
  overflow-wrap: anywhere;
  margin: 0 0 12px;
  line-height: 1.3;
}
.family-block-popup-rows {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.family-block-popup-row {
  display: flex;
  gap: 12px;
  font-size: 14px;
  color: var(--text);
  line-height: 1.4;
}
.family-block-popup-label {
  flex-shrink: 0;
  width: 78px;
  color: var(--text-muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding-top: 1px;
}

/* Per-column hour-range modal. Backdrop + centered card. Tap backdrop to
   dismiss; Done / Cancel / Reset buttons inside the card. */
.family-modal {
  position: fixed;
  inset: 0;
  background: rgba(15, 31, 42, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 20px;
}

.family-modal-card {
  background: var(--surface);
  border-radius: var(--radius);
  padding: 18px 20px 16px;
  width: 100%;
  max-width: 320px;
  box-shadow: 0 12px 40px rgba(15, 31, 42, 0.32);
}

.family-modal-title {
  font-weight: 600;
  margin-bottom: 14px;
  font-size: 15px;
  color: var(--text);
}

.family-modal-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
  font-size: 14px;
}

.family-modal-row label {
  color: var(--text-muted);
}

.family-modal-row select {
  border: 1px solid var(--hair);
  border-radius: 10px;
  padding: 8px 10px;
  background: var(--surface);
  font-size: 14px;
  color: var(--text);
  min-width: 150px;
}

.family-modal-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 14px;
  gap: 8px;
}

.family-modal-buttons {
  display: flex;
  gap: 8px;
}

.btn-link {
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  padding: 6px 0;
  font-size: 13px;
}

.btn-link:hover {
  color: var(--text);
}

/* ======================================================================
   Today screen drag-to-reschedule
   Free-time gaps render as drop zones. While dragging a task over a gap
   it expands ("zooms") to show 15-minute tick marks; the pointer Y
   selects the drop time precisely.
   ====================================================================== */

.timeline-gap {
  position: relative;
  /* Was a near-invisible 1px hair against the surface-alt background.
     Bumped to a 1.5px dashed line in a clearly-visible muted blue, plus
     a deeper wash so the bar reads as a real "open time" target rather
     than empty space. The Today header's sky-blue accent informs the
     palette so the bars feel native to the screen. */
  border: 1.5px dashed rgba(58, 131, 176, 0.45);
  border-radius: var(--radius-sm);
  background: rgba(91, 168, 214, 0.10);
  color: var(--accent-deep);
  margin: 6px 0;
  padding: 10px 12px;
  font-size: 12px;
  font-weight: 500;
  transition: padding 0.15s, background 0.15s, border-color 0.15s;
  cursor: default;
}

.timeline-gap.drag-over {
  background: var(--accent-softer);
  border-color: var(--accent);
  color: var(--accent-deep);
  padding: 0;
}

.timeline-gap-label {
  display: block;
}

.timeline-gap.drag-over .timeline-gap-label {
  display: none;
}

.timeline-gap-zoom {
  position: relative;
  display: none;
}

.timeline-gap.drag-over .timeline-gap-zoom {
  display: block;
}

.timeline-gap-tick {
  position: absolute;
  left: 0;
  right: 0;
  border-top: 1px dotted var(--accent);
  font-size: 10px;
  color: var(--accent-deep);
  padding-left: 6px;
  pointer-events: none;
}

.timeline-gap-cursor {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--accent);
  pointer-events: none;
  z-index: 2;
  box-shadow: 0 0 0 2px var(--accent-soft);
}

.timeline-gap-cursor-label {
  position: absolute;
  right: 8px;
  top: -10px;
  background: var(--accent);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 6px;
}

/* Tasks on the Today timeline get a dashed left edge so they read as
   movable Toach-managed blocks distinct from solid calendar events. */
.timeline-item[data-kind="task"] .timeline-content {
  border-left: 2px dashed var(--toach);
  padding-left: 8px;
  margin-left: -2px;
}

.timeline-item[data-kind="task"][draggable="true"] {
  cursor: grab;
}
.timeline-item[data-kind="task"].dragging {
  opacity: 0.5;
}

.unsched-item[draggable="true"] {
  cursor: grab;
}
.unsched-item.dragging {
  opacity: 0.5;
}

/* Global .hidden helper. The codebase toggles this class on many elements
   (today-current, today-unscheduled-wrap, today-empty, etc.) but historically
   relied on per-element rules — most of which were never written. A single
   global rule covers them all. */
.hidden { display: none !important; }

/* ---- Today: unschedule drop zone ----
   Pinned to the bottom of the viewport during drag so it's always visible,
   regardless of how long the day's timeline is. */
.today-unschedule-target {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: calc(var(--tabbar-h) + 14px + var(--safe-bottom));
  z-index: 60;
  padding: 16px;
  border: 2px dashed var(--slip);
  border-radius: var(--radius-sm);
  background: var(--slip-soft);
  color: var(--slip);
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  box-shadow: 0 8px 24px rgba(15, 31, 42, 0.16);
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
}

.today-unschedule-target.drag-over {
  background: var(--slip);
  color: #fff;
  border-color: var(--slip);
  transform: scale(1.03);
}

.today-unschedule-target-inner {
  pointer-events: none;
}

/* ---- Family: column drag-to-reorder visuals ---- */
.family-col.family-col-dragging {
  opacity: 0.45;
}

.family-col.family-col-drop-before {
  box-shadow: inset 3px 0 0 0 var(--accent);
}

.family-col.family-col-drop-after {
  box-shadow: inset -3px 0 0 0 var(--accent);
}

/* Drag handle — explicit grab affordance so the user knows where to grab.
   Lives left of the avatar in the column header. */
.family-col-drag-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 2px;
  margin-right: -2px;
  color: var(--text-subtle);
  cursor: grab;
  border-radius: 6px;
  flex-shrink: 0;
}
.family-col-drag-handle:hover, .family-col-drag-handle:active {
  background: rgba(40, 70, 90, 0.06);
  color: var(--text-muted);
  cursor: grabbing;
}


/* ======================================================================
   Stories 5/6/7 — Decision threads
   ====================================================================== */

/* The Decisions screen has two sub-views (list + detail) that swap via
   .active. Both fill the screen height; only one is visible at a time.
   The screen-level .active hides the parent; sub-view .active picks
   which child fills the column. */
.decisions-subview {
  display: none;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.decisions-subview.active {
  display: flex;
}

/* List view */

.decisions-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 16px 96px;  /* leave room for the floating "Start" button */
  -webkit-overflow-scrolling: touch;
}
.decisions-empty {
  text-align: center;
  padding: 60px 24px;
}
.decisions-empty p {
  margin-bottom: 6px;
}

.decisions-group {
  margin-bottom: 22px;
}
.decisions-group-label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-subtle);
  margin: 6px 4px 8px;
}
.decisions-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.decision-card {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  padding: 14px 14px 12px;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.05s ease;
  font-family: inherit;
  color: inherit;
}
.decision-card:hover {
  background: var(--accent-softer);
}
.decision-card:active {
  transform: scale(0.99);
}
/* Decided-card delete affordance: a sibling of the card <button>, pinned to
   the card's right edge and vertically centered. The card gets extra right
   padding (below) so its text never runs under the trash icon. */
.decision-card-wrap {
  position: relative;
}
.decision-card-wrap .decision-card {
  padding-right: 44px;
}
.decision-card-delete {
  position: absolute;
  top: 50%;
  right: 8px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--text-subtle);
  cursor: pointer;
}
.decision-card-delete:hover {
  background: var(--surface-alt);
  color: #B85850;
}
.decision-card-row1 {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 4px;
}
.decision-card-title {
  font-weight: 600;
  font-size: 16px;
  color: var(--text);
}
.decision-card-row2 {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 2px;
}
.decision-card-deadline {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
}
.decision-card-deadline.urgent { color: #B85850; }
.decision-card-deadline.expired { color: #B85850; }
.decision-card-deadline.soon { color: var(--accent-deep); }
.decision-card-meta {
  font-size: 12px;
  color: var(--text-subtle);
}
.decision-card-row3 {
  font-size: 12px;
}
.decision-card-badge {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--text-muted);
}
.decision-card-badge.decided {
  background: var(--toach-soft);
  color: var(--toach-deep);
}
.decision-card-badge.expired {
  background: var(--slip-soft);
  color: #8B4F45;
}

.decisions-add {
  position: absolute;
  bottom: calc(var(--tabbar-h) + 16px);
  left: 16px;
  right: 16px;
  pointer-events: none;
}
.decisions-add .btn-primary {
  pointer-events: auto;
  width: 100%;
  box-shadow: 0 4px 14px rgba(40, 70, 90, 0.18);
}

/* Detail view */

.decision-deadline-banner {
  padding: 10px 16px;
  background: var(--accent-softer);
  border-bottom: 1px solid var(--hair);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-size: 14px;
}
.decision-deadline-banner.urgent {
  background: #FCEFEC;
}
.decision-deadline-banner.expired {
  background: #F5DAD3;
  color: #8B4F45;
}
.decision-deadline-banner.soon {
  background: var(--accent-soft);
}
.decision-deadline-when {
  color: var(--text);
  font-weight: 500;
}
.decision-deadline-countdown {
  font-weight: 600;
  color: var(--text);
}

.decision-participants-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--hair);
  background: var(--surface);
  align-items: center;
}
.decision-pill {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
}
.decision-pill-edit {
  margin-left: auto;
  background: transparent;
  border: none;
  color: var(--accent-deep);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  padding: 4px 6px;
}

/* @mention pills inside message bubbles. Per-user color comes from inline
   style (set by renderMessageWithMentions in app.js); the AI variant uses
   the toach palette so it visually reads as "you summoned the assistant". */
.decision-mention {
  display: inline-block;
  padding: 0 6px;
  border-radius: 6px;
  background: var(--surface-alt);
  color: var(--text);
  font-weight: 700;
}
.decision-mention-ai {
  background: var(--toach-soft);
  color: var(--toach-deep);
}
.decision-mention-unknown {
  background: var(--surface-alt);
  color: var(--text-muted);
  font-weight: 600;
}

/* Autocomplete popover that appears above the input when the user is
   typing `@xyz`. Anchored to .input-area which is position:relative. */
.mention-popover {
  position: absolute;
  bottom: 100%;
  left: 12px;
  right: 12px;
  margin-bottom: 6px;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: 12px;
  box-shadow: 0 -6px 18px rgba(40, 70, 90, 0.10);
  overflow: hidden;
  z-index: 50;
  max-height: 240px;
  overflow-y: auto;
}
.mention-popover-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  cursor: pointer;
  user-select: none;
}
.mention-popover-row.active,
.mention-popover-row:hover {
  background: var(--accent-softer);
}
.mention-popover-handle {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  background: var(--surface-alt);
  color: var(--text);
  flex-shrink: 0;
}
.mention-popover-label {
  flex: 1;
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mention-popover-ai {
  background: var(--toach-soft);
  color: var(--toach-deep);
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 4px;
  letter-spacing: 0.04em;
  flex-shrink: 0;
}

.decision-summary-banner {
  padding: 12px 16px;
  background: var(--toach-soft);
  color: var(--them-bubble-text);
  border-bottom: 1px solid var(--hair);
  font-size: 14px;
  line-height: 1.4;
}

.decision-messages {
  flex: 1;
  overflow-y: auto;
  padding: 12px 14px 16px;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.decision-msg-empty {
  margin: auto;
  text-align: center;
}

.decision-msg {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 86%;
}
.decision-msg.me {
  align-self: flex-end;
  align-items: flex-end;
}
.decision-msg.ai {
  align-self: flex-start;
}
.decision-msg-who {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 3px;
  font-size: 12px;
}
.decision-msg-author {
  font-weight: 600;
  color: var(--text-muted);
}
.decision-msg.me .decision-msg-author {
  color: var(--accent-deep);
}
.decision-msg-time {
  font-size: 11px;
}
.decision-ai-badge {
  display: inline-block;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.08em;
  padding: 2px 6px;
  border-radius: 999px;
  background: var(--toach);
  color: white;
}
.decision-msg-bubble {
  background: var(--them-bubble);
  color: var(--them-bubble-text);
  padding: 9px 13px;
  border-radius: 16px;
  border-top-left-radius: 4px;
  font-size: 15px;
  line-height: 1.4;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.decision-msg.me .decision-msg-bubble {
  background: var(--me-bubble);
  color: var(--me-bubble-text);
  border-top-left-radius: 16px;
  border-top-right-radius: 4px;
}
.decision-msg.ai .decision-msg-bubble {
  background: var(--toach-soft);
  color: var(--text);
  border: 1px solid rgba(94, 142, 93, 0.2);
}
.decision-msg.pending .decision-msg-bubble {
  opacity: 0.85;
}

.decision-msg-reply {
  margin-top: 6px;
  align-self: flex-start;
  background: transparent;
  border: 1px solid var(--hair);
  color: var(--toach-deep);
  font-size: 11px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s ease;
}
.decision-msg-reply:hover {
  background: var(--toach-soft);
}

.decision-ai-dots {
  display: inline-flex;
  gap: 4px;
}
.decision-ai-dots span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--toach-deep);
  display: inline-block;
  animation: decisionAIDot 1.2s ease-in-out infinite;
}
.decision-ai-dots span:nth-child(2) { animation-delay: 0.15s; }
.decision-ai-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes decisionAIDot {
  0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-2px); }
}

.decision-ai-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 14px 10px;
  border-top: 1px solid var(--hair);
  background: var(--surface-alt);
  align-items: center;
}
.decision-ai-label {
  font-size: 12px;
  color: var(--text-muted);
  font-weight: 500;
  margin-right: 4px;
}
.decision-ai-btn {
  background: var(--surface);
  border: 1px solid var(--hair);
  color: var(--toach-deep);
  font-size: 12px;
  font-weight: 600;
  padding: 6px 10px;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s ease;
}
.decision-ai-btn:hover {
  background: var(--toach-soft);
}
.decision-ai-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Create / decide modals */

.decision-create-body {
  padding: 4px 0 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.decision-field-label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-subtle);
  margin: 8px 0 2px;
}
.decision-create-body input[type="text"],
.decision-create-body input[type="date"],
.decision-create-body input[type="time"],
.decision-create-body textarea {
  width: 100%;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--hair);
  background: var(--surface);
  font-size: 15px;
  color: var(--text);
  font-family: inherit;
}
.decision-create-body textarea {
  resize: vertical;
  min-height: 60px;
}
.decision-deadline-row {
  display: flex;
  gap: 8px;
}
.decision-deadline-row input[type="date"] { flex: 2; }
.decision-deadline-row input[type="time"] { flex: 1; }

.decision-participants-picker {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 180px;
  overflow-y: auto;
  border: 1px solid var(--hair);
  border-radius: 10px;
  padding: 6px 10px;
}
.decision-participant-row {
  display: flex;
  gap: 10px;
  align-items: center;
  font-size: 14px;
  padding: 4px 0;
}

.decision-decide-ai-list {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 220px;
  overflow-y: auto;
}
.decision-decide-ai-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 13px;
  line-height: 1.4;
  padding: 6px 8px;
  border-radius: 8px;
  background: var(--surface-alt);
}
.decision-decide-ai-row input[type="checkbox"] { margin-top: 3px; }

.decision-menu-danger {
  color: #B85850 !important;
}


/* ======================================================================
   Universal task edit modal (recurrence + scope flip + delete)
   ====================================================================== */

.task-edit-card {
  width: min(420px, 92vw);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}
.task-edit-subview {
  display: none;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.task-edit-subview.active {
  display: flex;
}
.task-edit-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px 8px;
  gap: 8px;
}
.task-edit-header .family-modal-title {
  margin: 0;
}
.task-edit-close, .task-edit-back {
  background: transparent;
  border: none;
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  color: var(--text-muted);
  cursor: pointer;
}
.task-edit-close:hover, .task-edit-back:hover {
  background: var(--surface-alt);
  color: var(--text);
}
.task-edit-body {
  flex: 1;
  overflow-y: auto;
  padding: 4px 18px 16px;
  -webkit-overflow-scrolling: touch;
}
.task-edit-body input[type="text"],
.task-edit-body input[type="date"],
.task-edit-body input[type="time"],
.task-edit-body input[type="number"],
.task-edit-body select,
.task-edit-body textarea {
  width: 100%;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--hair);
  background: var(--surface);
  font-size: 15px;
  color: var(--text);
  font-family: inherit;
}
.task-edit-body textarea {
  resize: vertical;
  min-height: 56px;
}
.task-edit-row-2 {
  display: flex;
  gap: 10px;
}
.task-edit-row-2 > div {
  flex: 1;
}
.task-edit-row-button {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--hair);
  background: var(--surface);
  font-size: 15px;
  font-family: inherit;
  cursor: pointer;
  color: var(--text);
}
.task-edit-row-button:hover {
  background: var(--accent-softer);
}
.task-edit-scope {
  display: flex;
  border: 1px solid var(--hair);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface);
}
.task-edit-scope-seg {
  flex: 1;
  background: transparent;
  border: none;
  padding: 10px 12px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s ease, color 0.15s ease;
}
.task-edit-scope-seg.active {
  background: var(--accent-softer);
  color: var(--accent-deep);
}
.task-edit-danger {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--hair);
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.btn-danger {
  background: transparent;
  border: 1px solid #E0B7B0;
  color: #B85850;
  padding: 8px 14px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}
.btn-danger:hover {
  background: #FCEFEC;
}
.btn-not-needed {
  background: #FFD8E2;
  border: 1px solid #F3B8C7;
  color: #B83A6B;
  padding: 8px 14px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}
.btn-not-needed:hover {
  background: #F9C4D3;
}
.btn-not-needed:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Inline "Not needed" — paired left of Start/Claim in each task row. Same
   pill shape as .btn-small so the two actions read as a unit. Pink so it
   stands out at a glance without using the destructive red reserved for
   Delete. */
.btn-not-needed-inline {
  background: #FFD8E2;
  color: #B83A6B;
  border: 1px solid #F3B8C7;
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  margin-right: 6px;
  font-family: inherit;
}
.btn-not-needed-inline:hover {
  background: #F9C4D3;
}

.task-row-cancelled .task-row-title {
  color: var(--text-subtle);
  text-decoration: line-through;
  text-decoration-color: var(--text-subtle);
}
.task-row-cancelled .task-row-check {
  cursor: default;
}
.task-row-cancelled-label {
  font-size: 12px;
  color: var(--text-subtle);
  font-style: italic;
}
.task-edit-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border-top: 1px solid var(--hair);
  background: var(--surface);
}

/* Recurrence sub-view */
.recurrence-options {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 14px;
}
.recurrence-option {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 10px;
  cursor: pointer;
  background: var(--surface-alt);
  font-size: 15px;
}
.recurrence-option input[type="radio"]:checked ~ span {
  font-weight: 600;
}
.recurrence-config {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--hair);
}
.recurrence-day-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.recurrence-day-chips button {
  background: var(--surface);
  border: 1px solid var(--hair);
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 12px;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
  min-width: 50px;
}
.recurrence-day-chips button.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #FFFFFF;
}

/* "Recurring tasks" view (Tasks tab → Household segment) */
.recurring-toolbar {
  padding: 12px 16px 4px;
}
.recurring-new-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--accent);
  border: none;
  color: #FFFFFF;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 10px 16px;
  border-radius: 999px;
  cursor: pointer;
}
.recurring-new-btn:hover { filter: brightness(1.05); }
.recurring-pool-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.recurring-pool-chip {
  background: var(--surface);
  border: 1px solid var(--hair);
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
}
.recurring-pool-chip.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #FFFFFF;
}

/* Recurrence indicator on task cards */
.task-recurring {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 12px;
  color: var(--toach-deep);
  background: var(--toach-soft);
  padding: 1px 8px;
  border-radius: 999px;
  font-weight: 500;
}

/* Make the title/meta area look obviously tappable */
.task-row-main-clickable {
  cursor: pointer;
}
.task-row-main-clickable:hover .task-row-title {
  color: var(--accent-deep);
}

/* ======================================================================
   Post-its on a Whiteboard — visual layer (May 2026)

   Skin overlay added on top of the existing component CSS. The token
   block at the top of this file already shifted the global palette to
   the whiteboard look; this section adds the post-it primitives and
   applies them to the most-visible "hero" surfaces (Today's now-card,
   Decisions card, the unscheduled bucket on Today, Review items).

   Lower-traffic surfaces (Settings, modals, login, calendar admin) keep
   their plain card styling — re-skinning those is a follow-up.
   ====================================================================== */

/* Handwritten section headers — replaces the small-caps labels with a
   warmer Patrick-Hand look. Only applied to display labels; data labels
   (e.g. tabular column heads) stay in the system sans for legibility. */
.today-unscheduled h4,
.decisions-group-label,
.timeline-gap-label {
  font-family: var(--font-hand);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--text-muted);
  text-transform: none;
}

/* ── Post-it primitive ───────────────────────────────────────────── */
.postit {
  position: relative;
  background:
    radial-gradient(1px 1px at 20% 30%, rgba(0,0,0,0.025) 1px, transparent 0),
    radial-gradient(1px 1px at 70% 60%, rgba(0,0,0,0.02) 1px, transparent 0),
    radial-gradient(1px 1px at 50% 85%, rgba(0,0,0,0.025) 1px, transparent 0),
    linear-gradient(135deg, var(--pi-y0, var(--pi-yellow)) 0%, var(--pi-y1, var(--pi-yellow-2)) 100%);
  background-size: 80px 80px, 100px 100px, 90px 90px, auto;
  border-radius: 2px;
  box-shadow: var(--sh-postit);
  border: none;
}
.postit::after {
  /* curled-corner shadow on bottom-right */
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  width: 18px;
  height: 18px;
  background: linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.10) 100%);
  border-radius: 0 0 2px 0;
  pointer-events: none;
}
.postit-yellow { --pi-y0: var(--pi-yellow); --pi-y1: var(--pi-yellow-2); }
.postit-pink   { --pi-y0: var(--pi-pink);   --pi-y1: var(--pi-pink-2);   }
.postit-blue   { --pi-y0: var(--pi-blue);   --pi-y1: var(--pi-blue-2);   }
.postit-mint   { --pi-y0: var(--pi-mint);   --pi-y1: var(--pi-mint-2);   }
.postit-peach  { --pi-y0: var(--pi-peach);  --pi-y1: var(--pi-peach-2);  }
.postit-lilac  { --pi-y0: var(--pi-lilac);  --pi-y1: var(--pi-lilac-2);  }

/* Slight rotations — hero items only. Lists keep rotation off so they
   don't feel chaotic when there are 10+ items. */
.postit-r-l1 { transform: rotate(-1.2deg); }
.postit-r-l2 { transform: rotate(-2deg);   }
.postit-r-r1 { transform: rotate(1deg);    }
.postit-r-r2 { transform: rotate(1.8deg);  }
.postit-r-0  { transform: rotate(0.3deg);  }

/* Washi tape — diagonal stripes, tinted. Position with washi-tl/tr. */
.washi {
  position: absolute;
  top: -8px;
  left: 50%;
  transform: translateX(-50%) rotate(-2deg);
  width: 64px;
  height: 18px;
  background: repeating-linear-gradient(
    -45deg,
    rgba(255,255,255,0.5) 0 4px,
    rgba(255,255,255,0.25) 4px 8px
  ), oklch(0.78 0.10 200 / 0.85);
  border-left: 1px dashed rgba(255,255,255,0.4);
  border-right: 1px dashed rgba(255,255,255,0.4);
  box-shadow: 0 1px 2px rgba(0,0,0,0.12);
  z-index: 2;
  pointer-events: none;
}
.washi-pink { background: repeating-linear-gradient(-45deg, rgba(255,255,255,0.5) 0 4px, rgba(255,255,255,0.25) 4px 8px), oklch(0.78 0.14 15 / 0.85); }
.washi-mint { background: repeating-linear-gradient(-45deg, rgba(255,255,255,0.5) 0 4px, rgba(255,255,255,0.25) 4px 8px), oklch(0.80 0.12 155 / 0.85); }
.washi-tl { left: 14px;  transform: translateX(0) rotate(-6deg); top: -7px; }
.washi-tr { left: auto; right: 14px; transform: translateX(0) rotate(8deg);  top: -7px; }

/* Pushpin — circular thumbtack. Use as a small decorative ::before or
   as its own element. */
.pushpin {
  position: absolute;
  top: -4px;
  left: 50%;
  transform: translateX(-50%);
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, oklch(0.85 0.18 25) 0%, oklch(0.55 0.20 25) 70%, oklch(0.35 0.16 25) 100%);
  box-shadow: 0 1px 1px rgba(0,0,0,0.4), inset 1px 1px 1px rgba(255,255,255,0.35);
  z-index: 2;
  pointer-events: none;
}
.pushpin-blue  { background: radial-gradient(circle at 35% 35%, oklch(0.78 0.16 230) 0%, oklch(0.48 0.18 235) 70%, oklch(0.30 0.14 240) 100%); }
.pushpin-green { background: radial-gradient(circle at 35% 35%, oklch(0.82 0.18 145) 0%, oklch(0.52 0.18 150) 70%, oklch(0.32 0.14 155) 100%); }

/* Handwritten accent — for "from Sarah" style margin notes */
.hand   { font-family: var(--font-script); font-weight: 600; letter-spacing: 0.005em; }
.hand-p { font-family: var(--font-hand); }

/* ── Hero card treatments ─────────────────────────────────────────── */

/* Today screen "right now" highlight — big yellow post-it with washi tape.
   This is the screen's most-visible card, so it gets the biggest treatment. */
.today-current {
  position: relative;
  background:
    radial-gradient(1px 1px at 20% 30%, rgba(0,0,0,0.025) 1px, transparent 0),
    radial-gradient(1px 1px at 70% 60%, rgba(0,0,0,0.02) 1px, transparent 0),
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  background-size: 80px 80px, 100px 100px, auto;
  border: none;
  border-radius: 2px;
  box-shadow: var(--sh-postit);
  transform: rotate(-0.6deg);
  margin: 8px 4px 22px;
}
.today-current::before {
  /* washi tape across the top */
  content: "";
  position: absolute;
  top: -7px;
  left: 14px;
  width: 64px;
  height: 18px;
  transform: rotate(-6deg);
  background: repeating-linear-gradient(
    -45deg,
    rgba(255,255,255,0.5) 0 4px,
    rgba(255,255,255,0.25) 4px 8px
  ), oklch(0.78 0.10 200 / 0.85);
  border-left: 1px dashed rgba(255,255,255,0.4);
  border-right: 1px dashed rgba(255,255,255,0.4);
  box-shadow: 0 1px 2px rgba(0,0,0,0.12);
  z-index: 2;
  pointer-events: none;
}
.today-current::after {
  /* curled corner */
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  width: 18px;
  height: 18px;
  background: linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.10) 100%);
  border-radius: 0 0 2px 0;
  pointer-events: none;
}
.today-current .now-label {
  font-family: var(--font-hand);
  font-size: 13px;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
  color: oklch(0.30 0.10 70);
}
.today-current .now-title {
  color: oklch(0.18 0.04 60);
}
.today-current .now-meta {
  color: oklch(0.32 0.04 65);
}

/* Decision card — the big focus item on the Decisions tab. Yellow post-it
   with washi tape. Only one or two visible at a time, so rotation works. */
.decision-card {
  position: relative;
  background:
    radial-gradient(1px 1px at 20% 30%, rgba(0,0,0,0.025) 1px, transparent 0),
    radial-gradient(1px 1px at 70% 60%, rgba(0,0,0,0.02) 1px, transparent 0),
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  background-size: 80px 80px, 100px 100px, auto;
  border: none;
  border-radius: 2px;
  box-shadow: var(--sh-postit);
  transform: rotate(-0.5deg);
}
.decision-card::before {
  content: "";
  position: absolute;
  top: -7px;
  right: 18px;
  width: 64px;
  height: 18px;
  transform: rotate(7deg);
  background: repeating-linear-gradient(
    -45deg,
    rgba(255,255,255,0.5) 0 4px,
    rgba(255,255,255,0.25) 4px 8px
  ), oklch(0.78 0.14 15 / 0.85);
  border-left: 1px dashed rgba(255,255,255,0.4);
  border-right: 1px dashed rgba(255,255,255,0.4);
  box-shadow: 0 1px 2px rgba(0,0,0,0.12);
  z-index: 2;
  pointer-events: none;
}
.decision-card:nth-child(2n) {
  background:
    radial-gradient(1px 1px at 20% 30%, rgba(0,0,0,0.025) 1px, transparent 0),
    radial-gradient(1px 1px at 70% 60%, rgba(0,0,0,0.02) 1px, transparent 0),
    linear-gradient(135deg, var(--pi-mint) 0%, var(--pi-mint-2) 100%);
  background-size: 80px 80px, 100px 100px, auto;
  transform: rotate(0.6deg);
}
.decision-card:nth-child(3n) {
  background:
    radial-gradient(1px 1px at 20% 30%, rgba(0,0,0,0.025) 1px, transparent 0),
    radial-gradient(1px 1px at 70% 60%, rgba(0,0,0,0.02) 1px, transparent 0),
    linear-gradient(135deg, var(--pi-peach) 0%, var(--pi-peach-2) 100%);
  background-size: 80px 80px, 100px 100px, auto;
  transform: rotate(-0.9deg);
}

/* ── List-item color cycling (no rotation — keeps long lists calm) ──── */

/* Unscheduled tasks on Today — small color-cycled post-its */
.unsched-item {
  background:
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  border: none;
  border-radius: 2px;
  box-shadow: var(--sh-postit);
}
.unsched-item:nth-child(6n+2) {
  background: linear-gradient(135deg, var(--pi-blue) 0%, var(--pi-blue-2) 100%);
}
.unsched-item:nth-child(6n+3) {
  background: linear-gradient(135deg, var(--pi-mint) 0%, var(--pi-mint-2) 100%);
}
.unsched-item:nth-child(6n+4) {
  background: linear-gradient(135deg, var(--pi-peach) 0%, var(--pi-peach-2) 100%);
}
.unsched-item:nth-child(6n+5) {
  background: linear-gradient(135deg, var(--pi-pink) 0%, var(--pi-pink-2) 100%);
}
.unsched-item:nth-child(6n) {
  background: linear-gradient(135deg, var(--pi-lilac) 0%, var(--pi-lilac-2) 100%);
}

/* Review items — color cycle so the daily reflection looks like notes
   pinned to a board, not a generic list. */
.review-item {
  background:
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  box-shadow: var(--sh-postit);
  border: none;
  border-radius: 2px;
}
.review-item:nth-child(5n+2) { background: linear-gradient(135deg, var(--pi-mint)   0%, var(--pi-mint-2)   100%); }
.review-item:nth-child(5n+3) { background: linear-gradient(135deg, var(--pi-blue)   0%, var(--pi-blue-2)   100%); }
.review-item:nth-child(5n+4) { background: linear-gradient(135deg, var(--pi-peach)  0%, var(--pi-peach-2)  100%); }
.review-item:nth-child(5n)   { background: linear-gradient(135deg, var(--pi-lilac)  0%, var(--pi-lilac-2)  100%); }

/* Tab bar amber pin-dot above the active tab — small "pinned" marker. */
.tab-btn { position: relative; }
.tab-btn.active::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: var(--tabbar-pin);
}

/* ======================================================================
   Round-2 surfaces (May 2026)

   Extends the post-it skin to lower-traffic surfaces that the first pass
   left vanilla: login form, tasks list groups, settings cards, schedule
   import preview rows, family-view event blocks (subtle), and modal
   sheets. Same rules as before — rotation only on hero items, color
   cycling for list-y stuff, subtle warmth elsewhere.
   ====================================================================== */

/* ── Login screen ────────────────────────────────────────────────── */

/* The form area becomes the post-it. The logo + tagline stay above on
   the whiteboard so the page reads as "sticky note pinned to the board." */
.login-form {
  position: relative;
  padding: 22px 18px 20px;
  background:
    radial-gradient(1px 1px at 25% 30%, rgba(0,0,0,0.025) 1px, transparent 0),
    radial-gradient(1px 1px at 70% 60%, rgba(0,0,0,0.02) 1px, transparent 0),
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  background-size: 80px 80px, 100px 100px, auto;
  border-radius: 2px;
  box-shadow: var(--sh-postit);
  transform: rotate(-0.4deg);
  margin-top: 4px;
}
.login-form::before {
  /* washi tape across the top */
  content: "";
  position: absolute;
  top: -9px;
  left: 50%;
  transform: translateX(-50%) rotate(-2deg);
  width: 90px;
  height: 18px;
  background: repeating-linear-gradient(
    -45deg,
    rgba(255,255,255,0.5) 0 4px,
    rgba(255,255,255,0.25) 4px 8px
  ), oklch(0.78 0.10 200 / 0.85);
  border-left: 1px dashed rgba(255,255,255,0.4);
  border-right: 1px dashed rgba(255,255,255,0.4);
  box-shadow: 0 1px 2px rgba(0,0,0,0.12);
  z-index: 2;
  pointer-events: none;
}
.login-form::after {
  /* curled corner */
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  width: 18px;
  height: 18px;
  background: linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.10) 100%);
  border-radius: 0 0 2px 0;
  pointer-events: none;
}
.login-form input {
  background: rgba(255, 255, 255, 0.85);
  border-color: rgba(0, 0, 0, 0.08);
}
.login-form input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.6);
  background: white;
}
.login-form button {
  background: var(--accent-deep);
  box-shadow: 0 2px 6px rgba(40, 80, 140, 0.18), 0 1px 0 rgba(255,255,255,0.2) inset;
}
.login-logo h1 {
  font-family: var(--font-hand);
  font-weight: 500;
  font-size: 2.2rem;
  letter-spacing: 0;
}
.logo-icon {
  background:
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  color: var(--accent-deep);
  box-shadow: var(--sh-postit);
  border-radius: 4px;
  font-family: var(--font-hand);
  transform: rotate(-3deg);
}

/* ── Tasks list — each row is its own post-it, color-cycled ─────── */

/* Container becomes transparent so rows float on the whiteboard with
   space between them, like the Decisions screen. */
.tasks-list {
  background: transparent;
  border: none;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow: visible;
}
.tasks-group h4 {
  font-family: var(--font-hand);
  font-size: 17px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-muted);
}

/* Each task-row becomes its own post-it. Six-color cycle so a long list
   reads like notes pinned in a row, not a striped grid. */
.task-row {
  background:
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  border-bottom: none !important;
  border-radius: 2px;
  box-shadow: var(--sh-postit);
  position: relative;
}
.task-row:nth-child(6n+2) {
  background: linear-gradient(135deg, var(--pi-blue)  0%, var(--pi-blue-2)  100%);
}
.task-row:nth-child(6n+3) {
  background: linear-gradient(135deg, var(--pi-mint)  0%, var(--pi-mint-2)  100%);
}
.task-row:nth-child(6n+4) {
  background: linear-gradient(135deg, var(--pi-peach) 0%, var(--pi-peach-2) 100%);
}
.task-row:nth-child(6n+5) {
  background: linear-gradient(135deg, var(--pi-pink)  0%, var(--pi-pink-2)  100%);
}
.task-row:nth-child(6n) {
  background: linear-gradient(135deg, var(--pi-lilac) 0%, var(--pi-lilac-2) 100%);
}

/* ── Schedule import preview — color-cycled rows ─────────────────── */

.schedule-row {
  background:
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  border: none !important;
  border-radius: 2px;
  box-shadow: var(--sh-postit);
  margin-bottom: 8px;
}
.schedule-row:nth-child(6n+2) { background: linear-gradient(135deg, var(--pi-blue)  0%, var(--pi-blue-2)  100%); }
.schedule-row:nth-child(6n+3) { background: linear-gradient(135deg, var(--pi-mint)  0%, var(--pi-mint-2)  100%); }
.schedule-row:nth-child(6n+4) { background: linear-gradient(135deg, var(--pi-peach) 0%, var(--pi-peach-2) 100%); }
.schedule-row:nth-child(6n+5) { background: linear-gradient(135deg, var(--pi-pink)  0%, var(--pi-pink-2)  100%); }
.schedule-row:nth-child(6n)   { background: linear-gradient(135deg, var(--pi-lilac) 0%, var(--pi-lilac-2) 100%); }

/* ── Settings — each row is its own post-it, color-cycled ───────── */

/* The card-shaped container becomes transparent so its row children
   read as a stack of pinned notes, not one big sheet of paper. */
.settings-card {
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  overflow: visible;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 0;
}
.settings-section h3 {
  font-family: var(--font-hand);
  font-size: 16px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-muted);
}

/* Every row-shaped child of a settings-card gets the post-it look.
   `.settings-row`, `.account-row`, `.household-member-wrap` (which
   wraps a member-row + optional editor) all hit the same rule so the
   look is consistent across sections. */
.settings-card .settings-row,
.settings-card .account-row,
.settings-card .household-member-wrap,
.settings-card .household-member-row,
.settings-card .pm-mode-block {
  background:
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  border: none;
  border-radius: 2px;
  box-shadow: var(--sh-postit);
}

/* Color-cycle the rows within a card. Keeps adjacent rows visually
   distinct without rotation. */
.settings-card > *:nth-child(6n+2),
.settings-card .pm-mode-block:nth-of-type(6n+2) {
  background: linear-gradient(135deg, var(--pi-mint)  0%, var(--pi-mint-2)  100%);
}
.settings-card > *:nth-child(6n+3),
.settings-card .pm-mode-block:nth-of-type(6n+3) {
  background: linear-gradient(135deg, var(--pi-blue)  0%, var(--pi-blue-2)  100%);
}
.settings-card > *:nth-child(6n+4) {
  background: linear-gradient(135deg, var(--pi-peach) 0%, var(--pi-peach-2) 100%);
}
.settings-card > *:nth-child(6n+5) {
  background: linear-gradient(135deg, var(--pi-pink)  0%, var(--pi-pink-2)  100%);
}
.settings-card > *:nth-child(6n) {
  background: linear-gradient(135deg, var(--pi-lilac) 0%, var(--pi-lilac-2) 100%);
}

/* household-member-row sits inside a wrapper; the wrapper gets the
   post-it surface, the inner row stays transparent so it inherits. */
.settings-card .household-member-wrap .household-member-row {
  background: transparent !important;
  box-shadow: none;
}

/* ── Family-view event blocks — softer paper feel, keep owner colors ─ */

.family-block {
  /* Owner-color cues are still set inline by app.js (background/border).
     We just soften the existing crisp shadow + border-radius so the
     blocks feel like little pinned notes rather than UI tiles. Inline
     styles override, so no color hijack. */
  border-radius: 2px !important;
  box-shadow:
    0 1px 1px rgba(80,60,30,0.10),
    1.5px 2px 3px rgba(80,60,30,0.08);
}

/* ── Modal sheets — warm paper on the whiteboard ─────────────────── */

.modal-card {
  background:
    radial-gradient(1px 1px at 25% 30%, rgba(0,0,0,0.018) 1px, transparent 0),
    linear-gradient(135deg, oklch(0.99 0.01 95) 0%, oklch(0.96 0.03 92) 100%);
  background-size: 80px 80px, auto;
  border-radius: 4px;
  box-shadow: var(--sh-postit-lift);
  border: none;
}
.modal-card h3 {
  font-family: var(--font-hand);
  font-size: 22px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text);
}

/* Family-modal — same treatment for the per-column hour-range modal. */
.family-modal-card {
  background:
    linear-gradient(135deg, oklch(0.99 0.01 95) 0%, oklch(0.96 0.03 92) 100%);
  border-radius: 4px;
  box-shadow: var(--sh-postit-lift);
}
.family-modal-title {
  font-family: var(--font-hand);
  font-size: 18px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
}

/* ======================================================================
   PM Layer v1 — Today brief card + Settings mode pickers + auto chip.
   ====================================================================== */

/* ── Today brief — yellow post-it with washi tape, pinned at the top
   of the Today screen. Same hero treatment as today-current. */
.today-brief {
  position: relative;
  margin: 12px 4px 22px;
  padding: 22px 18px 16px;
  background:
    radial-gradient(1px 1px at 25% 30%, rgba(0,0,0,0.025) 1px, transparent 0),
    radial-gradient(1px 1px at 70% 60%, rgba(0,0,0,0.02) 1px, transparent 0),
    linear-gradient(135deg, var(--pi-yellow) 0%, var(--pi-yellow-2) 100%);
  background-size: 80px 80px, 100px 100px, auto;
  border-radius: 2px;
  box-shadow: var(--sh-postit);
  transform: rotate(-0.4deg);
}
.today-brief.hidden { display: none; }
.today-brief::before {
  content: "";
  position: absolute;
  top: -8px;
  left: 18px;
  width: 64px;
  height: 18px;
  transform: rotate(-6deg);
  background: repeating-linear-gradient(
    -45deg,
    rgba(255,255,255,0.5) 0 4px,
    rgba(255,255,255,0.25) 4px 8px
  ), oklch(0.78 0.10 200 / 0.85);
  border-left: 1px dashed rgba(255,255,255,0.4);
  border-right: 1px dashed rgba(255,255,255,0.4);
  box-shadow: 0 1px 2px rgba(0,0,0,0.12);
  z-index: 2;
  pointer-events: none;
}
.today-brief::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  width: 18px;
  height: 18px;
  background: linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.10) 100%);
  border-radius: 0 0 2px 0;
  pointer-events: none;
}
.brief-postit { position: relative; }
.brief-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
}
.brief-eyebrow {
  font-family: var(--font-hand);
  font-size: 14px;
  color: var(--accent-deep);
}
.brief-close {
  appearance: none; border: 0; background: transparent;
  font-size: 22px; line-height: 1; padding: 4px 8px; cursor: pointer;
  color: oklch(0.32 0.04 70);
}
.brief-head-actions { display: flex; align-items: center; gap: 2px; }
.brief-refresh {
  appearance: none; border: 0; background: transparent;
  display: inline-flex; align-items: center;
  padding: 4px 6px; cursor: pointer;
  color: oklch(0.32 0.04 70);
}
.brief-refresh svg { display: block; }
.brief-refresh:disabled { opacity: 0.5; cursor: default; }
.brief-refresh.spinning svg { animation: brief-refresh-spin 0.9s linear infinite; }
@keyframes brief-refresh-spin { to { transform: rotate(360deg); } }
.brief-note {
  font-family: var(--font-serif);
  font-size: 15px;
  line-height: 1.5;
  color: oklch(0.20 0.04 60);
  margin-bottom: 12px;
}
.brief-title {
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 650;
  letter-spacing: -0.015em;
  color: oklch(0.18 0.04 60);
  margin-bottom: 2px;
}
.brief-sub {
  font-size: 13px;
  color: oklch(0.34 0.04 65);
  margin-bottom: 12px;
}
.brief-items {
  display: flex; flex-direction: column;
  border-top: 1px dashed rgba(0,0,0,0.10);
}
.brief-item {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 0;
  border-bottom: 1px dashed rgba(0,0,0,0.10);
  cursor: pointer;
}
.brief-item:last-child { border-bottom: none; }
.brief-dot {
  width: 10px; height: 10px; border-radius: 50%;
  margin-top: 5px; flex-shrink: 0;
  background: var(--accent);
}
.brief-dot-pending_trade_incoming,
.brief-dot-pending_trade_outgoing { background: var(--accent); }
.brief-dot-defaulted_debt,
.brief-dot-pinch_point { background: var(--slip); }
.brief-dot-silent_voice,
.brief-dot-stuck_decision { background: oklch(0.68 0.14 70); }
.brief-dot-collected_debt { background: var(--accent-deep); }
.brief-dot-assignments_today,
.brief-dot-all_clear { background: var(--toach); }
.brief-item-main { flex: 1; min-width: 0; }
.brief-item-title {
  font-weight: 600;
  font-size: 14px;
  color: oklch(0.18 0.04 60);
}
.brief-item-body {
  font-size: 12.5px;
  color: oklch(0.34 0.04 65);
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── "Today across the family" recap inside the morning brief ── */
.brief-family-recap {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed rgba(0,0,0,0.18);
}
.brief-family-recap-title {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: oklch(0.34 0.04 65);
  margin-bottom: 6px;
}
.brief-family-recap-list {
  list-style: disc;
  padding-left: 20px;
  margin: 0;
}
.brief-family-recap-list li {
  font-size: 13.5px;
  color: oklch(0.20 0.04 60);
  line-height: 1.45;
  margin: 2px 0;
}

/* ── PM mode pickers in Settings ── */
.pm-mode-block {
  padding: 12px 14px;
  border-bottom: 1px dashed rgba(0,0,0,0.10);
}
.pm-mode-block:last-child { border-bottom: none; }
.pm-mode-options {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 8px;
}
.pm-mode-opt {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 8px 10px;
  background: rgba(255,255,255,0.5);
  border: 1px dashed rgba(0,0,0,0.10);
  border-radius: 6px;
  cursor: pointer;
}
.pm-mode-opt:has(input:checked) {
  background: rgba(255,255,255,0.85);
  border-style: solid;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-softer);
}
.pm-mode-opt input { margin-top: 3px; flex-shrink: 0; }
.pm-mode-opt span { font-size: 13px; line-height: 1.4; color: var(--text); }
.pm-mode-opt span strong { color: var(--text); }

/* ── auto · why? chip on tasks ── */
.task-auto-chip {
  display: inline-flex;
  align-items: center;
  font-family: var(--mono, ui-monospace, "SF Mono", Menlo, monospace);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 5px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  cursor: pointer;
}

/* PM activity feed — admin-only modal that lists every PM-driven action. */
.pm-activity-card {
  max-width: 540px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  padding: 18px 18px 12px;
}
.pm-activity-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.pm-activity-head h3 { margin: 0; }
.pm-activity-head .btn-link {
  font-size: 1.5rem;
  line-height: 1;
  padding: 0 6px;
}
.pm-activity-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0 10px;
  font-size: 0.9rem;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border, rgba(0,0,0,0.08));
}
.pm-activity-controls select {
  margin-left: 4px;
  padding: 4px 6px;
  font-size: 0.9rem;
}
.pm-activity-list {
  overflow-y: auto;
  flex: 1 1 auto;
  margin-top: 6px;
}
.pm-activity-row {
  padding: 10px 4px;
  border-bottom: 1px solid var(--border, rgba(0,0,0,0.06));
}
.pm-activity-row:last-child { border-bottom: none; }
.pm-activity-title {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text);
}
.pm-activity-sub {
  margin-top: 2px;
  color: var(--text-muted);
  font-size: 0.88rem;
  line-height: 1.4;
}
.pm-activity-meta {
  margin-top: 4px;
  font-size: 0.78rem;
  color: var(--text-muted);
  opacity: 0.75;
}
.pm-activity-noadmin {
  font-size: 0.85rem;
  color: var(--text-muted);
  font-style: italic;
  white-space: nowrap;
}
.pm-activity-breakdown {
  margin: 6px 0 0;
  padding-left: 20px;
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.5;
}
.pm-activity-breakdown li { margin-bottom: 2px; }
.pm-activity-breakdown em {
  font-style: normal;
  color: var(--accent-deep, var(--text));
}
.pm-activity-checklog {
  margin: 8px 0 0;
  padding-left: 18px;
  font-size: 0.85rem;
  line-height: 1.45;
}
.pm-activity-checklog li {
  margin-bottom: 6px;
  color: var(--text);
}
.pm-activity-checklog li.pm-check-quiet {
  color: var(--text-muted);
  opacity: 0.85;
}
.pm-activity-checklog li.pm-check-fired strong {
  color: var(--accent-deep, var(--text));
}
.pm-check-note {
  font-size: 0.78rem;
  color: var(--text-muted);
  margin-top: 1px;
}
.pm-check-mode {
  font-size: 0.75rem;
  color: var(--text-muted);
  font-style: italic;
  margin-top: 1px;
}

/* Event meeting link — replaces a raw Zoom/Meet/Teams URL inside an
   event's location with a short tappable pill. Used by `formatLocation()`
   in app.js. Sized to sit inline with the surrounding meta text. */
.event-link {
  display: inline-block;
  background: var(--accent-softer);
  color: var(--accent-deep);
  padding: 1px 9px;
  border-radius: 999px;
  font-size: 0.95em;
  font-weight: 600;
  text-decoration: none;
  /* Slight vertical nudge so the pill aligns with the time text it
     sits next to in .now-meta / .timeline-loc. */
  vertical-align: baseline;
  /* Defensive — should never wrap (label is always short) but if a
     future "generic hostname" fallback returns something long, keep
     the pill from blowing the row. */
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.event-link:active { background: var(--accent-soft); }

/* ============================================================
   Mini-game: Squishy Shop
   ============================================================
   Opt-in reward modal shown after a task is completed. Visuals
   lean cartoony so it feels like a kid game, not a system dialog.
   ------------------------------------------------------------ */

/* iOS-style slide toggle in the Settings card */
.minigame-toggle {
  position: relative;
  width: 50px;
  height: 30px;
  flex-shrink: 0;
  cursor: pointer;
}
.minigame-toggle input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.minigame-slider {
  position: absolute;
  inset: 0;
  background: oklch(0.86 0.01 240);
  border-radius: 999px;
  transition: background 0.18s ease;
}
.minigame-slider::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 24px;
  height: 24px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
  transition: transform 0.18s ease;
}
.minigame-toggle input:checked + .minigame-slider {
  background: var(--accent);
}
.minigame-toggle input:checked + .minigame-slider::after {
  transform: translateX(20px);
}

.minigame-stats {
  display: flex;
  gap: 12px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid oklch(0.92 0.005 240);
}
.minigame-stats.hidden { display: none; }
.minigame-stat {
  flex: 1;
  text-align: center;
  background: var(--accent-softer);
  border-radius: 10px;
  padding: 8px 4px;
}
.minigame-stat-label {
  font-size: 0.72rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.minigame-stat-value {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--accent-deep);
  margin-top: 2px;
}

/* --- Game modal --- */
.minigame-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 31, 42, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: 9000;
  animation: minigame-fade 0.18s ease-out;
}
.minigame-overlay.hidden { display: none; }
@keyframes minigame-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.minigame-card {
  width: 100%;
  max-width: 420px;
  background: linear-gradient(170deg, #FFF7E8 0%, #FFE3F1 100%);
  border-radius: 20px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.3);
  padding: 16px 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-family: inherit;
  animation: minigame-pop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes minigame-pop {
  from { transform: scale(0.85); opacity: 0; }
  to   { transform: scale(1);    opacity: 1; }
}

.minigame-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.minigame-head-left, .minigame-head-right {
  display: flex;
  align-items: center;
  gap: 6px;
}
.minigame-pill {
  background: rgba(255,255,255,0.85);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}
.minigame-pill-cash { color: oklch(0.45 0.15 145); }
.minigame-pill-customer {
  background: rgba(255,255,255,0.6);
  font-weight: 600;
  font-size: 0.72rem;
}
.minigame-close {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,0.7);
  font-size: 1.4rem;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.minigame-close:hover { background: #fff; color: var(--text); }

.minigame-title {
  text-align: center;
  margin: 0;
  font-size: 1.4rem;
  font-weight: 800;
  color: oklch(0.40 0.15 350);
  letter-spacing: 0.01em;
}

.minigame-customer-area {
  position: relative;
  height: 160px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: 4px;
}
.minigame-customer {
  width: 110px;
  height: 140px;
  position: relative;
  transition: transform 0.4s ease, opacity 0.4s ease;
}
.minigame-customer.minigame-enter {
  animation: customer-walk-in 0.45s ease-out;
}
.minigame-customer.minigame-leave-happy {
  animation: customer-leave-happy 0.6s ease-in forwards;
}
.minigame-customer.minigame-leave-sad {
  animation: customer-leave-sad 0.7s ease-in forwards;
}
@keyframes customer-walk-in {
  from { transform: translateX(120px); opacity: 0; }
  to   { transform: translateX(0);     opacity: 1; }
}
@keyframes customer-leave-happy {
  0%   { transform: translateX(0)    translateY(0); }
  20%  { transform: translateX(0)    translateY(-8px); }
  100% { transform: translateX(140px) translateY(0); opacity: 0; }
}
@keyframes customer-leave-sad {
  0%   { transform: translateX(0)     rotate(0); }
  100% { transform: translateX(-140px) rotate(-4deg); opacity: 0; }
}

.minigame-bubble {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  background: #fff;
  border-radius: 16px;
  padding: 10px 14px;
  font-size: 0.92rem;
  color: var(--text);
  max-width: 280px;
  text-align: center;
  box-shadow: 0 4px 12px rgba(0,0,0,0.12);
  line-height: 1.3;
}
.minigame-bubble::after {
  content: "";
  position: absolute;
  bottom: -8px;
  left: 50%;
  transform: translateX(-50%);
  border: 8px solid transparent;
  border-top-color: #fff;
  border-bottom: 0;
}
.minigame-bubble.minigame-bubble-sad {
  background: oklch(0.95 0.04 25);
  color: oklch(0.40 0.15 25);
}
.minigame-bubble.minigame-bubble-sad::after {
  border-top-color: oklch(0.95 0.04 25);
}

/* --- Cart with squishies --- */
.minigame-cart-wrap {
  position: relative;
  margin-top: 4px;
}
.minigame-cart {
  display: flex;
  justify-content: center;
  gap: 16px;
  padding: 14px 14px 18px;
  background: linear-gradient(180deg, #C97B4A 0%, #A55F30 100%);
  border-radius: 14px 14px 6px 6px;
  border: 3px solid #7A4520;
  border-bottom: none;
  position: relative;
}
.minigame-cart::before {
  content: "";
  position: absolute;
  inset: 8px 12px 8px;
  border-radius: 8px;
  background: repeating-linear-gradient(
    90deg,
    transparent 0,
    transparent 28px,
    rgba(0,0,0,0.10) 28px,
    rgba(0,0,0,0.10) 29px
  );
  pointer-events: none;
}
.minigame-cart-base {
  height: 14px;
  background: #5A3318;
  border-radius: 0 0 14px 14px;
  margin: 0 12px;
  position: relative;
}
.minigame-cart-base::before, .minigame-cart-base::after {
  content: "";
  position: absolute;
  bottom: -10px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #2B1810;
  box-shadow: inset 0 0 0 4px #6B4226;
}
.minigame-cart-base::before { left: 14px; }
.minigame-cart-base::after  { right: 14px; }

.minigame-squishy-btn {
  position: relative;
  z-index: 2;
  width: 92px;
  height: 92px;
  background: rgba(255,255,255,0.9);
  border: 3px solid #fff;
  border-radius: 14px;
  padding: 6px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  box-shadow: 0 4px 0 rgba(0,0,0,0.18);
}
.minigame-squishy-btn:hover:not(:disabled) {
  transform: translateY(-4px);
  box-shadow: 0 8px 0 rgba(0,0,0,0.18);
}
.minigame-squishy-btn:active:not(:disabled) {
  transform: translateY(2px);
  box-shadow: 0 1px 0 rgba(0,0,0,0.18);
}
.minigame-squishy-btn:disabled {
  cursor: default;
  opacity: 0.6;
}
.minigame-squishy-btn.minigame-correct {
  animation: squishy-correct 0.5s ease;
  box-shadow: 0 0 0 4px oklch(0.75 0.18 145), 0 4px 0 rgba(0,0,0,0.18);
}
.minigame-squishy-btn.minigame-wrong {
  animation: squishy-wrong 0.45s ease;
  box-shadow: 0 0 0 4px oklch(0.65 0.18 25), 0 4px 0 rgba(0,0,0,0.18);
}
@keyframes squishy-correct {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.15); }
}
@keyframes squishy-wrong {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}
.minigame-squishy-btn svg {
  width: 100%;
  height: 100%;
  display: block;
}

.minigame-feedback {
  text-align: center;
  font-size: 0.95rem;
  font-weight: 700;
  min-height: 1.4em;
  color: var(--text-muted);
  transition: color 0.2s;
}
.minigame-feedback.minigame-feedback-good { color: oklch(0.45 0.15 145); }
.minigame-feedback.minigame-feedback-bad  { color: oklch(0.50 0.18 25); }

.minigame-summary {
  text-align: center;
  background: rgba(255,255,255,0.85);
  border-radius: 14px;
  padding: 14px;
}
.minigame-summary.hidden { display: none; }
.minigame-summary-title {
  font-size: 1.1rem;
  font-weight: 800;
  color: var(--text);
  margin-bottom: 4px;
}
.minigame-summary-line { font-size: 0.95rem; color: var(--text); }
.minigame-summary-sub  { font-size: 0.85rem; color: var(--text-muted); margin-top: 4px; }


/* ======================================================================
   Web gate — Toach is app-only; browsers get this instead of the app.
   Shown by _showWebGateIfNeeded() in app.js.
   ====================================================================== */
body.web-gated > :not(#web-gate) { display: none !important; }

.web-gate {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  padding: 24px;
}
.web-gate.hidden { display: none !important; }

.web-gate-card {
  max-width: 380px;
  text-align: center;
}

.web-gate-card h1 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 2rem;
  letter-spacing: -0.02em;
  color: var(--text);
}

.web-gate-lead {
  font-family: var(--font-serif);
  color: var(--text);
  margin-top: 12px;
  font-size: 1.2rem;
  line-height: 1.35;
}

.web-gate-detail {
  color: var(--text-muted);
  margin-top: 10px;
  font-size: 0.95rem;
  line-height: 1.5;
}


/* Lightweight transient toast (e.g. "Pasted!" after a clipboard image).
   z-index sits above the schedule-import modal card (1000) and backdrop. */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 88px);
  transform: translateX(-50%) translateY(8px);
  background: rgba(15, 31, 42, 0.92);
  color: #fff;
  padding: 9px 16px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  z-index: 1200;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
  box-shadow: 0 6px 20px rgba(15, 31, 42, 0.28);
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}


/* A pasted/uploaded photo shown as the user's own chat bubble. */
.msg-bubble-photo {
  padding: 4px;
}
.chat-photo-msg {
  display: block;
  max-width: min(62vw, 220px);
  max-height: 260px;
  width: auto;
  height: auto;
  border-radius: 10px;
  object-fit: cover;
}
.chat-photo-caption {
  margin: 6px 4px 2px;
  white-space: pre-wrap;
  word-break: break-word;
}

/* ======================================================================
   Coins & prizes — header balance pill, recurring-row coin badge, and
   the redeem/prize-management modal.
   ====================================================================== */

/* The coin glyph — a solid gold circle drawn in CSS (the 🪙 emoji renders
   in its own fixed colors and can't be tinted, so it's not used anywhere).
   Sized in em so it scales with the surrounding text. */
.coin-icon {
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 30%,
              oklch(0.78 0.13 85), var(--coin-gold) 72%);
  box-shadow: inset 0 0 0 1px oklch(0.50 0.12 78);
  vertical-align: -0.06em;
  flex-shrink: 0;
}

.coin-pill {
  gap: 4px;
  font-size: 14px;
  font-weight: 600;
  color: var(--coin-gold);
}

.coin-pill:hover { color: var(--coin-gold); }

.coin-balance-count {
  font-variant-numeric: tabular-nums;
  min-width: 14px;
  text-align: left;
}

.task-coin-badge {
  font-size: 11px;
  font-weight: 600;
  color: var(--coin-gold);
  white-space: nowrap;
}

/* Inline coin amount anywhere in the app (redemption rows, etc.). */
.coin-amount {
  color: var(--coin-gold);
  font-weight: 600;
}

.coin-modal-card {
  max-width: 420px;
  width: calc(100% - 32px);
}

.coin-modal-body {
  padding: 4px 16px 16px;
  overflow-y: auto;
  max-height: 70vh;
}

.coin-balance-hero {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  padding: 10px 0 16px;
  font-size: 34px;
  font-weight: 700;
  color: var(--coin-gold);
}

.coin-balance-hero-icon {
  width: 26px;
  height: 26px;
  align-self: center;
}

.coin-balance-hero-label {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
}

.coin-section-title {
  margin: 14px 0 8px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-subtle);
}

/* ── Chore trades card (Tasks tab) ─────────────────────────────── */
.trades-card {
  margin: 0 16px 12px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: 14px;
}

.trade-section-title {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-subtle);
  margin: 4px 0 8px;
}
.trade-section-title:not(:first-child) { margin-top: 14px; }

.trade-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--hair);
}
.trade-row:last-child { border-bottom: none; }

.trade-main { flex: 1; min-width: 0; }

.trade-line {
  font-size: 14px;
  line-height: 1.4;
  color: var(--text);
  overflow-wrap: anywhere;
}
.trade-sub { margin-top: 3px; }
.trade-note {
  margin-top: 4px;
  font-size: 13px;
  font-style: italic;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.trade-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 0 0 auto;
}

.trade-fair {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  vertical-align: middle;
}
.trade-fair.fair-even   { background: rgba(52,211,153,0.18); color: #0f7a52; }
.trade-fair.fair-slight { background: rgba(251,191,36,0.20); color: #92600a; }
.trade-fair.fair-uneven { background: rgba(248,113,113,0.18); color: #b3271e; }

.trade-status { font-size: 13px; font-weight: 500; }
.trade-status-proposed   { color: var(--text-muted); }
.trade-status-accepted   { color: var(--accent-deep); }
.trade-status-collecting { color: #b3271e; }

@media (prefers-color-scheme: dark) {
  .trade-fair.fair-even   { color: #6ee7b7; }
  .trade-fair.fair-slight { color: #fcd34d; }
  .trade-fair.fair-uneven { color: #fca5a5; }
}

/* Prize rows are two lines: the full name (wrapping) on top, then a
   cost + actions line. A single flex row starved long names — the shared
   .btn-primary carries flex:1 + min-width:140px, so "Redeem" swallowed
   the row and names truncated to a couple of characters. */
.coin-prize-row {
  padding: 10px 0;
  border-bottom: 1px solid var(--hair);
}

.coin-prize-row:last-child { border-bottom: none; }

.coin-prize-top {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
}

.coin-prize-emoji {
  font-size: 22px;
  line-height: 1.3;
  flex: 0 0 auto;
}

.coin-prize-name {
  flex: 1;
  min-width: 0;
  font-weight: 600;
  color: var(--text);
  line-height: 1.35;
  padding-top: 2px;
  /* Wrap fully — the point of the prize row redesign is that the whole
     description is readable. The modal body scrolls, so even a maximal
     120-char name just takes a few lines. */
  overflow-wrap: anywhere;
}

.coin-prize-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 6px;
  /* Indent under the name, past the emoji column. */
  padding-left: 32px;
}

.coin-prize-cost {
  font-size: 13px;
  font-weight: 600;
  color: var(--coin-gold);
  white-space: nowrap;
}

.coin-prize-actions {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* Compact button for use inside rows — undoes the shared .btn-primary /
   .btn-secondary flex-grow and min-width so it hugs its label. */
.coin-row-btn {
  flex: 0 0 auto;
  min-width: 0;
  padding: 7px 16px;
  font-size: 13px;
}

.coin-row-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  box-shadow: none;
}

.coin-prize-remove {
  background: none;
  border: none;
  color: var(--text-subtle);
  padding: 6px;
  border-radius: 8px;
  cursor: pointer;
}

.coin-prize-remove:hover {
  background: var(--surface-alt);
  color: var(--text);
}

.coin-prize-edit {
  background: none;
  border: none;
  color: var(--text-subtle);
  padding: 6px;
  border-radius: 8px;
  cursor: pointer;
}

.coin-prize-edit:hover {
  background: var(--surface-alt);
  color: var(--text);
}

/* Inline rename/reprice form shown in place of a prize row. */
.coin-prize-edit-form {
  display: grid;
  grid-template-columns: 1fr 80px;
  gap: 8px;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.coin-add-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.coin-add-form-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.coin-add-form-row input { width: 96px; flex: 0 0 auto; }
.coin-add-form-row .coin-row-btn { margin-left: auto; }

/* Real text-field styling for the prize inputs — the bare browser default
   rendered as skinny unpadded boxes that looked broken next to the
   buttons. Mirrors the login-form fields, sized down for the modal. */
.coin-add-form input,
.coin-prize-edit-form input {
  min-width: 0;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
  -webkit-appearance: none;
}

.coin-add-form input:focus,
.coin-prize-edit-form input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-softer);
}

.coin-redemption-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--hair);
}

.coin-redemption-row:last-child { border-bottom: none; }

.coin-redemption-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.coin-redemption-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
}

.coin-redemption-meta {
  font-size: 11px;
  color: var(--text-subtle);
}

.coin-redemption-done {
  font-size: 12px;
  color: var(--accent-deep);
  white-space: nowrap;
}

.coin-redemption-pending {
  font-size: 12px;
  color: var(--text-subtle);
  white-space: nowrap;
}

/* =========================================================
   Onboarding tour overlay
   ========================================================= */
.tour-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 31, 42, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 9500;
  animation: minigame-fade 0.18s ease-out;
}
.tour-overlay.hidden { display: none; }

.tour-card {
  position: relative;
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border-radius: 20px;
  padding: 28px 24px 22px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.28);
  text-align: center;
}

.tour-skip {
  position: absolute;
  top: 12px;
  right: 14px;
  background: none;
  border: none;
  color: var(--text-subtle);
  font-size: 14px;
  font-weight: 500;
  padding: 6px 8px;
  cursor: pointer;
}
.tour-skip:hover { color: var(--text); }

.tour-icon {
  font-size: 44px;
  line-height: 1;
  margin-bottom: 12px;
}

.tour-title {
  font-size: 19px;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 10px;
}

.tour-body {
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--text-muted);
  margin: 0 0 18px;
  min-height: 108px;
}

.tour-dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-bottom: 18px;
}
.tour-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--hair);
}
.tour-dot.active { background: #6b8e5a; }

.tour-nav {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.tour-nav .btn-primary,
.tour-nav .btn-secondary {
  flex: 1;
}
