/* ===== STITCH & FLOW DESIGN SYSTEM ===== */
:root {
  --primary: #ae2f34;
  --on-primary: #ffffff;
  --primary-container: #ff6b6b;
  --on-primary-container: #6d0010;
  --primary-fixed: #ffdad8;
  --primary-fixed-dim: #ffb3b0;
  --secondary: #006a65;
  --on-secondary: #ffffff;
  --secondary-container: #79f3ea;
  --on-secondary-container: #006f69;
  --tertiary: #705d00;
  --on-tertiary: #ffffff;
  --tertiary-fixed: #ffe173;
  --tertiary-fixed-dim: #e8c426;
  --on-tertiary-fixed: #221b00;
  --background: #fef8f4;
  --on-background: #1d1b19;
  --surface: #fef8f4;
  --surface-dim: #ded9d5;
  --surface-bright: #fef8f4;
  --surface-container-lowest: #ffffff;
  --surface-container-low: #f8f2ef;
  --surface-container: #f3ede9;
  --surface-container-high: #ede7e3;
  --surface-container-highest: #e7e1de;
  --on-surface: #1d1b19;
  --on-surface-variant: #584140;
  --outline: #8c706f;
  --outline-variant: #e0bfbd;
  --error: #ba1a1a;
  --error-container: #ffdad6;
  --on-error-container: #93000a;
  --inverse-surface: #32302e;
  --inverse-on-surface: #f5f0ec;
  --inverse-primary: #ffb3b0;
  --shadow-color: rgba(174, 47, 52, 0.06);
  /* Primary used as a text/icon colour. Identical to --primary in light mode;
     re-tinted for dark, where #ae2f34 on a near-black surface only reaches ~2.8:1
     (below the 3:1 WCAG floor for icons). --primary itself stays the fill colour
     so bg-primary + on-primary keeps working. */
  --primary-text: #ae2f34;
  /* Same idea for the teal accent: #006a65 only manages 2.2-3.0:1 on dark
     surfaces, so dark mode gets a lighter tint for text/icon use. */
  --secondary-text: #006a65;
  --color-scheme: light;
  /* Tells the browser which palette to use for the parts of form controls it
     paints itself: select popups, date pickers, carets, scrollbars, autofill. */
  color-scheme: light;
  /* Trends chart series (validated colorblind-safe categorical palette) */
  --trend-1: #2a78d6;
  --trend-2: #eb6834;
  --trend-3: #1baf7a;
}

.dark {
  --background: #1a1716;
  --on-background: #e7e1de;
  --surface: #1a1716;
  --surface-dim: #141210;
  --surface-bright: #322e2c;
  --surface-container-lowest: #0f0d0c;
  --surface-container-low: #1d1b19;
  --surface-container: #211f1d;
  --surface-container-high: #2b2927;
  --surface-container-highest: #363432;
  --on-surface: #e7e1de;
  --on-surface-variant: #cbc1bf;
  --outline: #948b89;
  --outline-variant: #524342;
  --primary-container: #8c1520;
  --on-primary-container: #ffdad8;
  --secondary-container: #00504c;
  --on-secondary-container: #7cf6ec;
  --tertiary: #e8c426;
  --on-tertiary: #1a1716;
  --tertiary-fixed: #554500;
  --on-tertiary-fixed: #ffe173;
  --shadow-color: rgba(0, 0, 0, 0.3);
  --color-scheme: dark;
  color-scheme: dark;
  /* These are Material "fixed" roles, which normally stay constant across
     themes — but this app paints focus rings, hover fills and error badges with
     them, so their light values showed up as near-white blocks on dark
     surfaces. Re-tinted for dark. */
  --primary-text: #ffb3b0;
  --secondary-text: #5dd9d0;
  --primary-fixed: #5c1519;
  --primary-fixed-dim: #7a1a20;
  --error: #ffb4ab;
  --error-container: #93000a;
  --on-error-container: #ffdad6;
  /* Trends chart series — steps re-derived for the dark surface */
  --trend-1: #3987e5;
  --trend-2: #d95926;
  --trend-3: #199e70;
}

/* Dark utility-class overrides (Tailwind CDN bakes hex values, so we re-apply via CSS vars) */
.dark .bg-background { background: var(--background) !important; }
.dark .bg-surface-container { background: var(--surface-container) !important; }
.dark .bg-surface-container-low { background: var(--surface-container-low) !important; }
.dark .bg-surface-container-lowest { background: var(--surface-container-lowest) !important; }
.dark .bg-surface-container-high { background: var(--surface-container-high) !important; }
.dark .hover\:bg-surface-container-high:hover { background: var(--surface-container-high) !important; }
.dark .hover\:bg-surface-container-low:hover { background: var(--surface-container-low) !important; }
.dark .bg-surface-container-highest { background: var(--surface-container-highest) !important; }
.dark .bg-primary { background: var(--primary) !important; }
.dark .bg-primary-container { background: var(--primary-container) !important; }
.dark .bg-secondary-container { background: var(--secondary-container) !important; }
.dark .bg-tertiary-fixed { background: var(--tertiary-fixed) !important; }
.dark .bg-on-tertiary-fixed { background: var(--on-tertiary-fixed) !important; }
.dark .bg-outline-variant { background: var(--outline-variant) !important; }
.dark .text-primary { color: var(--primary-text) !important; }
.dark .text-secondary { color: var(--secondary-text) !important; }
.dark .text-tertiary { color: var(--tertiary) !important; }
.dark .text-tertiary-fixed { color: var(--tertiary-fixed) !important; }
.dark .text-outline { color: var(--outline) !important; }
.dark .text-outline-variant { color: var(--outline-variant) !important; }
.dark .text-on-tertiary-fixed { color: var(--on-tertiary-fixed) !important; }
.dark .text-surface-container-high { color: var(--surface-container-high) !important; }
.dark .text-on-surface-variant { color: var(--on-surface-variant) !important; }
.dark .text-on-surface { color: var(--on-surface) !important; }
.dark .hover\:text-on-surface:hover { color: var(--on-surface) !important; }
.dark .text-on-primary { color: var(--on-primary) !important; }
.dark .text-on-primary-container { color: var(--on-primary-container) !important; }
.dark .text-on-secondary-container { color: var(--on-secondary-container) !important; }
.dark .border-surface-container { border-color: var(--surface-container) !important; }
.dark .border-outline-variant { border-color: var(--outline-variant) !important; }
.dark .border-primary { border-color: var(--primary) !important; }
.dark .bg-primary\/5 { background: color-mix(in srgb, var(--primary) 5%, transparent) !important; }
.dark .bg-primary-container\/10 { background: color-mix(in srgb, var(--primary-container) 10%, transparent) !important; }
.dark .bg-secondary-container\/30 { background: color-mix(in srgb, var(--secondary-container) 30%, transparent) !important; }
.dark .bg-surface-container\/80 { background: color-mix(in srgb, var(--surface-container) 80%, transparent) !important; }
.dark .bg-tertiary-fixed\/15 { background: color-mix(in srgb, var(--tertiary-fixed) 15%, transparent) !important; }
.dark .bg-surface-container-low\/80 { background: color-mix(in srgb, var(--surface-container-low) 80%, transparent) !important; }

/* Golden task item in Up Next */
.dash-task-item.golden-item {
  background: color-mix(in srgb, var(--tertiary-fixed) 15%, transparent);
  border-left-color: var(--tertiary-fixed-dim);
}
.dark .dash-task-item.golden-item {
  background: color-mix(in srgb, var(--tertiary-fixed) 25%, transparent);
}

/* ===== Up Next: collapsible subtask checklist ===== */
.dash-subtask-toggle {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--on-surface-variant);
  opacity: 0.55;
  padding: 2px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  flex-shrink: 0;
  transition: all 0.2s;
}
.dash-subtask-toggle:hover { opacity: 1; color: var(--primary-text); background: var(--surface-container); }
.dash-subtask-toggle[aria-expanded="true"] { opacity: 1; color: var(--primary-text); }
.dash-subtask-toggle .material-symbols-outlined { font-size: 20px; }

/* Indented under the task title, aligned past the drag/play/check icons */
.dash-subtask-list {
  list-style: none;
  margin: 8px 0 2px 34px;
  padding-left: 10px;
  border-left: 2px solid var(--outline-variant);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.dash-subtask-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 5px;
  border-radius: 8px;
  transition: background 0.15s;
}
.dash-subtask-item:hover { background: var(--surface-container); }
.dash-subtask-check {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--outline-variant);
  flex-shrink: 0;
  line-height: 1;
  padding: 0;
  font-size: 17px !important;
  transition: color 0.2s, transform 0.2s;
}
.dash-subtask-check:hover { color: var(--secondary-text); transform: scale(1.15); }
.dash-subtask-item.done .dash-subtask-check { color: var(--secondary-text); }
.dash-subtask-text { font-size: 12px; min-width: 0; word-break: break-word; }
.dash-subtask-item.done .dash-subtask-text { text-decoration: line-through; opacity: 0.55; }

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

body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  background: var(--background);
  color: var(--on-background);
  min-height: 100vh;
  min-height: 100dvh;
  /* Installed, there is no browser chrome to rubber-band against, so the bounce
     at the end of a scroll just detaches the app from its own background. */
  overscroll-behavior-y: none;
  /* The grey flash on every tap on Android reads as lag on elements that are
     not buttons at all. Real feedback comes from :active and .press-effect. */
  -webkit-tap-highlight-color: transparent;
}

/* ===== APP SHELL HEIGHT =====
   100vh on a mobile browser is the viewport with the URL bar hidden, which is
   taller than what you can see while it is showing. Sizing the shell that way
   pushed its foot — and the end of the inner scroller — underneath the URL bar,
   with no way to reach it. dvh is the visible height and follows the bar as it
   collapses. The 100vh line stays as the fallback for anything without dvh. */
.app-main {
  height: 100vh;
  height: 100dvh;
}

.px-container-padding { padding-left: 24px; padding-right: 24px; }

/* ===== PAGE WIDTH =====
   One width for every tab, so switching between them doesn't shift the content
   sideways. Wide enough to earn a large display, capped so a line of text never
   gets unreadably long. Tune here, not per section. */
.app-wide {
  width: 100%;
  max-width: 1600px;
  margin-left: auto;
  margin-right: auto;
}

/* Gutters grow with the viewport. Without this the content runs almost to the
   bezel between roughly 1024px and the cap, which is what makes a full-width
   layout feel cramped rather than generous. */
.tab-pad { padding-left: 16px; padding-right: 16px; }
@media (min-width: 768px) { .tab-pad { padding-left: 24px; padding-right: 24px; } }
@media (min-width: 1280px) { .tab-pad { padding-left: 40px; padding-right: 40px; } }

/* ===== SCROLLBAR ===== */
.custom-scrollbar::-webkit-scrollbar { width: 6px; }
.custom-scrollbar::-webkit-scrollbar-track { background: transparent; }
.custom-scrollbar::-webkit-scrollbar-thumb { background: var(--outline-variant); border-radius: 10px; }
* { scrollbar-width: thin; scrollbar-color: var(--outline-variant) transparent; }

/* ===== TAB SYSTEM ===== */
section[data-tab].tab-hidden { display: none !important; }

/* Sidebar tabs */
.tab {
  background: transparent;
  border: none;
  color: var(--on-surface-variant);
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: 16px;
  text-align: left;
  width: 100%;
}
.tab:hover { background: var(--surface-container-high); color: var(--primary-text); }
.tab .material-symbols-outlined { color: inherit; }
.tab.active {
  background: var(--primary-container);
  color: var(--on-primary-container);
  font-weight: 700;
}
.tab.active .material-symbols-outlined { font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24; }

/* Mobile nav tabs.
   These three rules used to be written `.md\\:hidden .tab` — a doubled
   backslash, which CSS reads as the class `md\` followed by an unknown
   pseudo-class, making the selector invalid and throwing the rule away. So none
   of it had ever applied, and the bottom bar's selected tab fell through to
   `.tab.active` above and drew a coral pill across itself. Targeting the id
   instead says the same thing and is a selector that actually parses. */
#mobileNav .tab,
#mobileNav .mnav-more {
  justify-content: center;
  align-items: center;
  padding: 6px 12px;
  /* The resting colour lives here, at one id and one class, rather than on the
     buttons as a `text-on-surface-variant` utility. That utility has a
     `.dark .text-on-surface-variant { ... !important }` override further up,
     which outranked `.active` — so in dark mode every tab in the bar was the
     same grey and there was no telling which one you were on. */
  color: var(--on-surface-variant);
}
#mobileNav .tab.active {
  color: var(--primary-text);
  background: transparent;
}
#mobileNav .tab.active .material-symbols-outlined { font-variation-settings: 'FILL' 1; }

/* ===== POMODORO ===== */
#pomodoroSection { min-height: calc(100vh - 200px); min-height: calc(100dvh - 200px); }
/* These target the class the markup actually carries. They used to say
   `.progress-ring`, which nothing has had for a long time — so the ring started
   at 3 o'clock instead of 12 and jumped a step per second instead of sweeping. */
.timer-ring { transform: rotate(-90deg); }
.timer-ring circle { transition: stroke-dashoffset 0.5s ease-in-out; }
.timer-ring .fg { transition: stroke-dashoffset 0.5s ease-in-out, stroke 0.3s ease; }
.pulse-slow { animation: pulse-ring 3s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
@keyframes pulse-ring {
  0%, 100% { opacity: 0.1; transform: scale(1); }
  50% { opacity: 0.2; transform: scale(1.05); }
}

/* ===== TASK LIST ===== */
#todoList { list-style: none; }

/* --- Individual task item ---
   Deliberately dense: the vertical rhythm here decides how many tasks are on
   screen at once, so padding, the gap to the action icons and the row gap are all
   kept tight. Touch targets are held at >=28px by the action-button padding. */
#todoList > li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 12px;
  background: var(--surface-container-lowest);
  border-radius: 14px;
  box-shadow: 0 8px 20px -4px var(--shadow-color);
  border: 1px solid var(--surface-container);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  position: relative;
  overflow: hidden;
}
#todoList > li:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 24px -8px var(--shadow-color);
}

/* Active/pending tasks get left accent strip */
#todoList > li:not(.completed)::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: var(--primary-container);
  border-radius: 0 4px 4px 0;
}

/* Golden task */
#todoList > li.golden {
  border: 1px solid var(--tertiary-fixed-dim);
  box-shadow: 0 0 25px rgba(232, 196, 38, 0.15);
}
#todoList > li.golden::before { background: var(--tertiary-fixed-dim); }

/* Completed task */
#todoList > li.completed {
  background: var(--surface-container-low);
  opacity: 0.75;
}
#todoList > li.completed::before { background: var(--secondary); }
#todoList > li.completed .task-text { text-decoration: line-through; color: var(--on-surface-variant); opacity: 0.6; }

#todoList > li input[type="checkbox"] {
  appearance: none;
  background: transparent;
  width: 20px;
  height: 20px;
  border: 2px solid var(--outline);
  border-radius: 50%;
  cursor: pointer;
  flex-shrink: 0;
  margin-top: 1px;
  position: relative;
  transition: all 0.25s ease;
}
#todoList > li input[type="checkbox"]:hover { border-color: var(--primary); background: var(--primary-fixed); }
#todoList > li input[type="checkbox"]:checked {
  background: var(--secondary);
  border-color: var(--secondary);
  transform: scale(1.05);
}
#todoList > li input[type="checkbox"]:checked::after {
  content: 'check';
  font-family: 'Material Symbols Outlined';
  font-size: 14px;
  color: white;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.task-content { flex: 1; min-width: 0; }
.task-title-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.task-text { font-weight: 600; word-break: break-word; font-size: 15px; line-height: 1.35; }
.task-badges { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.task-tags-row { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.task-desc { font-size: 13px; color: var(--on-surface-variant); margin-top: 3px; line-height: 1.4; }
.task-actions-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding-top: 3px;
  border-top: 1px solid var(--surface-container);
}

#todoList > li .task-actions-row button {
  background: none;
  border: none;
  cursor: pointer;
  padding: 3px 5px;
  border-radius: 8px;
  transition: all 0.2s;
  font-size: 14px;
  line-height: 1;
  opacity: 0.6;
}
#todoList > li .task-actions-row button:hover { opacity: 1; background: var(--surface-container); }

/* Priority badges */
.priority-badge { font-size: 10px; padding: 2px 8px; border-radius: 999px; font-weight: 700; font-family: 'JetBrains Mono', monospace; text-transform: uppercase; letter-spacing: 0.5px; }
.priority-badge.low { background: #2ecc7140; color: #2ecc71; }
.priority-badge.medium { background: #f39c1240; color: #f39c12; }
.priority-badge.high { background: #e67e2240; color: #e67e22; }
.priority-badge.urgent { background: #e74c3c40; color: #e74c3c; }

/* Project badge */
.project-badge { font-size: 10px; padding: 2px 8px; border-radius: 999px; background: var(--outline-variant); color: var(--on-surface-variant); font-weight: 600; font-family: 'JetBrains Mono', monospace; text-transform: uppercase; letter-spacing: 0.5px; }

/* Frequency badge */
.freq-badge { font-size: 10px; padding: 2px 8px; border-radius: 999px; background: var(--primary); color: var(--on-primary); font-weight: 600; font-family: 'JetBrains Mono', monospace; }

/* Due badge */
.due-badge { font-size: 10px; padding: 2px 8px; border-radius: 999px; background: var(--surface-container-high); color: var(--on-surface-variant); font-weight: 600; white-space: nowrap; }
.due-badge.overdue { background: var(--error-container); color: var(--on-error-container); }

/* On an open task the badge is a button that opens the inline date picker. It
   inherits the pill above unchanged, so a dated row looks exactly as it did. */
button.due-badge {
  border: none;
  font-family: inherit;
  cursor: pointer;
  transition: opacity 0.2s, filter 0.2s, background 0.2s;
}
button.due-badge:hover { filter: brightness(1.08); }
/* An undated task has no date to show, so the icon sits back until it's wanted.
   Always present rather than hover-only — touch has no hover. */
button.due-badge.is-empty {
  background: transparent;
  opacity: 0.45;
  padding: 2px 4px;
}
button.due-badge.is-empty:hover,
button.due-badge.is-empty:focus-visible {
  background: var(--surface-container-high);
  opacity: 1;
}

/* ===== INLINE DUE-DATE PICKER =====
   Anchored to the badge but parented to <body>, so neither the task list's
   re-render nor #taskScrollArea's overflow can clip it. Sits above the list and
   below the modals (which are 1000+). */
.due-picker {
  position: fixed;
  z-index: 900;
  width: 244px;
  padding: 10px;
  background: var(--surface-container-lowest);
  border: 1px solid var(--outline-variant);
  border-radius: 14px;
  box-shadow: 0 12px 28px -6px var(--shadow-color);
  font-family: 'JetBrains Mono', monospace;
}
.due-picker.hidden { display: none; }

.due-picker-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.due-picker-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--on-surface);
}
.due-picker-nav {
  background: transparent;
  border: none;
  border-radius: 999px;
  width: 24px;
  height: 24px;
  font-size: 16px;
  line-height: 1;
  color: var(--on-surface-variant);
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.due-picker-nav:hover { background: var(--surface-container); color: var(--primary-text); }

.due-picker-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.due-picker-dayname {
  text-align: center;
  font-size: 9px;
  font-weight: 700;
  color: var(--on-surface-variant);
  opacity: 0.7;
  padding-bottom: 4px;
}
.due-picker-day {
  aspect-ratio: 1;
  background: transparent;
  border: none;
  border-radius: 8px;
  font-family: inherit;
  font-size: 11px;
  color: var(--on-surface);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.due-picker-day:hover { background: var(--surface-container-high); }
.due-picker-day.other-month { opacity: 0.32; }
/* Today is outlined, the chosen day is filled — so both can show at once. */
.due-picker-day.is-today { box-shadow: inset 0 0 0 1.5px var(--primary); }
.due-picker-day.is-selected {
  background: var(--primary);
  color: var(--on-primary);
  font-weight: 700;
}

.due-picker-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--surface-container);
}
.due-picker-preset {
  flex: 1 1 auto;
  background: var(--surface-container-low);
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  padding: 4px 8px;
  font-family: inherit;
  font-size: 10px;
  font-weight: 600;
  color: var(--on-surface-variant);
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.due-picker-preset:hover { color: var(--primary-text); border-color: var(--primary); }
.due-picker-preset.is-clear { flex-basis: 100%; color: var(--error); }
.due-picker-preset.is-clear:hover { border-color: var(--error); color: var(--error); }

/* Est. pomo badge */
.task-pomo-count { font-size: 11px; color: var(--on-surface-variant); white-space: nowrap; display: flex; align-items: center; gap: 2px; }
.est-pomo-done { color: var(--secondary-text); font-weight: 700; }
.est-pomo-sep { color: var(--outline); }

/* ===== SUBTASKS ===== */
/* Progress pill in the task title row — click to open/close the checklist */
.subtask-badge {
  font-size: 10px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-container-high);
  color: var(--on-surface-variant);
  font-weight: 700;
  font-family: 'JetBrains Mono', monospace;
  white-space: nowrap;
  border: none;
  cursor: pointer;
  transition: all 0.2s;
}
.subtask-badge:hover { background: var(--primary-container); color: var(--on-primary-container); }
.subtask-badge.complete { background: var(--secondary-container); color: var(--on-secondary-container); }

/* Toggle in the actions row */
.subtask-toggle-btn { font-size: 13px !important; flex-shrink: 0; }
#todoList > li .task-actions-row button.subtask-toggle-btn.active {
  opacity: 1;
  color: var(--primary-text);
  background: var(--primary-fixed);
}

.subtask-panel {
  margin-top: 8px;
  padding: 8px 10px;
  background: var(--surface-container-low);
  border: 1px solid var(--surface-container);
  border-radius: 12px;
}

.subtask-progress {
  height: 4px;
  width: 100%;
  background: var(--surface-container-high);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 10px;
}
.subtask-progress-fill {
  height: 100%;
  background: var(--secondary);
  border-radius: 999px;
  transition: width 0.3s ease;
}

.subtask-list { list-style: none; display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; }
.subtask-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 2px;
  border-radius: 8px;
}
.subtask-item:hover { background: var(--surface-container); }
.subtask-text { flex: 1; min-width: 0; font-size: 13px; word-break: break-word; }
.subtask-item.done .subtask-text { text-decoration: line-through; color: var(--on-surface-variant); opacity: 0.6; }

/* Click-to-rename. The label carries the same padding as the field that replaces
   it, so switching between them doesn't shift the row. */
.subtask-text[role="button"], .dash-subtask-text[role="button"] {
  cursor: text;
  padding: 1px 5px;
  margin-left: -5px;
  border-radius: 6px;
  transition: background 0.15s;
}
.subtask-text[role="button"]:hover, .dash-subtask-text[role="button"]:hover {
  background: var(--surface-container-high);
}
.subtask-text[role="button"]:focus-visible, .dash-subtask-text[role="button"]:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
input.subtask-edit-input {
  flex: 1;
  min-width: 0;
  background: var(--surface-container-high);
  border: 1.5px solid var(--primary);
  border-radius: 8px;
  padding: 1px 5px;
  font-size: 13px;
  font-family: 'Inter', sans-serif;
  color: var(--on-surface);
  outline: none;
  box-shadow: 0 0 0 3px var(--primary-fixed);
}

/* Smaller square checkbox — overrides the round 22px task checkbox */
#todoList > li .subtask-item input[type="checkbox"] {
  background: transparent;
  width: 16px;
  height: 16px;
  border-radius: 5px;
  border-width: 2px;
  margin-top: 0;
}
#todoList > li .subtask-item input[type="checkbox"]:checked::after { font-size: 11px; }

.subtask-del {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--outline);
  font-size: 12px;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 6px;
  opacity: 0;
  transition: all 0.2s;
  flex-shrink: 0;
}
.subtask-item:hover .subtask-del, .modal-subtask-row:hover .subtask-del { opacity: 0.7; }
.subtask-del:hover { opacity: 1 !important; color: var(--error); background: var(--surface-container-high); }

.subtask-empty {
  font-size: 12px;
  color: var(--on-surface-variant);
  opacity: 0.6;
  padding: 4px 2px;
  list-style: none;
}

/* Matches the app's form-input treatment (see .form-group input): 1.5px border,
   12px radius, surface-container-low fill, primary focus ring. */
.subtask-add { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
input.subtask-input {
  flex: 1;
  min-width: 0;
  /* NOT --surface-container-low: the panel around it already uses that, so the
     field had zero contrast and no visible box in either theme. One step up
     reproduces the container-vs-field relationship the modal inputs have.
     (Inside the modal, .form-group's rule wins and keeps the standard fill.) */
  background: var(--surface-container-high);
  border: 1.5px solid var(--outline-variant);
  border-radius: 12px;
  padding: 8px 12px;
  font-size: 13px;
  font-family: 'Inter', sans-serif;
  color: var(--on-surface);
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
}
input.subtask-input::placeholder { color: var(--outline); opacity: 0.5; }
input.subtask-input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-fixed);
}

/* Pill "add" button, matching the quick-add button in the task header */
.subtask-add-btn {
  background: var(--primary-container);
  color: var(--on-primary-container);
  border: none;
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 12px;
  font-weight: 700;
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  flex-shrink: 0;
  transition: filter 0.2s, transform 0.15s;
}
.subtask-add-btn:hover { filter: brightness(1.08); }
.subtask-add-btn:active { transform: scale(0.95); }

/* Subtask editor inside the task modal */
.modal-subtask-list { display: flex; flex-direction: column; gap: 4px; }
.modal-subtask-row { display: flex; align-items: center; gap: 8px; }
.modal-subtask-row input[type="checkbox"] {
  appearance: none;
  background: transparent;
  width: 16px;
  height: 16px;
  border: 2px solid var(--outline);
  border-radius: 5px;
  cursor: pointer;
  flex-shrink: 0;
  position: relative;
  transition: all 0.2s ease;
}
.modal-subtask-row input[type="checkbox"]:checked { background: var(--secondary); border-color: var(--secondary); }
.modal-subtask-row input[type="checkbox"]:checked::after {
  content: 'check';
  font-family: 'Material Symbols Outlined';
  font-size: 11px;
  color: white;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.modal-subtask-title {
  flex: 1;
  min-width: 0;
  background: var(--surface-container-low);
  border: 1.5px solid var(--outline-variant);
  border-radius: 12px;
  padding: 8px 12px;
  font-size: 13px;
  font-family: 'Inter', sans-serif;
  color: var(--on-surface);
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.modal-subtask-title:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-fixed);
}
.modal-subtask-row.done .modal-subtask-title { text-decoration: line-through; opacity: 0.6; }
.subtask-hint { font-size: 11px; color: var(--on-surface-variant); opacity: 0.6; margin-top: 6px; }

/* Golden button */
.golden-btn { font-size: 15px !important; flex-shrink: 0; filter: grayscale(1); opacity: 0.4 !important; transition: all 0.2s !important; }
.golden-btn.active { filter: grayscale(0); opacity: 1 !important; transform: scale(1.1); }

/* Play button */
.play-btn { font-size: 13px !important; flex-shrink: 0; }

/* Drag handle */
.drag-handle { cursor: grab; color: var(--outline); font-size: 16px; line-height: 1; flex-shrink: 0; padding: 0 4px; user-select: none; opacity: 0; transition: opacity 0.2s; }
#todoList > li:hover .drag-handle { opacity: 0.5; }
.drag-handle:hover { opacity: 1 !important; }

/* Drag & Drop */
#todoList > li.dragging { opacity: 0.3; }
#todoList > li.drag-over { border-top: 2px solid var(--primary); }

/* ===== TAG CLOUD ===== */
#tagCloud .tag-pill {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 999px;
  cursor: pointer;
  transition: all 0.2s;
  font-weight: 500;
  border: 1.5px solid transparent;
  background: var(--surface-container-high);
  color: var(--on-surface);
}
#tagCloud .tag-pill:hover { transform: scale(1.05); }
#tagCloud .tag-pill.active { border-color: currentColor; font-weight: 700; }
#tagCloud .tag-pill .count { margin-left: 4px; font-size: 10px; opacity: 0.6; font-family: 'JetBrains Mono', monospace; }

/* ===== SORT CONTROLS ===== */
.sort-btn {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--on-surface-variant);
  cursor: pointer;
  font-family: 'JetBrains Mono', monospace;
  padding-bottom: 6px;
  transition: color 0.2s, border-color 0.2s;
}
.sort-btn:hover { color: var(--primary-text); }
.sort-btn.active { color: var(--primary-text); font-weight: 700; border-bottom-color: var(--primary); }

/* ===== DUE WINDOW FILTER =====
   Pills rather than the sort bar's underlines: sorting and filtering sit side by
   side here, and they need to look like two different kinds of control. */
.due-filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--surface-container-low);
  color: var(--on-surface-variant);
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  padding: 3px 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.due-filter-btn:hover { color: var(--primary-text); border-color: var(--primary); }
.due-filter-btn.active {
  background: var(--primary-fixed);
  color: var(--on-primary-container);
  border-color: var(--primary);
  font-weight: 700;
}
.due-filter-btn .due-filter-count {
  background: var(--surface-container-high);
  color: var(--on-surface-variant);
  border-radius: 999px;
  padding: 0 5px;
  font-size: 10px;
}
.due-filter-btn.active .due-filter-count { background: var(--surface-container-lowest); }
/* Hidden rather than zeroed: a count only earns its space once it says something
   the label doesn't. */
.due-filter-btn .due-filter-count:empty { display: none; }

/* Shown only when a due window is what emptied the list, so the plain empty list
   keeps looking the way it always has. */
.task-empty-note {
  list-style: none;
  text-align: center;
  padding: 28px 12px;
  color: var(--on-surface-variant);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
}
.task-empty-note button {
  display: block;
  margin: 10px auto 0;
  background: transparent;
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  padding: 4px 12px;
  color: var(--primary-text);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.task-empty-note button:hover { border-color: var(--primary); }

/* ===== DUE SECTION HEADERS ===== */
.due-section-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--on-surface-variant);
  padding: 12px 4px 4px;
  font-family: 'JetBrains Mono', monospace;
  list-style: none;
  pointer-events: none;
}
.due-section-header .due-count { background: var(--surface-container); padding: 1px 8px; border-radius: 999px; font-size: 10px; }
.due-section-header.overdue { color: var(--error); }

/* ===== COMPLETED TASKS ===== */
.completed-section-header {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--on-surface-variant);
  padding: 16px 4px 4px;
  margin-top: 12px;
  border-top: 1px solid var(--surface-container);
  font-family: 'JetBrains Mono', monospace;
  list-style: none;
}
.completed-section-header:first-child { border-top: none; margin-top: 0; }
.completed-section-header span { background: var(--surface-container-lowest); padding-right: 8px; }
.completed-badge { font-size: 10px; color: var(--secondary-text); font-weight: 600; }

.completed-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 12px 0;
  margin-top: 8px;
  border-top: 1px solid var(--surface-container);
  list-style: none;
}
.completed-pagination button {
  background: var(--surface-container);
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  color: var(--on-surface-variant);
  font-size: 11px;
  padding: 6px 14px;
  cursor: pointer;
  transition: all 0.2s;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
}
.completed-pagination button:hover:not(:disabled) { background: var(--surface-container-high); }
.completed-pagination button:disabled { opacity: 0.3; cursor: default; }
.completed-pagination span { font-size: 11px; color: var(--on-surface-variant); min-width: 3rem; text-align: center; font-family: 'JetBrains Mono', monospace; }

/* ===== TAGS (inline) ===== */
.tag {
  display: inline-block;
  font-size: 11px;
  padding: 2px 10px;
  border-radius: 999px;
  font-weight: 600;
}

/* ===== VIEW TABS (Stats) ===== */
.view-tabs button {
  background: none;
  border: none;
  color: var(--on-surface-variant);
  cursor: pointer;
  font-family: 'JetBrains Mono', monospace;
  transition: all 0.2s;
}
.view-tabs button.active { color: var(--primary-text); font-weight: 700; border-bottom: 2px solid var(--primary); }
.view-tabs button:hover:not(.active) { color: var(--on-surface); }

/* ===== STATS: CONTRIBUTION HEATMAP =====
   Distinct from the Calendar tab, whose rules are namespaced .cal-*. */
.heatmap-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.heatmap-nav button {
  background: var(--surface-container);
  border: none;
  color: var(--on-surface);
  padding: 8px 14px;
  border-radius: 999px;
  cursor: pointer;
  font-size: 14px;
  transition: background 0.2s;
  font-weight: 600;
}
.heatmap-nav button:hover { background: var(--surface-container-high); }
.heatmap-nav span { font-weight: 700; font-size: 16px; }

/* Sized to the chart column it now sits in. The cell cap matters as much as the
   container one: with cells pinned at 84px the grid stopped growing at ~620px
   however wide the page got. */
.heatmap-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 8px;
  max-width: 840px;
  margin: 0 auto;
}
.heatmap-grid .day-header {
  text-align: center;
  font-size: 10px;
  color: var(--on-surface-variant);
  padding: 6px 0;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
}
.heatmap-grid .day-cell {
  aspect-ratio: 1;
  max-width: 112px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  font-size: 15px;
  position: relative;
  transition: transform 0.2s;
}
.heatmap-grid .day-cell:hover { transform: scale(1.1); z-index: 2; }
.heatmap-grid .day-cell.empty { background: none; }
.heatmap-grid .day-cell .day-num { font-weight: 600; line-height: 1.1; }
.heatmap-grid .day-cell .day-star { font-size: 11px; line-height: 1; }
/* Pomodoros completed that day — inherit the cell's text colour so it stays
   legible on both empty and filled (coloured) cells. */
.heatmap-grid .day-cell .day-count {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  font-size: 12px;
  font-weight: 700;
  color: inherit;
  opacity: 0.9;
  margin-top: 2px;
  line-height: 1;
  font-family: 'JetBrains Mono', monospace;
}
.heatmap-grid .day-cell.level-0 .day-count { color: var(--primary-text); opacity: 1; }
.heatmap-legend {
  text-align: center;
  font-size: 11px;
  color: var(--on-surface-variant);
  opacity: 0.7;
  margin-top: 12px;
  font-family: 'JetBrains Mono', monospace;
}

.heatmap-grid .day-cell.level-0 { background: var(--surface-container); }
.heatmap-grid .day-cell.level-1 { background: #ffe0e0; color: #410006; }
.heatmap-grid .day-cell.level-2 { background: #ffc0c0; color: #410006; }
.heatmap-grid .day-cell.level-3 { background: #ff6b6b; color: #ffffff; }
.heatmap-grid .day-cell.level-4 { background: var(--primary); color: var(--on-primary); }
.heatmap-grid .day-cell.level-5 { background: #6d0010; color: #ffffff; }

.dark .heatmap-grid .day-cell.level-0 { background: var(--surface-container); }
.dark .heatmap-grid .day-cell.level-1 { background: #2d1520; color: #e7e1de; }
.dark .heatmap-grid .day-cell.level-2 { background: #4a1c30; color: #e7e1de; }
.dark .heatmap-grid .day-cell.level-3 { background: #8c1520; color: #ffdad8; }
.dark .heatmap-grid .day-cell.level-4 { background: var(--primary); color: var(--on-primary); }
.dark .heatmap-grid .day-cell.level-5 { background: #410006; color: #ffdad8; }

/* ===== HOURS CHART ===== */
.hours-chart { display: flex; flex-direction: column; gap: 4px; }
.hours-row { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.hours-row .hour-label { width: 40px; text-align: right; color: var(--on-surface-variant); flex-shrink: 0; font-family: 'JetBrains Mono', monospace; font-weight: 600; }
.hours-row .hour-bar-bg { flex: 1; height: 18px; background: var(--surface-container); border-radius: 999px; overflow: hidden; }
.hours-row .hour-bar { height: 100%; border-radius: 999px; transition: width 0.3s ease; min-width: 2px; background: var(--primary); }
.dark .hours-row .hour-bar { background: var(--primary-container); }
.hours-row .hour-val { width: 28px; text-align: left; color: var(--on-surface-variant); flex-shrink: 0; font-family: 'JetBrains Mono', monospace; }

.no-data { text-align: center; color: var(--on-surface-variant); font-size: 14px; padding: 40px 0; opacity: 0.6; }

/* ===== TRENDS LINE CHART ===== */
.trends-controls { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.trend-ranges { display: inline-flex; background: var(--surface-container); border-radius: 999px; padding: 3px; gap: 2px; }
.trend-range-btn {
  border: none; background: transparent; cursor: pointer;
  font-family: 'JetBrains Mono', monospace; font-size: 12px; font-weight: 700;
  color: var(--on-surface-variant); padding: 5px 14px; border-radius: 999px; transition: all 0.15s ease;
}
.trend-range-btn:hover:not(.active) { color: var(--on-surface); }
.trend-range-btn.active { background: var(--surface-container-lowest); color: var(--primary-text); box-shadow: 0 1px 3px var(--shadow-color); }
.trends-legend { display: flex; flex-wrap: wrap; gap: 12px 16px; }
.trend-legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--on-surface-variant); font-weight: 600; }
.trend-legend-dot { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }

.trends-chart-area { position: relative; width: 100%; }
.trends-svg { display: block; width: 100%; height: auto; overflow: visible; }
.trend-grid { stroke: var(--outline-variant); stroke-width: 1; opacity: 0.5; }
.trend-axis-label { fill: var(--on-surface-variant); font-family: 'JetBrains Mono', monospace; font-size: 10px; opacity: 0.8; }
.trend-bar { stroke: none; pointer-events: none; }
.trends-hover-band { fill: var(--on-surface); opacity: 0.06; pointer-events: none; }

.trends-tooltip {
  position: absolute; top: 4px; transform: translateX(-50%);
  background: var(--inverse-surface); color: var(--inverse-on-surface);
  border-radius: 10px; padding: 8px 10px; font-size: 12px; pointer-events: none;
  box-shadow: 0 6px 20px -6px rgba(0,0,0,0.4); z-index: 5; min-width: 130px; white-space: nowrap;
}
.trends-tooltip.hidden { display: none; }
.trend-tip-date { font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700; opacity: 0.8; margin-bottom: 6px; }
.trend-tip-row { display: flex; align-items: center; gap: 6px; margin-top: 3px; }
.trend-tip-name { flex: 1; }
.trend-tip-val { font-family: 'JetBrains Mono', monospace; font-weight: 700; }
.trend-tip-total { margin-top: 6px; padding-top: 6px; border-top: 1px solid currentColor; opacity: 0.75; }

.trends-table-details { margin-top: 16px; font-size: 13px; }
.trends-table-details summary { cursor: pointer; color: var(--on-surface-variant); font-weight: 600; font-size: 12px; }
.trends-table-scroll { overflow-x: auto; max-height: 280px; overflow-y: auto; margin-top: 10px; }
.trends-table { width: 100%; border-collapse: collapse; font-family: 'JetBrains Mono', monospace; font-size: 12px; }
.trends-table th, .trends-table td { padding: 5px 10px; text-align: right; border-bottom: 1px solid var(--outline-variant); }
.trends-table th:first-child, .trends-table td:first-child { text-align: left; }
.trends-table th { color: var(--on-surface-variant); position: sticky; top: 0; background: var(--surface-container-low); }

/* ===== QUARTERLY GOALS ===== */

.qg-add-row {
  display: flex;
  gap: 8px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--surface-container);
}
.qg-add-row input {
  flex: 1;
  background: var(--surface-container-low);
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  padding: 8px 14px;
  color: var(--on-surface);
  font-size: 13px;
  font-family: 'Inter', sans-serif;
  outline: none;
  transition: border-color 0.2s;
}
.qg-add-row input:focus { border-color: var(--primary); }
.qg-add-btn {
  background: var(--primary);
  color: var(--on-primary);
  border: none;
  border-radius: 999px;
  padding: 8px 14px;
  font-size: 13px;
  cursor: pointer;
  flex-shrink: 0;
  font-weight: 600;
  transition: background 0.2s;
}
.qg-add-btn:hover { opacity: 0.9; }

/* ===== GOALS ARCHIVE =====
   One collapsed row per finished month, expanding to what was planned, what got
   ticked off, and what else happened that month. Read-only on purpose: an
   archive you can edit by mis-clicking isn't a record of anything. */
.qg-archive { display: flex; flex-direction: column; gap: 8px; }
.qg-archive-card {
  background: var(--surface-container-low);
  border: 1px solid var(--surface-container);
  border-radius: 14px;
  overflow: hidden;
  transition: border-color 0.2s;
}
.qg-archive-card.open { border-color: var(--outline-variant); }

.qg-archive-head {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  color: var(--on-surface);
  transition: background 0.15s;
}
.qg-archive-head:hover { background: var(--surface-container); }
.qg-archive-icon { font-size: 20px; color: var(--outline); flex-shrink: 0; }
.qg-archive-icon.all-done { color: var(--secondary-text); font-variation-settings: 'FILL' 1; }
.qg-archive-title {
  flex: 1;
  min-width: 0;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 14px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qg-archive-meta {
  flex-shrink: 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--on-surface-variant);
}
.qg-archive-chevron {
  font-size: 20px;
  flex-shrink: 0;
  color: var(--on-surface-variant);
  opacity: 0.6;
  transition: transform 0.2s;
}
.qg-archive-card.open .qg-archive-chevron { transform: rotate(180deg); }

.qg-archive-body { display: none; padding: 0 14px 14px; }
.qg-archive-card.open .qg-archive-body { display: block; }

.qg-archive-bar {
  height: 5px;
  background: var(--surface-container-high);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 12px;
}
.qg-archive-bar-fill { height: 100%; border-radius: 999px; background: var(--secondary); }

.qg-archive-list { list-style: none; display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; }
.qg-archive-item { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; line-height: 1.5; }
.qg-archive-item .material-symbols-outlined { font-size: 16px; margin-top: 2px; flex-shrink: 0; }
.qg-archive-item.done .material-symbols-outlined { color: var(--secondary-text); font-variation-settings: 'FILL' 1; }
.qg-archive-item.open .material-symbols-outlined { color: var(--outline); }
.qg-archive-item-text { min-width: 0; word-break: break-word; }
.qg-archive-item.done .qg-archive-item-text { text-decoration: line-through; opacity: 0.6; }
.qg-archive-empty { font-size: 12px; color: var(--on-surface-variant); opacity: 0.6; font-style: italic; list-style: none; }

.qg-archive-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--surface-container);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--on-surface-variant);
}
.qg-archive-stats strong { color: var(--primary-text); }

/* ===== MODAL OVERLAY ===== */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  /* The insets keep a dialog clear of the notch and the home indicator; they
     are 0 on anything without them, leaving the 16px exactly as it was. */
  padding: calc(16px + env(safe-area-inset-top)) calc(16px + env(safe-area-inset-right))
           calc(16px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left));
  backdrop-filter: blur(4px);
}
.modal-overlay.hidden { display: none; }

.modal {
  background: var(--surface-container-lowest);
  border-radius: 24px;
  width: 100%;
  max-height: 90vh;
  /* dvh, or an open keyboard on a phone leaves the modal taller than the space
     left above it and the buttons at its foot become unreachable. */
  max-height: 90dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
}

/* Modal header */
.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  border-bottom: 1px solid var(--surface-container);
}
.modal-header h2 { font-size: 18px; margin: 0; }

/* Modal body */
.modal-body { padding: 24px; }

/* Form groups */
.form-group { margin-bottom: 16px; }
.form-group label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--on-surface-variant);
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-family: 'JetBrains Mono', monospace;
}
/* Matches every text-like input rather than an allow-list of types, so adding a
   field of type email/search/tel/url can't silently fall back to the browser's
   white default. The :focus rule below keeps a higher specificity on purpose. */
.form-group input:not([type="checkbox"]):not([type="radio"]),
.form-group textarea,
.form-group select {
  width: 100%;
  padding: 10px 14px;
  border: 1.5px solid var(--outline-variant);
  border-radius: 12px;
  background: var(--surface-container-low);
  color: var(--on-surface);
  font-size: 14px;
  font-family: 'Inter', sans-serif;
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.form-group input[type="date"] { color-scheme: var(--color-scheme, dark); }
.form-group input:not([type="checkbox"]):not([type="radio"])::placeholder,
.form-group textarea::placeholder { color: var(--outline); opacity: 0.5; }
.form-group input:not([type="checkbox"]):not([type="radio"]):focus,
.form-group textarea:focus,
.form-group select:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-fixed);
}
.form-group textarea { resize: vertical; min-height: 60px; }

/* Chrome paints autofilled fields with its own near-white fill, overriding the
   background above. The inset shadow trick is the only way to repaint it. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-text-fill-color: var(--on-surface);
  -webkit-box-shadow: 0 0 0 1000px var(--surface-container-low) inset;
  box-shadow: 0 0 0 1000px var(--surface-container-low) inset;
  caret-color: var(--on-surface);
}
.form-row { display: flex; gap: 12px; }
.form-row .form-group { flex: 1; }

/* Modal actions */
.modal-actions { display: flex; gap: 12px; justify-content: flex-end; margin-top: 24px; }
.btn-primary {
  padding: 10px 24px;
  border: none;
  border-radius: 999px;
  background: var(--primary);
  color: var(--on-primary);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.2s;
  font-family: 'Inter', sans-serif;
}
.btn-primary:hover { opacity: 0.9; }
.btn-secondary {
  padding: 10px 24px;
  border: 1.5px solid var(--outline-variant);
  border-radius: 999px;
  background: none;
  color: var(--on-surface-variant);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
  font-family: 'Inter', sans-serif;
}
.btn-secondary:hover { border-color: var(--on-surface); color: var(--on-surface); }

/* Tags input */
.tags-input-wrapper { display: flex; flex-direction: column; gap: 8px; }
.tags-container { display: flex; flex-wrap: wrap; gap: 6px; }
.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--primary-container);
  color: var(--on-primary-container);
  font-size: 12px;
  padding: 4px 12px;
  border-radius: 999px;
  font-weight: 600;
}
.tag-chip-remove { cursor: pointer; font-size: 16px; line-height: 1; opacity: 0.7; transition: opacity 0.2s; }
.tag-chip-remove:hover { opacity: 1; }

/* Confirm modal */
.confirm-modal .modal-body p { font-size: 15px; line-height: 1.6; }
.confirm-modal .modal-actions { margin-top: 24px; }

/* ===== TOAST ===== */
.toast {
  position: fixed;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--surface-container-lowest);
  border: 1px solid var(--surface-container);
  border-radius: 16px;
  padding: 12px 20px;
  display: flex;
  align-items: center;
  gap: 12px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
  z-index: 2000;
  font-size: 14px;
  max-width: 90vw;
  transition: opacity 0.3s, transform 0.3s;
}
@media (min-width: 768px) { .toast { bottom: 24px; } }
.toast.hidden { opacity: 0; transform: translateX(-50%) translateY(16px); pointer-events: none; }
.toast-undo {
  background: var(--primary-container);
  color: var(--on-primary-container);
  border: none;
  border-radius: 999px;
  padding: 6px 16px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  flex-shrink: 0;
  transition: opacity 0.2s;
  font-family: 'JetBrains Mono', monospace;
}
.toast-undo:hover { opacity: 0.8; }

/* ===== HELP OVERLAY ===== */
.help-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  /* The insets keep a dialog clear of the notch and the home indicator; they
     are 0 on anything without them, leaving the 16px exactly as it was. */
  padding: calc(16px + env(safe-area-inset-top)) calc(16px + env(safe-area-inset-right))
           calc(16px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left));
  backdrop-filter: blur(4px);
}
.help-overlay.hidden { display: none; }
.help-modal {
  background: var(--surface-container-lowest);
  border-radius: 24px;
  width: 100%;
  max-height: 80vh;
  max-height: 80dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
}
.help-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  border-bottom: 1px solid var(--surface-container);
}
.help-header h2 { font-size: 18px; margin: 0; }
.help-body { padding: 24px; }
.help-body h3 { font-size: 16px; margin: 20px 0 8px; }
.help-body h3:first-child { margin-top: 0; }
.help-body p { font-size: 14px; color: var(--on-surface-variant); line-height: 1.6; margin-bottom: 8px; }
.help-body ul { list-style: none; padding: 0; margin-bottom: 8px; }
.help-body li { font-size: 14px; color: var(--on-surface-variant); padding: 4px 0; line-height: 1.6; }
.help-body code { background: var(--surface-container); padding: 2px 8px; border-radius: 6px; font-size: 13px; }
.help-body kbd { background: var(--surface-container); border: 1px solid var(--outline-variant); border-radius: 6px; padding: 2px 8px; font-size: 12px; font-family: 'JetBrains Mono', monospace; }

/* ===== POMODORO ACTIVE TASK ===== */
.current-task { display: none; }
#currentTaskDisplay { display: none; }

/* ===== MISSING UTILITY CLASSES ===== */
.organic-card {
  border-radius: 16px;
  box-shadow: 0 8px 20px -4px var(--shadow-color);
  /* Merged from a second, later .organic-card block that redefined only
     `transition` and so silently dropped the box-shadow animation. */
  transition:
    transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 0.2s ease;
}
.organic-card:hover {
  transform: translateY(-3px) scale(1.01);
  box-shadow: 0 12px 24px -8px var(--shadow-color);
}

.bento-card {
  position: relative;
  overflow: hidden;
  transition: transform 0.2s ease;
  border-radius: 16px;
}
.bento-card:hover { transform: translateY(-2px); }

.stitch-border {
  border: 1.5px solid var(--outline-variant);
  transition: border-color 0.2s;
}
.stitch-border:hover { border-color: var(--primary); }

/* ===== HELP & SUPPORT MODAL ===== */
.support-hint {
  display: block;
  font-size: 11px;
  color: var(--on-surface-variant);
  opacity: 0.6;
  margin-top: 6px;
  line-height: 1.5;
}
#supportCount { text-align: right; font-family: 'JetBrains Mono', monospace; }

.support-diag {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  font-size: 13px;
  color: var(--on-surface);
}
.support-diag .stitch-checkbox { margin-top: 2px; flex-shrink: 0; }
.support-diag .support-hint { margin-top: 2px; }

/* Same shape as .support-diag — the schedule dialog's "Create a task for this". */
.sched-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  font-size: 13px;
  color: var(--on-surface);
}
.sched-check .stitch-checkbox { margin-top: 1px; flex-shrink: 0; }
.sched-check .support-hint { margin-top: 2px; }

/* Sits under the Start/End pair and reads back their difference. Empty (and so
   invisible) whenever the range is backwards or incomplete. */
.sched-duration {
  margin: -6px 0 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  color: var(--on-surface-variant);
}
.sched-duration:empty { display: none; }

/* Honeypot — invisible to people, still submittable by bots */
.support-botcheck { display: none !important; }

.support-status {
  font-size: 12px;
  line-height: 1.5;
  border-radius: 12px;
  padding: 10px 12px;
  margin-top: 4px;
}
.support-status.hidden { display: none; }
.support-status.info {
  background: var(--surface-container-high);
  color: var(--on-surface-variant);
}
.support-status.error {
  background: var(--error-container);
  color: var(--on-error-container);
}

.support-fallback-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  background: none;
  border: 1.5px dashed var(--outline-variant);
  border-radius: 12px;
  padding: 8px 12px;
  margin-bottom: 14px;
  color: var(--on-surface-variant);
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}
.support-fallback-btn:hover { border-color: var(--primary); color: var(--primary-text); }
.support-fallback-btn.hidden { display: none; }
.support-fallback-btn .material-symbols-outlined { font-size: 16px; }

.support-direct {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--outline-variant);
}
.support-direct .support-hint { margin-top: 0; margin-bottom: 6px; }
.support-direct-row { display: flex; align-items: center; gap: 8px; }
.support-email {
  flex: 1;
  min-width: 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--primary-text);
  text-decoration: none;
  word-break: break-all;
}
.support-email:hover { text-decoration: underline; }
.support-copy-btn {
  background: var(--surface-container-high);
  color: var(--on-surface-variant);
  border: none;
  border-radius: 999px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.2s, color 0.2s, transform 0.15s;
}
.support-copy-btn:hover { background: var(--primary-container); color: var(--on-primary-container); }
.support-copy-btn:active { transform: scale(0.95); }
.support-copy-btn .material-symbols-outlined { font-size: 16px; }

/* Donate (Razorpay) — the widget is a cross-origin iframe, so it can't be themed
   from here at all. App-themed buttons front it and it opens in its own dialog,
   which is the only container wide enough for Razorpay's own button; the 256px
   sidebar squeezed it and that is what looked broken. */
.donate-wrap {
  display: flex;
  justify-content: center;
}
.donate-wrap form { max-width: 100%; }
.donate-wrap iframe { max-width: 100% !important; border: 0; }

.sidebar-support {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--outline-variant);
}
/* The app-themed front for the widget. Razorpay's own button can't be styled
   from here, so this is what carries the app's look. */
.donate-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 8px 14px;
  background: var(--primary-fixed);
  color: var(--on-primary-container);
  border: 1.5px solid var(--primary);
  border-radius: 999px;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: filter 0.2s, transform 0.15s;
}
.donate-btn:hover { filter: brightness(1.06); }
.donate-btn:active { transform: scale(0.97); }
.donate-btn .material-symbols-outlined {
  font-size: 16px;
  flex-shrink: 0;
  font-variation-settings: 'FILL' 1;
}
.donate-btn-inline { margin-top: 14px; }

/* Razorpay needs room for its own button; the dialog gives it the width the
   256px sidebar could not. */
.donate-wrap { min-height: 48px; align-items: center; }
.donate-note {
  margin-top: 14px;
  font-size: 11px;
  line-height: 1.5;
  text-align: center;
  color: var(--on-surface-variant);
  opacity: 0.7;
}

/* Quote topic chip — every dashboard quote is tagged time / success / hard work */
.quote-topic {
  display: inline-block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  padding: 2px 8px;
  border-radius: 999px;
  margin-bottom: 6px;
  background: var(--surface-container-high);
  color: var(--on-surface-variant);
}
.quote-topic-time { background: color-mix(in srgb, var(--trend-1) 16%, transparent); color: var(--trend-1); }
.quote-topic-success { background: color-mix(in srgb, var(--trend-3) 16%, transparent); color: var(--trend-3); }
.quote-topic-hardwork { background: color-mix(in srgb, var(--trend-2) 16%, transparent); color: var(--trend-2); }

.golden-glow {
  animation: golden-shimmer 3s ease-in-out infinite;
  background-size: 200% 200%;
}
@keyframes golden-shimmer {
  0%, 100% { box-shadow: 0 0 20px rgba(232, 196, 38, 0.1); }
  50% { box-shadow: 0 0 40px rgba(232, 196, 38, 0.25); }
}

.squishy-button:active { transform: scale(0.95); }

.organic-shadow {
  box-shadow: 0 8px 24px -4px var(--shadow-color);
}

.rounded-organic { border-radius: 16px; }

/* ===== HEADER CONTROLS =====
   The search field and the New Task pill share one height, so neither out-grows
   the icon buttons beside them (the bordered search box used to sit ~3px taller
   than the button next to it). */
.header-control { height: 36px; box-sizing: border-box; }
#headerSearch { height: 100%; padding: 0; line-height: 1; }

/* ===== TAG PILLS (sidebar clouds) =====
   The sidebar clouds had no rule of their own, so their pills rendered as bare
   coloured text. Shape lives here; the per-tag hue still arrives inline. */
#tagCloudSidebar .tag-pill,
#tagCloudTags .tag-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1.5px solid transparent;
  background: var(--surface-container-high);
  color: var(--on-surface);
  cursor: pointer;
  user-select: none;
  transition: transform 0.15s, filter 0.15s;
}
#tagCloudSidebar .tag-pill:hover,
#tagCloudTags .tag-pill:hover { transform: translateY(-1px); filter: brightness(1.1); }
.tag-pill:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* Selected: a leading ✓ and heavier text. The ring and the solid border come in
   inline from renderTagCloud, because the pill's hue does too. */
.tag-pill.active { font-weight: 800; }
.tag-pill.active::before {
  content: 'check';
  font-family: 'Material Symbols Outlined';
  font-size: 13px;
  line-height: 1;
  font-variation-settings: 'FILL' 1, 'wght' 700;
}

.tag-cloud-empty {
  font-size: 11px;
  color: var(--on-surface-variant);
  opacity: 0.55;
}

.tag-filter-clear {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  margin-top: 14px;
  background: var(--primary-fixed);
  color: var(--on-primary-container);
  border: 1.5px solid var(--primary);
  border-radius: 999px;
  padding: 6px 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  transition: filter 0.2s, transform 0.15s;
}
.tag-filter-clear.hidden { display: none; }
.tag-filter-clear:hover { filter: brightness(1.06); }
.tag-filter-clear:active { transform: scale(0.97); }
.tag-filter-clear .material-symbols-outlined { font-size: 15px; flex-shrink: 0; }
.tag-filter-clear span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ===== FOCUS SCORE EXPLAINER =====
   A title attribute is useless on touch, so the definition lives in a panel the
   info button expands. */
.focus-score-info {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--on-surface-variant);
  opacity: 0.6;
  display: inline-flex;
  align-items: center;
  transition: opacity 0.2s, color 0.2s;
}
.focus-score-info:hover,
.focus-score-info[aria-expanded="true"] { opacity: 1; color: var(--primary-text); }
.focus-score-info .material-symbols-outlined { font-size: 14px; }

.focus-score-help {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--surface-container);
  border: 1px solid var(--outline-variant);
  border-radius: 12px;
  font-size: 11px;
  line-height: 1.6;
  color: var(--on-surface-variant);
}
.focus-score-help.hidden { display: none; }
.focus-score-help p + p { margin-top: 6px; }
.focus-score-help strong { color: var(--on-surface); }
.focus-score-formula {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--primary-text);
  background: var(--surface-container-high);
  border-radius: 8px;
  padding: 6px 8px;
  text-align: center;
}

/* ===== STATS: WORD CLOUD ===== */
.cloud-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin-bottom: 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--on-surface-variant);
}
.cloud-legend > span { display: inline-flex; align-items: center; gap: 6px; }
.cloud-legend-swatch { width: 10px; height: 10px; border-radius: 3px; background: var(--outline); }
.cloud-legend-swatch.is-project { border-radius: 999px; background: var(--primary); }
.cloud-legend-note { opacity: 0.7; }

.wordcloud {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px 16px;
  padding: 28px 18px;
  min-height: 200px;
  background: var(--surface-container-low);
  border: 1px solid var(--surface-container);
  border-radius: 16px;
}
.cloud-word {
  background: none;
  border: none;
  padding: 2px 4px;
  border-radius: 8px;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  line-height: 1.15;
  transition: transform 0.15s, background 0.15s;
}
.cloud-word:hover { transform: scale(1.08); background: var(--surface-container-high); }
.cloud-word:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* The word's colour is its tag's hue, set inline, and the TAG_COLORS palette was
   picked for tinted pills rather than for bare text. Untouched, the yellows and
   limes fall to ~1.6:1 on a light surface and the deep purple to ~2.2:1 on a dark
   one. A per-theme brightness nudge lifts the whole palette past 3:1 in both
   directions without giving up the hue that identifies the tag. */
html:not(.dark) .cloud-word { filter: brightness(0.62); }
html.dark .cloud-word { filter: brightness(1.3) saturate(0.95); }
/* Projects read as headings, tags as words — the legend says which is which. */
.cloud-word.is-project { text-transform: uppercase; letter-spacing: 0.5px; }
.cloud-word.active { background: var(--surface-container-high); box-shadow: inset 0 -3px 0 currentColor; }

.cloud-podium { margin-top: 18px; display: flex; flex-direction: column; gap: 8px; }
.cloud-podium-title {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--on-surface-variant);
}
.cloud-rank {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--surface-container-low);
  border: 1px solid var(--surface-container);
  border-radius: 12px;
  font-size: 13px;
}
.cloud-rank-pos { font-family: 'JetBrains Mono', monospace; font-weight: 700; color: var(--on-surface-variant); width: 12px; flex-shrink: 0; }
.cloud-rank-dot { width: 10px; height: 10px; border-radius: 999px; flex-shrink: 0; }
.cloud-rank-name { flex: 1; min-width: 0; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cloud-rank-meta { font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--on-surface-variant); flex-shrink: 0; }

/* ===== TASK MODAL: SCHEDULE EDITOR =====
   Repeatable rows are how one task gets more than one time block. */
.modal-schedule-list { display: flex; flex-direction: column; gap: 8px; }
.modal-schedule-row { display: flex; align-items: center; gap: 6px; }
/* An id selector is needed to outrank `.form-group input:not(...)`, whose
   width:100% would otherwise stack the three fields instead of forming a row. */
#modalScheduleList input {
  width: auto;
  flex: 1 1 0;
  min-width: 0;
  padding: 7px 9px;
  font-size: 12px;
}
#modalScheduleList input[type="date"] { flex: 1.5 1 0; }
.modal-schedule-sep { flex-shrink: 0; font-size: 12px; color: var(--on-surface-variant); }
.schedule-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  background: var(--surface-container-high);
  color: var(--on-surface-variant);
  border: 1.5px dashed var(--outline-variant);
  border-radius: 999px;
  padding: 6px 14px;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}
.schedule-add-btn:hover { border-color: var(--primary); color: var(--primary-text); }
.schedule-add-btn .material-symbols-outlined { font-size: 16px; }

/* Recurrence on a row. The select spans the row's second line, with the rule
   spelled out underneath so "every 2 weeks until 1 Dec" is visible at a glance. */
#modalScheduleList select {
  flex: 1 1 100%;
  padding: 7px 9px;
  font-size: 12px;
}
.modal-schedule-rule {
  flex: 1 1 100%;
  margin-top: 2px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--primary-text);
  opacity: 0.85;
}
.modal-schedule-row { flex-wrap: wrap; }

/* ===== SCHEDULE MODAL: RECURRENCE ===== */
.sched-interval-row { display: flex; align-items: center; gap: 8px; }
/* An id is needed to beat `.form-group input:not(...)`'s width:100%. */
#schedInterval { width: auto; flex: 0 0 76px; }
.sched-interval-unit {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--on-surface-variant);
  white-space: nowrap;
}
.sched-optional {
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  opacity: 0.6;
}
.sched-repeat-summary {
  margin: -6px 0 16px;
  padding: 7px 10px;
  background: var(--surface-container-high);
  border-radius: 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--primary-text);
}
.sched-repeat-summary:empty { display: none; }
#schedRepeatDetail.hidden { display: none; }

.sched-locked-note {
  margin: -8px 0 16px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--on-surface-variant);
  opacity: 0.75;
}
.sched-locked-note.hidden { display: none; }
#schedRepeat:disabled, #schedInterval:disabled, #schedUntil:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.sched-scope {
  margin-bottom: 16px;
  padding: 12px 14px;
  background: var(--surface-container-low);
  border: 1.5px solid var(--outline-variant);
  border-radius: 12px;
}
.sched-scope.hidden { display: none; }
.sched-scope legend {
  padding: 0 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--on-surface-variant);
}
.sched-scope label {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 4px 0;
  font-size: 13px;
  color: var(--on-surface);
  cursor: pointer;
}
/* Custom-drawn: @tailwindcss/forms paints a bare radio white, and it loads after
   this stylesheet, so a bare `[type=radio]` rule would lose the tie. */
input.sched-radio {
  appearance: none;
  background: transparent;
  width: 16px;
  height: 16px;
  border: 2px solid var(--outline);
  border-radius: 50%;
  cursor: pointer;
  flex-shrink: 0;
  position: relative;
  transition: border-color 0.2s;
}
/* The shorthand (not background-color) on purpose: @tailwindcss/forms paints a
   checked radio with `currentColor` plus its own SVG dot, and at (0,2,1) this
   both outranks that fill and clears the image, leaving the ::after dot below as
   the only marker. */
input.sched-radio:checked { border-color: var(--primary); background: transparent; }
input.sched-radio:checked::after {
  content: '';
  position: absolute;
  inset: 2px;
  border-radius: 50%;
  background: var(--primary);
}

/* Repeating marker on chips, blocks and today's rows */
.cal-repeat-mark { margin-left: 4px; font-size: 10px; opacity: 0.85; flex-shrink: 0; }
.today-repeat { color: var(--primary-text); }

.btn-danger {
  padding: 10px 20px;
  border: 1.5px solid var(--error);
  border-radius: 999px;
  background: none;
  color: var(--error);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  transition: all 0.2s;
  margin-right: auto; /* sits apart from Cancel/Save */
}
.btn-danger:hover { background: var(--error-container); color: var(--on-error-container); }
.btn-danger.hidden { display: none; }

/* ===== CALENDAR TAB ===== */
.cal-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}
.cal-toolbar-group { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.cal-label { font-size: 20px; line-height: 28px; margin-left: 4px; }

.cal-nav-btn {
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-container);
  color: var(--on-surface);
  border: none;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.2s;
}
.cal-nav-btn:hover { background: var(--surface-container-high); }
.cal-nav-btn .material-symbols-outlined { font-size: 20px; }

.cal-today-btn {
  background: var(--surface-container);
  color: var(--on-surface);
  border: 1.5px solid var(--outline-variant);
  border-radius: 999px;
  padding: 6px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}
.cal-today-btn:hover { border-color: var(--primary); color: var(--primary-text); }

.cal-view-switch { display: inline-flex; background: var(--surface-container); border-radius: 999px; padding: 3px; gap: 2px; }
.cal-view-btn {
  border: none;
  background: transparent;
  cursor: pointer;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  color: var(--on-surface-variant);
  padding: 5px 14px;
  border-radius: 999px;
  transition: all 0.15s;
}
.cal-view-btn:hover:not(.active) { color: var(--on-surface); }
.cal-view-btn.active { background: var(--surface-container-lowest); color: var(--primary-text); box-shadow: 0 1px 3px var(--shadow-color); }

.cal-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--primary);
  color: var(--on-primary);
  border: none;
  border-radius: 999px;
  padding: 8px 16px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  transition: opacity 0.2s, transform 0.15s;
}
.cal-add-btn:hover { opacity: 0.9; }
.cal-add-btn:active { transform: scale(0.96); }
.cal-add-btn .material-symbols-outlined { font-size: 16px; }

.cal-hint {
  margin-top: 12px;
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--on-surface-variant);
  opacity: 0.65;
}

/* --- Month view --- */
.cal-month {
  background: var(--surface-container-lowest);
  border: 1px solid var(--surface-container);
  border-radius: 16px;
  overflow: hidden;
}
.cal-month-head {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  background: var(--surface-container-low);
  border-bottom: 1px solid var(--surface-container);
}
.cal-month-dayname {
  padding: 8px 6px;
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--on-surface-variant);
}
.cal-month-grid { display: grid; grid-template-columns: repeat(7, 1fr); grid-auto-rows: minmax(96px, auto); }
.cal-month-cell {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  padding: 4px 5px 6px;
  border-right: 1px solid var(--surface-container);
  border-bottom: 1px solid var(--surface-container);
  cursor: pointer;
  transition: background 0.15s;
}
.cal-month-cell:nth-child(7n) { border-right: none; }
.cal-month-cell:hover { background: var(--surface-container-low); }
.cal-month-cell.other-month { background: var(--surface-container-low); opacity: 0.55; }
.cal-month-cell.is-today { background: color-mix(in srgb, var(--primary) 7%, transparent); }
.cal-month-daynum {
  align-self: flex-start;
  width: 22px;
  height: 22px;
  background: none;
  border: none;
  border-radius: 999px;
  cursor: pointer;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  color: var(--on-surface-variant);
  transition: background 0.15s, color 0.15s;
}
.cal-month-daynum:hover { background: var(--surface-container-high); color: var(--on-surface); }
.cal-month-cell.is-today .cal-month-daynum { background: var(--primary); color: var(--on-primary); }
.cal-month-events { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.cal-chip {
  display: flex;
  align-items: center;
  gap: 5px;
  width: 100%;
  min-width: 0;
  padding: 2px 5px;
  text-align: left;
  background: var(--surface-container-high);
  border: none;
  border-left: 3px solid var(--primary);
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.15s;
}
.cal-chip:hover { background: var(--primary-fixed); }
.cal-chip.done { opacity: 0.5; border-left-color: var(--secondary); }
/* After .done on purpose: a finished block keeps its colour, because the
   strikethrough and the fade already say it is done. */
.cal-chip.has-color { border-left-color: var(--block-color); }
.cal-chip.done .cal-chip-title { text-decoration: line-through; }
/* A dashed edge is the calendar's shorthand for "this is not a task" — it reads
   at chip size, and it survives whatever colour the block is wearing. */
.cal-chip.is-event { border-left-style: dashed; }
.cal-chip-time { flex-shrink: 0; font-family: 'JetBrains Mono', monospace; font-size: 9px; font-weight: 700; color: var(--primary-text); }
.cal-chip-title { min-width: 0; font-size: 11px; font-weight: 600; color: var(--on-surface); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-more {
  padding: 1px 5px;
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  color: var(--primary-text);
}
.cal-more:hover { text-decoration: underline; }

/* --- Week / day time grid --- */
.cal-grid {
  background: var(--surface-container-lowest);
  border: 1px solid var(--surface-container);
  border-radius: 16px;
  overflow: hidden;
}
/* Sticky inside .cal-grid-scroll so the day headers stay put vertically and stay
   glued to their columns when a week scrolls sideways. */
.cal-grid-head {
  display: flex;
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--surface-container-low);
  border-bottom: 1px solid var(--surface-container);
}
.cal-gutter-head { width: 60px; flex-shrink: 0; }
.cal-day-head {
  flex: 1;
  min-width: 78px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 8px 4px;
  border-left: 1px solid var(--surface-container);
}
.cal-day-name { font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--on-surface-variant); }
.cal-day-num { font-family: 'Plus Jakarta Sans', sans-serif; font-size: 17px; font-weight: 700; line-height: 1.1; }
.cal-day-head.is-today .cal-day-name { color: var(--primary-text); }
.cal-day-head.is-today .cal-day-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: var(--primary);
  color: var(--on-primary);
  font-size: 15px;
}

.cal-grid-scroll { max-height: min(62vh, 660px); overflow: auto; }
/* A week needs the gutter plus seven 78px columns before it starts scrolling
   sideways; a single day has no floor to hold. */
.cal-grid.is-week .cal-grid-inner { min-width: 606px; }
.cal-grid-body { display: flex; }
.cal-gutter { width: 60px; flex-shrink: 0; }
.cal-hour-label {
  padding-right: 8px;
  text-align: right;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--on-surface-variant);
  opacity: 0.75;
  transform: translateY(-6px);
}
.cal-day-col { position: relative; flex: 1; min-width: 78px; border-left: 1px solid var(--surface-container); }
.cal-day-col.is-today { background: color-mix(in srgb, var(--primary) 5%, transparent); }
.cal-slot {
  position: absolute;
  left: 0;
  right: 0;
  border-top: 1px solid var(--surface-container);
  cursor: pointer;
  transition: background 0.12s;
}
.cal-slot:hover { background: color-mix(in srgb, var(--primary) 9%, transparent); }
.cal-now { position: absolute; left: 0; right: 0; height: 2px; background: var(--error); z-index: 3; pointer-events: none; }
.cal-now::before { content: ''; position: absolute; left: -4px; top: -3px; width: 8px; height: 8px; border-radius: 999px; background: var(--error); }

.cal-block {
  position: absolute;
  z-index: 2;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 3px 5px;
  background: var(--primary-fixed);
  color: var(--on-primary-container);
  border-left: 3px solid var(--primary);
  border-radius: 7px;
  cursor: pointer;
  transition: filter 0.15s, box-shadow 0.15s;
}
.cal-block:hover { filter: brightness(1.06); box-shadow: 0 4px 12px -4px var(--shadow-color); z-index: 4; }
.cal-block:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.cal-block.golden {
  background: color-mix(in srgb, var(--tertiary-fixed) 70%, transparent);
  border-left-color: var(--tertiary-fixed-dim);
  color: var(--on-tertiary-fixed);
}
.cal-block.active { border-left-color: var(--secondary); box-shadow: inset 0 0 0 1.5px var(--secondary); }
.cal-block.done { opacity: 0.55; }
.cal-block.done .cal-block-title { text-decoration: line-through; }

/* A block's colour beats the golden and active tints — the swatch you picked
   should be the colour you get. Both states keep an inset ring instead, so they
   stay identifiable on a fully colour-coded calendar. The ring rules come first
   so .has-color can still win on background and border below. */
.cal-block.golden { box-shadow: inset 0 0 0 1.5px var(--tertiary-fixed-dim); }
.cal-block.has-color {
  /* Mixed down into the page surface rather than used neat: a 3px border can
     carry a saturated colour, a filled box behind 11px text cannot. Mixing into
     --surface-container-lowest is what makes one rule work in both themes —
     it resolves light on light and dark on dark. */
  background: color-mix(in srgb, var(--block-color) 20%, var(--surface-container-lowest));
  border-left-color: var(--block-color);
  color: var(--on-surface);
}
/* Same dashed edge the month chips use for an event: it says "not a task" without
   spending any of the little width or height a block has on saying it. */
.cal-block.is-event { border-left-style: dashed; }
.cal-block-time { font-family: 'JetBrains Mono', monospace; font-size: 9px; font-weight: 700; opacity: 0.85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-block-title { font-size: 11px; font-weight: 700; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; }
.cal-block-project { font-family: 'JetBrains Mono', monospace; font-size: 8px; text-transform: uppercase; letter-spacing: 0.5px; opacity: 0.7; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-block-del {
  position: absolute;
  top: 1px;
  right: 1px;
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-container-lowest);
  color: var(--on-surface-variant);
  border: none;
  border-radius: 999px;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s, color 0.15s;
}
.cal-block:hover .cal-block-del { opacity: 0.9; }
.cal-block-del:hover { color: var(--error); }

/* ===== DASHBOARD: TODAY'S SCHEDULE ===== */
.today-schedule-toggle {
  display: flex;
  align-items: center;
  padding: 2px;
  background: none;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  color: var(--on-surface-variant);
  opacity: 0.6;
  transition: all 0.2s;
}
.today-schedule-toggle:hover { opacity: 1; color: var(--primary-text); background: var(--surface-container); }
.today-schedule-toggle .material-symbols-outlined { font-size: 20px; }

/* Scrolls past ~9 rows rather than growing the column without limit, matching
   the treatment Up Next already has (both cap at 340px). This is what keeps a
   day with twenty due tasks from making the dashboard taller than a day with
   three. */
.today-schedule-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 10px;
  max-height: 340px;
  overflow-y: auto;
  overflow-x: hidden;
}
.today-schedule.collapsed .today-schedule-body { display: none; }
.today-schedule-empty { font-size: 12px; color: var(--on-surface-variant); opacity: 0.75; }
.today-schedule-add {
  margin-left: 4px;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 700;
  color: var(--primary-text);
  text-decoration: underline;
}

.today-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  background: var(--surface-container);
  border-left: 3px solid var(--outline-variant);
  border-radius: 10px;
  transition: background 0.15s;
}
.today-row:hover { background: var(--surface-container-high); }
.today-row.now { border-left-color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.today-row.past { opacity: 0.6; }
.today-row.done { opacity: 0.5; border-left-color: var(--secondary-text); }
.today-row.done .today-title { text-decoration: line-through; }
/* Last, so a coloured row keeps its colour through the now/past/done states.
   The NOW row still stands out — it just glows in its own colour instead of the
   theme's primary. */
.today-row.has-color { border-left-color: var(--block-color); }
.today-row.has-color.now { background: color-mix(in srgb, var(--block-color) 14%, transparent); }
.today-time {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  min-width: 54px;
  line-height: 1.2;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  color: var(--on-surface-variant);
}
.today-time-end { opacity: 0.55; font-weight: 600; }

/* ===== SCHEDULE COLOUR PICKER ===== */
/* Matches .form-group label so the section header sits in line with the rest of
   the dialog — it is a <span>, not a <label>, because it labels a group of
   buttons rather than one control. */
.sched-color-label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--on-surface-variant);
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-family: 'JetBrains Mono', monospace;
}
.sched-colors { display: flex; flex-wrap: wrap; gap: 8px; }
.sched-swatch {
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: var(--swatch, var(--outline-variant));
  cursor: pointer;
  /* The ring is drawn outside the circle so selecting one doesn't resize it. */
  box-shadow: 0 0 0 1.5px var(--surface-container-lowest) inset;
  transition: transform 0.15s, outline-color 0.15s;
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.sched-swatch:hover { transform: scale(1.1); }
.sched-swatch.selected { outline-color: var(--on-surface); }
.sched-swatch:focus-visible { outline-color: var(--on-surface); }
/* Automatic: a dashed ring says "derived", while the fill still previews the
   colour the current project would produce. */
.sched-swatch.is-auto {
  border: 2px dashed var(--outline);
  background: var(--swatch, transparent);
}
/* Automatic with no project to inherit from — nothing to preview. */
.sched-swatch.is-auto.is-empty { background: transparent; }
.today-title { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.today-project { margin-left: 8px; font-family: 'JetBrains Mono', monospace; font-size: 9px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--on-surface-variant); opacity: 0.7; }
.today-now-badge {
  flex-shrink: 0;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--primary);
  color: var(--on-primary);
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 1px;
}
.today-check, .today-play {
  flex-shrink: 0;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  line-height: 1;
  transition: transform 0.15s, color 0.15s;
}
.today-check { font-size: 18px !important; color: var(--outline-variant); }
.today-check:hover { color: var(--secondary-text); transform: scale(1.12); }
.today-row.done .today-check { color: var(--secondary-text); }
.today-play { font-size: 22px !important; color: var(--primary-text); }
.today-play:hover { transform: scale(1.12); }
/* Where an event's checkbox would be. It borrows .today-check for the column
   width, so it has to give back the parts that promise a click. */
.today-event-mark { cursor: default; color: var(--on-surface-variant); opacity: 0.55; }
.today-event-mark:hover { color: var(--on-surface-variant); transform: none; }

/* ===== RESPONSIVE ===== */
@media (max-width: 639px) {
  .px-container-padding { padding-left: 16px; padding-right: 16px; }
  .form-row { flex-direction: column; }
  .view-tabs { width: 100%; justify-content: center; }

  /* A native date input has a wide intrinsic minimum, so on a narrow modal it
     takes its own line and the two times share the next one. */
  .modal-schedule-row { flex-wrap: wrap; }
  #modalScheduleList input[type="date"] { flex: 1 1 100%; }
}

/* ===== DARK MODE OVERRIDES ===== */
.dark body, .dark .modal, .dark .help-modal, .dark .toast,
.dark #todoList > li,
.dark .bg-surface-container-lowest { background-color: var(--surface-container-lowest); }
.dark #todoList > li.completed { background: var(--surface-container-low); }

.dark .sort-btn:not(.active) { border-color: var(--outline-variant); }
.dark .timer-ring .text-surface-container-high { color: var(--surface-container-high); }

/* ===== PICTURE-IN-PICTURE BUTTONS ===== */
#pipBtn.active, #dashPipBtn.active {
  background: var(--primary);
  color: var(--on-primary);
}
#dashPipBtn.active .material-symbols-outlined { font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24; }

/* ===== GOALS ===== */
input.stitch-checkbox {
  appearance: none;
  background: transparent;
  width: 22px;
  height: 22px;
  border: 2px dashed var(--outline);
  border-radius: 50%;
  cursor: pointer;
  position: relative;
  transition: all 0.3s ease;
  flex-shrink: 0;
}
input.stitch-checkbox:checked {
  background-color: var(--secondary);
  border: 2px solid var(--secondary);
  transform: scale(1.1);
}
input.stitch-checkbox:checked::after {
  content: 'check';
  font-family: 'Material Symbols Outlined';
  font-size: 14px;
  color: white;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.progress-glow {
  box-shadow: 0 0 10px rgba(0, 106, 101, 0.2);
}
/* ===== QUICK ADD ===== */
#quickAddInput::placeholder { color: var(--outline); opacity: 0.5; }

/* ===== MOBILE ADJUSTMENTS ===== */
@media (max-width: 767px) {
  #ambientBg .absolute { width: 200px; height: 200px; }
  .heatmap-grid .day-cell { font-size: 11px; }

  /* Five items share the bottom bar, so they give up their side padding. */
  #mobileNav .tab, #mobileNav .mnav-more { padding-left: 2px; padding-right: 2px; }

  /* ---- SHELL ----
     pb-36 was a 144px guess at how much room the bottom bar needs. The bar is
     ~56px plus the home-indicator inset, and the last card was left floating
     well above it. */
  .app-scroll { padding-bottom: calc(72px + env(safe-area-inset-bottom)) !important; }
  /* Installed on iOS the app is drawn behind the status bar (see
     apple-mobile-web-app-status-bar-style in index.html), so the sticky header
     has to hold the clock's room itself or the page title sits under it. */
  .app-header {
    padding-top: calc(12px + env(safe-area-inset-top));
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
  }
  /* 24px plus three controls plus a nine-character title does not fit 360px. */
  .page-title { font-size: 20px !important; line-height: 28px !important; }
  /* Help and support live in the More sheet on a phone. */
  .mobile-overflow-control { display: none !important; }
  /* Label off, so the add button is a round icon rather than a wide pill. */
  #headerAddBtn { width: 36px; padding: 0; justify-content: center; }
  #headerAddBtn .material-symbols-outlined { font-size: 20px; }

  /* ---- NESTED SCROLLERS ----
     The task list had its own 'calc(100vh - 260px)' scroller inside the page's
     scroller: two swipe areas competing for one gesture, and a height that
     overshot the visible viewport anyway. On a phone the list just grows and the
     page scrolls. */
  .task-scroll-area { max-height: none !important; overflow: visible !important; }
  #dashTaskList { max-height: none !important; }

  /* ---- iOS INPUT ZOOM ----
     Safari zooms the whole page in when a focused field's text is under 16px and
     offers no way back out — and nearly every field in the app was under it, so
     tapping one left the layout scaled up and stuck. A blanket floor is right
     here because it is a platform constraint rather than a design choice, and it
     is scoped to the widths where the zoom happens.
     CSS cannot say "only if smaller", so this also pulls the one field that
     asked for more back to 16px; #quickAddInput restores itself below. */
  input, select, textarea { font-size: 16px !important; }
  /* The controls whose font-size is their appearance, not their text. */
  input[type="checkbox"], input[type="radio"], input[type="range"],
  input[type="color"], .stitch-checkbox { font-size: inherit !important; }
  /* Deliberately larger than the floor, so it never triggers the zoom either. */
  #quickAddInput { font-size: 18px !important; }

  /* Calendar: the month grid gets shorter rows and drops chip times; the week
     grid keeps its 560px floor and scrolls sideways instead of crushing. */
  .cal-toolbar { gap: 8px; }
  .cal-label { order: 3; width: 100%; margin-left: 0; font-size: 16px; line-height: 22px; }
  .cal-toolbar-group { width: 100%; justify-content: space-between; }
  .cal-month-grid { grid-auto-rows: minmax(70px, auto); }
  .cal-month-dayname { padding: 6px 2px; font-size: 9px; letter-spacing: 0; }
  .cal-month-cell { padding: 3px; gap: 2px; }
  .cal-chip-time { display: none; }
  .cal-chip { padding: 2px 4px; }
  .cal-grid-scroll { max-height: 62vh; }
  .cal-view-btn { padding: 5px 10px; font-size: 11px; }

  /* The cloud's largest words are set inline, so only the box tightens here. */
  .wordcloud { padding: 20px 12px; min-height: 160px; gap: 2px 12px; }

  .today-time { min-width: 48px; }

  /* The toast sat 100px up, which cleared the old bottom bar but left about
     10px between them once a home indicator was in play. Measured from the bar
     instead. */
  .toast { bottom: calc(84px + env(safe-area-inset-bottom)); }
}

/* ===== PRESS EFFECT ===== */
.press-effect:active { transform: scale(0.95); }

/* ===== NAV CAPACITY =====
   Nine tabs used to share the bar and it scrolled sideways, which meant the last
   three were only reachable by discovering that a nav bar could be swiped —
   nobody does. Now the bar shows the first four switched-on tabs and hands the
   rest to the More sheet. syncMobileNav() in app.js picks the four and marks
   them .mnav-primary; everything else in the bar is hidden here rather than
   removed, so both copies of a tab keep their click handler and their
   module-off state. */
#mobileNav {
  padding-top: 6px;
  /* The home indicator on a gesture-navigation phone sits over the bottom
     ~20px. env() only reports a real number when the viewport meta says
     viewport-fit=cover, which is why that was added to index.html. */
  padding-bottom: max(6px, env(safe-area-inset-bottom));
  /* A landscape notch eats into the sides. */
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
  /* Dragging the bar itself should never scroll the page behind it. */
  overscroll-behavior: contain;
}
#mobileNav .tab { display: none; }
#mobileNav .tab.mnav-primary,
#mobileNav .mnav-more {
  /* Equal shares of the bar. min-width:0 lets a long label ellipsise instead of
     forcing the row wider than the screen. */
  display: flex;
  flex: 1 1 0;
  min-width: 0;
  flex-direction: column;
  gap: 2px;
  /* 48px is the smallest comfortable touch target; the bar's own padding takes
     it past that. */
  min-height: 48px;
  background: none;
  border: 0;
  font-family: inherit;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  /* No `color` here on purpose. This selector is one id and two classes, exactly
     the weight of `#mobileNav .tab.active` far above, and being later in the file
     it would win the tie — leaving the selected tab the same grey as the other
     four, distinguishable only by the icon's fill. The resting colour comes from
     the markup's own text-on-surface-variant utility, which .active outranks. */
}
/* module-off has to keep winning over the display:flex above, hence the id here
   too — .module-off is !important but a bare class would still read oddly. */
#mobileNav .tab.module-off { display: none; }
#mobileNav .mnav-primary span:last-child,
#mobileNav .mnav-more span:last-child {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#mobileNav .mnav-more.open { color: var(--primary-text); }
#mobileNav .mnav-more.open .material-symbols-outlined { font-variation-settings: 'FILL' 1; }

/* ===== MOBILE "MORE" SHEET =====
   A bottom sheet, because it is opened from the bottom bar and a phone's thumb
   reaches the bottom of the screen, not the top of it. */
.more-sheet {
  position: fixed;
  inset: 0;
  z-index: 60;              /* over #mobileNav (z-50), under .modal-overlay (1000) */
  display: flex;
  align-items: flex-end;
}
.more-sheet.hidden { display: none; }
.more-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
}
.more-sheet-panel {
  position: relative;
  width: 100%;
  max-height: 85dvh;
  display: flex;
  flex-direction: column;
  background: var(--surface-container-lowest);
  border-radius: 24px 24px 0 0;
  box-shadow: 0 -12px 40px rgba(0, 0, 0, 0.28);
  padding-bottom: env(safe-area-inset-bottom);
  animation: more-sheet-in 0.22s cubic-bezier(0.2, 0, 0, 1);
}
@keyframes more-sheet-in {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}
/* Reduced-motion users get the sheet, just not the slide. */
@media (prefers-reduced-motion: reduce) {
  .more-sheet-panel { animation: none; }
}
/* The handle a sheet is expected to have. It closes on tap; there is no drag
   gesture, and pretending there is one with a drag affordance only would be
   worse than a tap target that works. */
.more-sheet-grip {
  width: 40px;
  height: 4px;
  border-radius: 999px;
  background: var(--outline-variant);
  margin: 10px auto 2px;
  flex-shrink: 0;
  cursor: pointer;
}
.more-sheet-head {
  display: flex;
  align-items: center;
  padding: 6px 20px 4px;
  flex-shrink: 0;
}
.more-sheet-title {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 18px;
  font-weight: 700;
  color: var(--on-surface);
}
.more-sheet-close {
  margin-left: auto;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 999px;
  background: var(--surface-container);
  color: var(--on-surface-variant);
  cursor: pointer;
}
.more-sheet-body {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 4px 20px 20px;
}
.more-sheet-heading {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--on-surface-variant);
  opacity: 0.7;
  margin: 14px 0 8px;
}
.more-sheet-tabs {
  display: grid;
  /* Two up on a 360px screen, three from about 480px, without a media query. */
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
}
.more-tab,
.more-action {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 10px 14px;
  border: 1px solid var(--outline-variant);
  border-radius: 16px;
  background: var(--surface-container-low);
  color: var(--on-surface);
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.more-tab span:last-child,
.more-action span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.more-tab .material-symbols-outlined,
.more-action .material-symbols-outlined { font-size: 22px; color: var(--on-surface-variant); flex-shrink: 0; }
.more-tab:active,
.more-action:active { transform: scale(0.98); }
/* The tab you are already on, so the sheet is not a list of nine identical rows. */
.more-tab.active {
  background: var(--primary-container);
  border-color: transparent;
  color: var(--on-primary-container);
}
.more-tab.active .material-symbols-outlined {
  color: var(--on-primary-container);
  font-variation-settings: 'FILL' 1;
}
/* Whatever the bottom bar is already showing is not repeated in the sheet:
   syncMobileNav() sets this on the sheet copy of each bar tab. */
.more-tab.in-bar { display: none; }
.more-sheet-actions { display: flex; flex-direction: column; gap: 8px; }
.more-sheet-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  background: var(--surface-container-low);
}
.more-sheet-search .material-symbols-outlined { font-size: 20px; color: var(--on-surface-variant); opacity: 0.7; }
.more-sheet-search input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--on-surface);
  /* 16px exactly: iOS Safari zooms the page when a focused field is smaller,
     and never zooms back out. */
  font-size: 16px;
  font-family: 'Inter', sans-serif;
  padding: 12px 0;
  outline: none;
}
.more-sheet-search input::placeholder { color: var(--on-surface-variant); opacity: 0.6; }
.more-sheet-search:focus-within { border-color: var(--primary); }

/* ===== ALL-DAY STRIP =====
   Things that belong to a day rather than to an hour in it: birthdays,
   anniversaries. Drawn above the hour grid so nothing tries to give them a
   height. */
.cal-allday-row {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--outline-variant);
  background: var(--surface-container-low);
  min-height: 30px;
}
.cal-allday-gutter {
  width: 56px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--on-surface-variant);
  opacity: 0.6;
}
.cal-allday-cell {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 3px;
  border-left: 1px solid var(--outline-variant);
}
.cal-allday-cell.is-today { background: var(--primary-fixed); }

.cal-allday-chip {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  background: var(--tertiary-fixed);
  color: var(--on-tertiary-fixed);
  border: none;
  border-radius: 6px;
  padding: 2px 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: filter 0.2s;
}
.cal-allday-chip:hover { filter: brightness(1.06); }
.cal-allday-years {
  margin-left: auto;
  background: var(--surface-container-lowest);
  color: var(--on-surface-variant);
  border-radius: 999px;
  padding: 0 5px;
  font-size: 9px;
  flex-shrink: 0;
}
/* In a month cell the chip sits among the timed ones, so it needs the same
   compact metrics rather than the strip's. */
.cal-month-events .cal-allday-chip { font-size: 9px; padding: 1px 5px; }

/* ===== REMINDERS TAB ===== */
.reminder-group {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 20px 0 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--on-surface-variant);
}
.reminder-group:first-child { margin-top: 0; }
.reminder-group-count {
  background: var(--surface-container);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 10px;
}

.reminder-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--surface-container-lowest);
  border: 1px solid var(--surface-container);
  border-radius: 14px;
  padding: 12px 14px;
  margin-bottom: 8px;
  transition: border-color 0.2s, transform 0.15s;
}
.reminder-row:hover { border-color: var(--outline-variant); transform: translateX(2px); }
/* The day itself earns a ring — this is the one row that is not just upcoming. */
.reminder-row.is-today {
  border-color: var(--primary);
  background: var(--primary-fixed);
}
.reminder-icon { font-size: 22px; line-height: 26px; flex-shrink: 0; }
.reminder-main { flex: 1; min-width: 0; }
.reminder-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 14px;
  color: var(--on-surface);
}
.reminder-years {
  background: var(--secondary-container);
  color: var(--on-secondary-container);
  border-radius: 999px;
  padding: 0 7px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  flex-shrink: 0;
}
.reminder-meta {
  margin-top: 3px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--on-surface-variant);
}
.reminder-away { color: var(--primary-text); font-weight: 700; }
.reminder-repeat { opacity: 0.7; }
.reminder-note {
  margin-top: 5px;
  font-size: 12px;
  color: var(--on-surface-variant);
  opacity: 0.85;
}
.reminder-edit,
.reminder-del {
  background: transparent;
  border: none;
  border-radius: 999px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--on-surface-variant);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.2s, color 0.2s;
}
.reminder-edit:hover { background: var(--surface-container); color: var(--primary-text); }
.reminder-del:hover { background: var(--error-container); color: var(--on-error-container); }
.reminder-edit .material-symbols-outlined,
.reminder-del .material-symbols-outlined { font-size: 17px; }

.reminders-empty {
  text-align: center;
  padding: 48px 16px;
  color: var(--on-surface-variant);
}
.reminders-empty p { font-family: 'JetBrains Mono', monospace; font-size: 13px; font-weight: 700; }
.reminders-empty-hint {
  margin-top: 8px;
  max-width: 420px;
  margin-left: auto;
  margin-right: auto;
  font-family: inherit;
  font-size: 12px;
  font-weight: 400;
  opacity: 0.7;
}

/* ===== DASHBOARD: TODAY'S DATES ===== */
.today-reminders-body { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.today-reminder-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-container-lowest);
  border-radius: 10px;
  padding: 7px 10px;
  cursor: pointer;
  transition: background 0.2s;
}
.today-reminder-row:hover { background: var(--surface-container); }
.today-reminder-icon { font-size: 16px; flex-shrink: 0; }
.today-reminder-title {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--on-surface);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.today-reminder-when {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  color: var(--on-surface-variant);
  opacity: 0.7;
  flex-shrink: 0;
}

/* ===== JOURNAL ===== */
.journal-saved {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  /* The -text pair, not the raw accents: those are container fills and go
     too dark to read on a dark surface. */
  color: var(--secondary-text);
  min-height: 16px;
}

.journal-editor { border: 1px solid var(--surface-container); border-radius: 18px; }
.journal-editor-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--surface-container);
}
/* The one date field not wrapped in a .form-group, so the shared input styling
   never reaches it and @tailwindcss/forms' [type=date]{background-color:#fff}
   base rule wins instead — a white box painted with inherited light text, which
   in dark mode hides the date entirely. The id outranks both. */
#journalDate {
  padding: 5px 12px;
  border: 1.5px solid var(--outline-variant);
  border-radius: 999px;
  background: var(--surface-container-low);
  color: var(--on-surface);
  /* The parts Chrome paints itself: the picker popup and the calendar icon. */
  color-scheme: var(--color-scheme, dark);
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
}
#journalDate:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-fixed);
}

.journal-date-label,
.journal-field-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--on-surface-variant);
}
.journal-field-label { display: block; margin-bottom: 8px; }
.journal-today-btn {
  background: var(--surface-container-low);
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  padding: 4px 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  color: var(--on-surface-variant);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s;
}
.journal-today-btn:hover { color: var(--primary-text); border-color: var(--primary); }

/* Buttons rather than radio inputs: an emoji cannot be drawn inside a native
   radio without restyling it past recognition. The group carries the semantics. */
.journal-moods { display: flex; gap: 8px; flex-wrap: wrap; }
.journal-mood {
  background: var(--surface-container-low);
  border: 1.5px solid var(--outline-variant);
  border-radius: 14px;
  width: 46px;
  height: 44px;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s, transform 0.15s;
}
.journal-mood:hover { border-color: var(--primary); transform: translateY(-1px); }
.journal-mood.selected {
  border-color: var(--primary);
  background: var(--primary-fixed);
  transform: translateY(-1px);
}

.journal-editor-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 4px;
  padding-top: 14px;
  border-top: 1px solid var(--surface-container);
}
.journal-promote {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--secondary-container);
  color: var(--on-secondary-container);
  border: none;
  border-radius: 999px;
  padding: 6px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  transition: filter 0.2s;
}
.journal-promote:hover { filter: brightness(1.06); }
.journal-promote .material-symbols-outlined { font-size: 15px; }
.journal-promote.hidden, .journal-clear.hidden { display: none; }
.journal-clear {
  margin-left: auto;
  background: transparent;
  border: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  color: var(--error);
  cursor: pointer;
  opacity: 0.75;
  transition: opacity 0.2s;
}
.journal-clear:hover { opacity: 1; }

.journal-past-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 28px 0 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--on-surface-variant);
}
.journal-count {
  background: var(--surface-container);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 10px;
}
.journal-past {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  background: var(--surface-container-lowest);
  border: 1px solid var(--surface-container);
  border-radius: 12px;
  padding: 11px 14px;
  margin-bottom: 6px;
  cursor: pointer;
  transition: border-color 0.2s, transform 0.15s;
}
.journal-past:hover { border-color: var(--outline-variant); transform: translateX(2px); }
.journal-past-date {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  color: var(--primary-text);
  flex-shrink: 0;
  min-width: 92px;
}
.journal-past-mood { font-size: 15px; flex-shrink: 0; }
.journal-past-text {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--on-surface-variant);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.journal-empty {
  padding: 22px 4px;
  font-size: 13px;
  color: var(--on-surface-variant);
  opacity: 0.7;
}

/* ===== LIFE LESSONS ===== */
.lesson-add { border: 1px solid var(--surface-container); border-radius: 16px; }
/* Roomier than a one-line field: a lesson is usually a sentence or two, and a
   cramped box invites clipping the thought to fit. */
.lesson-add textarea { min-height: 92px; line-height: 1.5; }
.lesson-add-row {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
}
/* The date needs a field's width, not the row's. */
.lesson-date-group { flex: 0 1 190px; margin-bottom: 0; }
.lesson-add-row button { flex: 0 0 auto; }

.lesson-year {
  margin: 26px 0 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1px;
  color: var(--on-surface-variant);
}
.lesson-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-left: 2px solid var(--outline-variant);
  margin-bottom: 4px;
  transition: border-color 0.2s, background 0.2s;
}
.lesson-row:hover { border-left-color: var(--primary); background: var(--surface-container-low); }
.lesson-bullet { color: var(--primary-text); font-weight: 700; line-height: 20px; flex-shrink: 0; }
/* pre-wrap so the line breaks the writer put in are the ones they get back. */
.lesson-text {
  flex: 1;
  min-width: 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--on-surface);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.lesson-date {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  color: var(--on-surface-variant);
  opacity: 0.65;
  flex-shrink: 0;
  line-height: 20px;
}
.lesson-del {
  background: transparent;
  border: none;
  border-radius: 999px;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--on-surface-variant);
  opacity: 0;
  cursor: pointer;
  flex-shrink: 0;
  transition: opacity 0.2s, background 0.2s, color 0.2s;
}
.lesson-row:hover .lesson-del,
.lesson-del:focus-visible { opacity: 1; }
.lesson-del:hover { background: var(--error-container); color: var(--on-error-container); }
.lesson-del .material-symbols-outlined { font-size: 15px; }

.lessons-empty { text-align: center; padding: 48px 16px; color: var(--on-surface-variant); }
.lessons-empty p { font-family: 'JetBrains Mono', monospace; font-size: 13px; font-weight: 700; }
.lessons-empty-hint {
  margin: 8px auto 0;
  max-width: 420px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 400;
  opacity: 0.7;
}

/* Touch has no hover, so the delete affordance cannot hide behind one. */
@media (hover: none) {
  .lesson-del { opacity: 0.6; }
}

/* ===== SETTINGS ===== */
/* One rule hides a switched-off module everywhere it appears: nav entry,
   section, and the dashboard timer that belongs to Pomodoro. */
.module-off { display: none !important; }

.settings-heading {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--on-surface-variant);
}
.settings-intro {
  margin: 6px 0 14px;
  font-size: 13px;
  color: var(--on-surface-variant);
  opacity: 0.8;
}
.settings-modules { display: flex; flex-direction: column; gap: 2px; }
.settings-module {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 12px;
  cursor: pointer;
  transition: background 0.2s;
}
.settings-module:hover { background: var(--surface-container-low); }
.settings-module .stitch-checkbox { margin-top: 1px; flex-shrink: 0; }
.settings-module-text { display: flex; flex-direction: column; gap: 2px; }
.settings-module-label { font-size: 14px; font-weight: 600; color: var(--on-surface); }
.settings-core-note {
  margin-top: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--on-surface-variant);
  opacity: 0.65;
}

/* ===== SETTINGS: YOUR DATA =====
   Backup used to sit on the Stats tab, which is a module that can be switched off —
   so turning Stats off took the only route to your own data with it. */
.install-state {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 12px;
  border: 1px solid var(--outline-variant);
  border-radius: 16px;
  background: var(--surface-container-low);
}
.install-state[hidden] { display: none; }
.install-state-icon { font-size: 22px; color: var(--primary-text); flex-shrink: 0; }
.install-state-text { min-width: 0; flex: 1; }
.install-state-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--on-surface);
}
.install-state-hint {
  font-size: 12px;
  line-height: 1.5;
  color: var(--on-surface-variant);
  margin-top: 2px;
}
.install-state-btn { flex-shrink: 0; }
.install-state-btn[hidden] { display: none; }

.data-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.data-btn,
.data-undo-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.data-btn .material-symbols-outlined,
.data-undo-btn .material-symbols-outlined { font-size: 18px; }
.data-undo-btn { margin-top: 10px; }
.data-undo-btn[hidden] { display: none; }

/* ===== ACCOUNT =====
   Deliberately no new custom properties. Every colour here is one the theme
   already defines in both :root and .dark, which is what keeps a signed-in
   panel readable in light mode without a second set of values to maintain. */
.account-panel { margin: 10px 0 4px; }
.account-email {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--on-surface);
  margin-bottom: 10px;
  /* An address can be long and a dialog is narrow; wrapping beats a scrollbar. */
  overflow-wrap: anywhere;
}

/* The sync button lives in the header with the other 36px controls and inherits
   their shape. Only the error state paints differently — a failed sync is the
   one thing here worth noticing without being told. */
#syncBtn[data-state="error"] { color: var(--error); }
#syncBtn[data-state="syncing"] .material-symbols-outlined {
  animation: sync-spin 1s linear infinite;
}
@keyframes sync-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  #syncBtn[data-state="syncing"] .material-symbols-outlined { animation: none; }
}

/* ===== IMPORT DIALOG ===== */
/* The counts are the whole point of the dialog: choosing between merging and
   replacing is only a real choice if you can see what would be replaced. */
.import-table-wrap { overflow-x: auto; margin: 4px 0 2px; }
.import-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.import-table th,
.import-table td {
  padding: 7px 8px;
  text-align: right;
  border-bottom: 1px solid var(--outline-variant);
  white-space: nowrap;
}
.import-table thead th {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--on-surface-variant);
}
/* The row labels are the only left-aligned column, and they may wrap. */
.import-table tbody th {
  text-align: left;
  font-weight: 600;
  color: var(--on-surface);
  white-space: normal;
}
.import-table tbody td { color: var(--on-surface-variant); font-variant-numeric: tabular-nums; }
.import-table tbody tr:last-child th,
.import-table tbody tr:last-child td { border-bottom: 0; }

.import-dropped {
  margin-top: 8px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--on-error-container);
  background: var(--error-container);
  border-radius: 10px;
  padding: 8px 10px;
}
.import-dropped[hidden] { display: none; }

/* Three buttons will not sit on one line at 360px, so they stack there instead of
   overflowing the dialog. */
.import-actions { flex-wrap: wrap; }
.import-note {
  margin-top: 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--on-surface-variant);
}

@media (max-width: 480px) {
  .import-actions { flex-direction: column-reverse; align-items: stretch; }
  .import-actions button { width: 100%; }
  .install-state { flex-wrap: wrap; }
  .install-state-btn { width: 100%; }
}
